Compare commits

...

5 Commits

8 changed files with 463 additions and 243 deletions

View File

@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.10)
project(Asynco)
# Postavi verziju projekta
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# Pronađi Boost biblioteku (ako nije uobičajeni direktorijum, postavi put)

174
README.md
View File

@ -1,13 +1,13 @@
# Asynco
A C++ library for event-driven asynchronous multi-threaded programming.
A C++ library for event-driven asynchronous multi-threaded programming that serves as a runtime for asynchronous operations. It acts as a wrapper around the Boost.Asio library, providing a cleaner way to write asynchronous, concurrent, and parallel code utilizing a set of threads and an event loops. It offers features for event-driven programming, timers, and coroutine support.
## Motivation
The original concept was to create an interface capable of asynchronously calling any function. It has since evolved into a library that incorporates a thread pool, each with its own event loop, event-driven programming, and functions inherently designed for asynchronous operation (including periodic and delayed functions).
The initial goal was to create an interface that makes it easy and clean to asynchronously invoke any function in C++ without resorting to complex calls. Initially, the library was built around a custom implementation of a scheduling loop for queuing functions. However, this part was later replaced with Boost.Asio, mainly for its timer functionality. As the library evolved, it expanded to include a thread pool, each with its own event loop, and adopted event-driven programming. This enhancement also introduced functions specifically designed for asynchronous operations, including periodic and delayed execution.
The asynchronous filesystem is provided solely to guide users on how to wrap any time- or IO-intensive function for asynchronous execution.
The asynchronous filesystem was included solely to demonstrate how users can wrap any time- or I/O-intensive functions for asynchronous execution.
## Features
@ -16,12 +16,13 @@ The asynchronous filesystem is provided solely to guide users on how to wrap any
- Header only
- Asynchronous programming
- Multithread
- Asynchronous timer functions: periodic, delayed (like setInterval and setTimeout from JS)
- Asynchronous timer functions: Periodic, Delayed (like setInterval and setTimeout from JS)
- Typed events (on, tick, off) (like EventEmitter from JS: on, emit, etc)
- Event loops
- Multiple parallel execution loops
- Asynchronous file IO
- Based on ASIO (Boost Asio)
- On C++20 support Boost.Asio coroutines
## Installation
Just download the latest release and unzip it into your project.
@ -30,13 +31,13 @@ Just download the latest release and unzip it into your project.
#define NUM_OF_RUNNERS 8 // To change the number of threads used by asynco, without this it runs according to the number of cores
#include "asynco/lib/asynco.hpp" // async_ (), await_()
#include "asynco/lib/triggers.hpp" // trigger (event emitter)
#include "asynco/lib/timers.hpp" // periodic, delayed (like setInterval and setTimeout from JS)
#include "asynco/lib/triggers.hpp" // Trigger (event emitter)
#include "asynco/lib/timers.hpp" // Periodic, Delayed (like setInterval and setTimeout from JS)
#include "asynco/lib/filesystem.hpp" // for async read and write files
#include "asynco/lib/define.hpp" // async_, await_, asyncable_ defines
using namespace marcelb;
using namespace asynco;
using namespace triggers;
// At the end of the main function, always set
_asynco_engine.run();
@ -46,11 +47,15 @@ return 0;
## Usage
Time asynchronous functions
In the following sections, we will explore timers, function execution via the runtime, asynchronous invocation, and waiting for results. We will cover essential use cases involving triggers, file handling, and coroutines.
### Timers
We have two timer classes, Periodic (which runs a callback function periodically), and Delayed (delayed runs a callback function only once).
```c++
// start periodic
periodic inter1 ([]() {
Periodic inter1 ([]() {
cout << "Interval 1" << endl;
}, 1000);
@ -64,7 +69,7 @@ int t = inter1.ticks();
bool stoped = inter1.stoped();
// start delayed
delayed time1 ( [] () {
Delayed time1 ( [] () {
cout << "Timeout 1 " << endl;
}, 10000);
@ -77,30 +82,10 @@ int t = time1.expired();
// is it stopped
bool stoped = time1.stoped();
// If you don't want to save in a variable, but you want to start a timer, use these functions
// And you can also save them, they are only of the shared pointer type
auto d = Delayed( [](){
cout << "Delayed" << endl;
}, 2000);
auto p = Periodic( [](){
cout << "Periodic" << endl;
}, 700);
Periodic( [&] (){
cout << "Delayed expire " << d->expired() << endl;
cout << "Periodic ticks " << p->ticks() << endl;
cout << "Delayed stoped " << d->stoped() << endl;
cout << "Periodic stoped " << p->stoped() << endl;
}, 1000);
Delayed( [&](){
p->stop();
}, 10000);
```
Make functions asynchronous
### Make functions asynchronous
Running functions at runtime, asynchronous execution, uses the `async_` call and its return type is `std::future<T>`
```c++
/**
@ -139,12 +124,11 @@ clm classes;
async_ ( [&classes] () {
classes.classMethode();
});
```
To wait for the result (blocking the flow) use `await_` (basically nothing more than a `.get()` call on a future object)
/**
* await_ after runned as async
*/
```c++
auto a = async_ ( []() {
sleep_for(2s); // only for simulating long duration function
@ -164,10 +148,20 @@ cout << await_(async_ ( [] () {
return 4;
})) << endl;
```
/**
* Await all
**/
If you want to run asynchronously but need the result immediately, you can use a shorter notation
```c++
await_ ([]() {
cout << "Hello" << endl;
});
```
If multiple function calls do not depend on each other, you can call them and wait for the results later, better concurrency.
```c++
auto a = async_ ( []() {
cout << "A" << endl;
@ -218,13 +212,18 @@ auto await_all = [&] () {
}
};
```
Just an example:
```c++
/**
* Sleep with delayed sleep implement
*/
* Sleep with delayed sleep implement
**/
void sleep_to (int _time) {
promise<void> _promise;
delayed t( [&]() {
Delayed t( [&]() {
_promise.set_value();
}, _time);
@ -239,7 +238,7 @@ sleep_to(3000);
void promise_reject (int _time) {
promise<void> _promise;
delayed t( [&]() {
Delayed t( [&]() {
try {
// simulate except
throw runtime_error("Error simulation");
@ -258,16 +257,19 @@ try {
cout<< err.what() << endl;
}
```
Events
### Triggers
The library implements Triggers, which are basically typed Events.
```c++
/**
* initialization of typed events
*/
trigger<int, int> ev2int;
trigger<int, string> evintString;
trigger<> evoid;
Trigger<int, int> ev2int;
Trigger<int, string> evintString;
Trigger<> evoid;
ev2int.on("sum", [](int a, int b) {
cout << "Sum " << a+b << endl;
@ -312,14 +314,14 @@ evoid.tick("void"); // nothing is happening
Extend own class whit events
```c++
class myOwnClass : public trigger<int> {
class myOwnClass : public Trigger<int> {
public:
myOwnClass() : trigger() {};
myOwnClass() : Trigger() {};
};
myOwnClass myclass;
delayed t( [&] {
Delayed t( [&] {
myclass.tick("constructed", 1);
}, 200);
@ -334,8 +336,8 @@ Implementing a class with multiple triggers of different types
```c++
class ClassWithTriggers {
trigger<int> emitter1;
trigger<string> emitter2;
Trigger<int> emitter1;
Trigger<string> emitter2;
public:
template<typename... T>
@ -377,7 +379,7 @@ mt.tick("string", string("Hello world"));
```
Another example:
Asynchronous file IO
```c++
@ -419,6 +421,70 @@ try {
```
## Coroutine
If `define.hpp` is included, you can initialize coroutines using `asyncable<T>`; if not, just use `boost::asio::awaitable<T>`.
```c++
asyncable<int> c2(int a) {
co_return a * 2;
}
```
To run the coroutine at runtime, simply call:
```c++
async_(c2(4));
```
Or using a lambda expression:
```c++
async_([]() -> asyncable<void> {
std::cout << "Hello" << std::endl;
co_await c2(4);
co_return;
}());
```
To retrieve results from coroutines, you can do so as you would from classical functions by calling `await_`:
```c++
int r = await_(
async_(
c2(10)
));
```
If you need the result immediately, you can use a shorter notation
```c++
auto a = await_ ( c2(3));
cout << a << endl;
await_ ([]() -> asyncable<void> {
cout << "Hello" << endl;
co_return;
}());
```
Timers and triggers work the same with coroutines; it is important to call the coroutine with `async_` in the callback, and to call `async_`, wrap it with a lambda expression:
```c++
Periodic p([]() {
async_(c2(34));
}, 2000);
```
If you need a result, you can also retrieve it with `await_`.
## License
[APACHE 2.0](http://www.apache.org/licenses/LICENSE-2.0/)

View File

@ -3,9 +3,14 @@
#include "engine.hpp"
#include <iostream>
using namespace std;
#if __cplusplus >= 202002L
#include <boost/asio/awaitable.hpp>
#include <boost/asio/co_spawn.hpp>
#include <boost/asio/use_awaitable.hpp>
#endif
namespace marcelb {
namespace asynco {
@ -19,6 +24,34 @@ auto async_(F&& f, Args&&... args) -> future<typename result_of<F(Args...)>::typ
return res;
}
#if __cplusplus >= 202002L
/**
* Run the coroutine
*/
template <typename T>
std::future<T> async_(boost::asio::awaitable<T> _coroutine) {
std::promise<T> promise;
auto future = promise.get_future();
co_spawn(_asynco_engine.io_context, [_coroutine = std::move(_coroutine), promise = std::move(promise)]() mutable -> boost::asio::awaitable<void> {
try {
if constexpr (!std::is_void_v<T>) {
T result = co_await std::move(_coroutine);
promise.set_value(std::move(result));
} else {
co_await std::move(_coroutine);
promise.set_value(); // Za void ne postavljamo rezultat
}
} catch (...) {
promise.set_exception(std::current_exception()); // Postavljamo izuzetak
}
}, boost::asio::detached);
return future;
}
#endif
/**
* Block until the asynchronous call completes
*/
@ -36,26 +69,53 @@ T await_(future<T>&& r) {
}
/**
* Block until the asynchronous call completes or time expired
* Run the function asynchronously an block until completes
*/
template<typename T>
T await_(future<T>& r, uint64_t time) {
if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) {
throw runtime_error("Asynchronous execution timed out");
}
return r.get();
template<class F, class... Args>
auto await_(F&& f, Args&&... args) -> typename result_of<F(Args...)>::type {
return await_(
async_(f, args...)
);
}
#if __cplusplus >= 202002L
/**
* Run the coruotine and wait
*/
template <typename T>
T await_(boost::asio::awaitable<T> _coroutine) {
return await_(
async_(
move(_coroutine)
));
}
#endif
/**
* Block until the asynchronous call completes or time expired
*/
template<typename T>
T await_(future<T>&& r, uint64_t time) {
if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) {
throw runtime_error("Asynchronous execution timed out");
}
return move(r).get();
}
// template<typename T>
// T await_(future<T>& r, uint64_t time) {
// if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) {
// throw runtime_error("Asynchronous execution timed out");
// }
// return r.get();
// }
/**
* Block until the asynchronous call completes or time expired
*/
// template<typename T>
// T await_(future<T>&& r, uint64_t time) {
// if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) {
// throw runtime_error("Asynchronous execution timed out");
// }
// return move(r).get();
// }
}
}

View File

@ -11,6 +11,10 @@ namespace asynco {
#define async_ marcelb::asynco::async_
#define await_ marcelb::asynco::await_
#if __cplusplus >= 202002L
#define asyncable boost::asio::awaitable
#endif
}
}

View File

@ -24,7 +24,7 @@ int64_t rtime_us();
/**
* Core timer class for construct time async functions
*/
class timer {
class Timer {
boost::asio::steady_timer st;
bool _stop = false;
bool repeate;
@ -35,14 +35,13 @@ class timer {
/**
* A method to assign a callback wrapper and a reinitialization algorithm
*/
void init();
void init();
public:
/**
* The constructor creates the steady_timer and accompanying variables and runs a method to initialize the timer
*/
timer (function<void()> _callback, uint64_t _time, bool _repeate);
Timer (function<void()> _callback, uint64_t _time, bool _repeate);
/**
* Stop timer
@ -68,21 +67,21 @@ class timer {
/**
* The destructor stops the timer
*/
~timer();
~Timer();
};
/**
* Class periodic for periodic execution of the callback in time in ms
*/
class periodic {
shared_ptr<timer> _timer;
class Periodic {
shared_ptr<Timer> _timer;
public:
/**
* Constructor initializes a shared pointer of type timer
*/
periodic(function<void()> callback, uint64_t time);
Periodic(function<void()> callback, uint64_t time);
/**
* Stop periodic
@ -108,21 +107,21 @@ class periodic {
/**
* The destructor stops the periodic
*/
~periodic();
~Periodic();
};
/**
* Class delayed for delayed callback execution in ms
*/
class delayed {
shared_ptr<timer> _timer;
class Delayed {
shared_ptr<Timer> _timer;
public:
/**
* Constructor initializes a shared pointer of type timer
*/
delayed(function<void()> callback, uint64_t time);
Delayed(function<void()> callback, uint64_t time);
/**
* Stop delayed
@ -147,13 +146,10 @@ class delayed {
/**
* The destructor stops the delayed
*/
~delayed();
~Delayed();
};
shared_ptr<periodic> Periodic(function<void()> callback, uint64_t time);
shared_ptr<delayed> Delayed(function<void()> callback, uint64_t time);
}
}

View File

@ -11,14 +11,13 @@ using namespace std;
#include "engine.hpp"
namespace marcelb {
namespace asynco {
namespace triggers {
/**
* trigger class, for event-driven programming.
* Trigger class, for event-driven programming.
* These events are typed according to the arguments of the callback function
*/
template<typename... T>
class trigger {
class Trigger {
private:
mutex m_eve;
unordered_map<string, vector<function<void(T...)>>> triggers;
@ -48,7 +47,7 @@ class trigger {
}
/**
* Remove an trigger listener from an event
* Remove an Trigger listener from an event
*/
void off(const string& key) {
lock_guard _off(m_eve);
@ -56,7 +55,7 @@ class trigger {
}
/**
* Remove all trigger listener
* Remove all Trigger listener
*/
void off() {
lock_guard _off(m_eve);
@ -65,7 +64,7 @@ class trigger {
/**
* Get num of listeners by an trigger key
* Get num of listeners by an Trigger key
*/
unsigned int listeners(const string& key) {
return triggers[key].size();
@ -85,7 +84,6 @@ class trigger {
};
}
}
}

View File

@ -14,7 +14,7 @@ int64_t rtime_us() {
.count();
}
void timer::init() {
void Timer::init() {
st.async_wait( [this] (const boost::system::error_code&) {
if (!_stop) {
callback();
@ -27,7 +27,7 @@ void timer::init() {
});
}
timer::timer (function<void()> _callback, uint64_t _time, bool _repeate) :
Timer::Timer (function<void()> _callback, uint64_t _time, bool _repeate) :
st(_asynco_engine.io_context, boost::asio::chrono::milliseconds(_time)),
_stop(false),
repeate(_repeate),
@ -37,109 +37,74 @@ timer::timer (function<void()> _callback, uint64_t _time, bool _repeate) :
init();
}
void timer::stop() {
void Timer::stop() {
_stop = true;
st.cancel();
}
void timer::now() {
void Timer::now() {
st.cancel();
}
uint64_t timer::ticks() {
uint64_t Timer::ticks() {
return _ticks;
}
bool timer::stoped() {
bool Timer::stoped() {
return _stop;
}
timer::~timer() {
Timer::~Timer() {
stop();
}
periodic::periodic(function<void()> callback, uint64_t time) :
_timer(make_shared<timer> (callback, time, true)) {
Periodic::Periodic(function<void()> callback, uint64_t time) :
_timer(make_shared<Timer> (callback, time, true)) {
}
void periodic::stop() {
void Periodic::stop() {
_timer->stop();
}
void periodic::now() {
void Periodic::now() {
_timer->now();
}
uint64_t periodic::ticks() {
uint64_t Periodic::ticks() {
return _timer->ticks();
}
bool periodic::stoped() {
bool Periodic::stoped() {
return _timer->stoped();
}
periodic::~periodic() {
Periodic::~Periodic() {
stop();
}
delayed::delayed(function<void()> callback, uint64_t time) :
_timer(make_shared<timer> (callback, time, false)) {
Delayed::Delayed(function<void()> callback, uint64_t time) :
_timer(make_shared<Timer> (callback, time, false)) {
}
void delayed::stop() {
void Delayed::stop() {
_timer->stop();
}
void delayed::now() {
void Delayed::now() {
_timer->now();
}
bool delayed::expired() {
bool Delayed::expired() {
return bool(_timer->ticks());
}
bool delayed::stoped() {
bool Delayed::stoped() {
return _timer->stoped();
}
delayed::~delayed() {
Delayed::~Delayed() {
stop();
}
mutex p_io, d_io;
vector<shared_ptr<periodic>> periodic_calls_container;
vector<shared_ptr<delayed>> delayed_calls_container;
shared_ptr<periodic> Periodic(function<void()> callback, uint64_t time) {
shared_ptr<periodic> periodic_ptr(make_shared<periodic>(callback, time));
async_ ( [&, periodic_ptr](){
lock_guard<mutex> lock(p_io);
periodic_calls_container.push_back(periodic_ptr);
for (uint32_t i=0; i<periodic_calls_container.size(); i++) {
if (periodic_calls_container[i]->stoped()) {
periodic_calls_container.erase(periodic_calls_container.begin()+i);
i--;
}
}
});
return periodic_ptr;
}
shared_ptr<delayed> Delayed(function<void()> callback, uint64_t time) {
shared_ptr<delayed> delayed_ptr(make_shared<delayed>(callback, time));
async_ ( [&, delayed_ptr](){
lock_guard<mutex> lock(p_io);
delayed_calls_container.push_back(delayed_ptr);
for (uint32_t i=0; i<delayed_calls_container.size(); i++) {
if (delayed_calls_container[i]->stoped() || delayed_calls_container[i]->expired()) {
delayed_calls_container.erase(delayed_calls_container.begin()+i);
i--;
}
}
});
return delayed_ptr;
}
};

View File

@ -7,7 +7,6 @@
#include "define.hpp"
using namespace marcelb::asynco;
using namespace triggers;
#include <iostream>
#include <unistd.h>
@ -18,80 +17,97 @@ using namespace triggers;
using namespace std;
using namespace this_thread;
asyncable<int> c2 (int a) {
co_return a*2;
}
asyncable<void> sleep_co (int a) {
sleep(a);
cout << "Gotov" << endl;
co_return;
}
void sleep_to (int _time) {
promise<void> _promise;
delayed t( [&]() {
_promise.set_value();
}, _time);
asyncable<void> c () {
cout << "Ispisi" << endl;
co_await c2(0);
co_return;
}
return _promise.get_future().get();
}
void promise_reject (int _time) {
promise<void> _promise;
delayed t( [&]() {
try {
// simulate except
throw runtime_error("Error simulation");
_promise.set_value();
} catch (...) {
_promise.set_exception(current_exception());
}
}, _time);
return _promise.get_future().get();
}
// void sleep_to (int _time) {
// promise<void> _promise;
// Delayed t( [&]() {
// _promise.set_value();
// }, _time);
void notLambdaFunction() {
cout << "Call to not lambda function" << endl;
}
// return _promise.get_future().get();
// }
class clm {
public:
void classMethode() {
cout << "Call class method" << endl;
}
};
// void promise_reject (int _time) {
// promise<void> _promise;
// Delayed t( [&]() {
// try {
// // simulate except
// throw runtime_error("Error simulation");
// _promise.set_value();
// } catch (...) {
// _promise.set_exception(current_exception());
// }
// }, _time);
// ------------------ EXTEND OWN CLASS WITH EVENTS -------------------
// return _promise.get_future().get();
// }
class myOwnClass : public trigger<int> {
public:
myOwnClass() : trigger() {};
};
// void notLambdaFunction() {
// cout << "Call to not lambda function" << endl;
// }
// class clm {
// public:
// void classMethode() {
// cout << "Call class method" << endl;
// }
// };
// // ------------------ EXTEND OWN CLASS WITH EVENTS -------------------
// class myOwnClass : public Trigger<int> {
// public:
// myOwnClass() : Trigger() {};
// };
// ----------------- MULTIPLE TRIGGERS IN ONE CLASS ------------------
class ClassWithTriggers {
trigger<int> emitter1;
trigger<string> emitter2;
// class ClassWithTriggers {
// Trigger<int> emitter1;
// Trigger<string> emitter2;
public:
template<typename... T>
void on(const string& key, function<void(T...)> callback) {
if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, int>) {
emitter1.on(key, callback);
}
else if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, string>) {
emitter2.on(key, callback);
}
}
// public:
// template<typename... T>
// void on(const string& key, function<void(T...)> callback) {
// if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, int>) {
// emitter1.on(key, callback);
// }
// else if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, string>) {
// emitter2.on(key, callback);
// }
// }
template <typename... Args>
void tick(const string& key, Args&&... args) {
if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, int>) {
emitter1.tick(key, forward<Args>(args)...);
}
else if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, string>) {
emitter2.tick(key, forward<Args>(args)...);
}
else {
static_assert(sizeof...(Args) == 0, "Unsupported number or types of arguments");
}
}
};
// template <typename... Args>
// void tick(const string& key, Args&&... args) {
// if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, int>) {
// emitter1.tick(key, forward<Args>(args)...);
// }
// else if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, string>) {
// emitter2.tick(key, forward<Args>(args)...);
// }
// else {
// static_assert(sizeof...(Args) == 0, "Unsupported number or types of arguments");
// }
// }
// };
int main () {
@ -101,36 +117,36 @@ int main () {
// --------------- TIME ASYNCHRONOUS FUNCTIONS --------------
/**
* Init periodic and delayed; clear periodic and delayed
* Init Periodic and delayed; clear Periodic and delayed
*/
// periodic inter1 ([&]() {
// cout << "periodic prvi " << rtime_ms() - start << endl;
// Periodic inter1 ([&]() {
// cout << "Periodic prvi " << rtime_ms() - start << endl;
// }, 1000);
// periodic inter2 ([&]() {
// cout << "periodic drugi " << rtime_ms() - start << endl;
// Periodic inter2 ([&]() {
// cout << "Periodic drugi " << rtime_ms() - start << endl;
// }, 2000);
// periodic inter3 ([&]() {
// cout << "periodic treći " << rtime_ms() - start << endl;
// Periodic inter3 ([&]() {
// cout << "Periodic treći " << rtime_ms() - start << endl;
// }, 1000);
// periodic inter4 ([&]() {
// // cout << "periodic cetvrti " << rtime_ms() - start << endl;
// Periodic inter4 ([&]() {
// // cout << "Periodic cetvrti " << rtime_ms() - start << endl;
// cout << "Ticks " << inter3.ticks() << endl;
// }, 500);
// periodic inter5 ([&]() {
// cout << "periodic peti " << rtime_ms() - start << endl;
// Periodic inter5 ([&]() {
// cout << "Periodic peti " << rtime_ms() - start << endl;
// }, 2000);
// periodic inter6 ([&]() {
// cout << "periodic sesti " << rtime_ms() - start << endl;
// Periodic inter6 ([&]() {
// cout << "Periodic sesti " << rtime_ms() - start << endl;
// }, 3000);
// delayed time1 ( [&] () {
// cout << "Close periodic 1 i 2 " << rtime_ms() - start << endl;
// Delayed time1 ( [&] () {
// cout << "Close Periodic 1 i 2 " << rtime_ms() - start << endl;
// inter1.stop();
// cout << "inter1.stop " << endl;
// inter2.stop();
@ -138,8 +154,8 @@ int main () {
// }, 8000);
// delayed time2 ([&] () {
// cout << "Close periodic 3 " << rtime_ms() - start << endl;
// Delayed time2 ([&] () {
// cout << "Close Periodic 3 " << rtime_ms() - start << endl;
// inter3.stop();
// cout << "Stoped " << inter3.stoped() << endl;
// // time1.stop();
@ -244,7 +260,7 @@ int main () {
// })) << endl;
// /**
// * Sleep with delayed sleep implement
// * Sleep with Delayed sleep implement
// */
// sleep_to(3000);
@ -335,9 +351,9 @@ int main () {
// * initialization of typed events
// */
// trigger<int, int> ev2int;
// trigger<int, string> evintString;
// trigger<> evoid;
// Trigger<int, int> ev2int;
// Trigger<int, string> evintString;
// Trigger<> evoid;
// ev2int.on("sum", [](int a, int b) {
// cout << "Sum " << a+b << endl;
@ -390,7 +406,7 @@ int main () {
// myOwnClass myclass;
// delayed t( [&] {
// Delayed t( [&] {
// myclass.tick("constructed", 1);
// }, 200);
@ -404,18 +420,18 @@ int main () {
// *
// */
ClassWithTriggers mt;
// ClassWithTriggers mt;
mt.on<int>("int", function<void(int)>([&](int i) {
cout << "Emit int " << i << endl;
}));
// mt.on<int>("int", function<void(int)>([&](int i) {
// cout << "Emit int " << i << endl;
// }));
mt.on<string>("string", function<void(string)>([&](string s) {
cout << "Emit string " << s << endl;
}));
// mt.on<string>("string", function<void(string)>([&](string s) {
// cout << "Emit string " << s << endl;
// }));
mt.tick("int", 5);
mt.tick("string", string("Hello world"));
// mt.tick("int", 5);
// mt.tick("string", string("Hello world"));
// auto status = fs::read("test1.txt");
@ -446,9 +462,124 @@ int main () {
// // ----------------------------------------------------------------------------------------------------
cout << "Run" << endl;
_asynco_engine.run();
// auto i = async_ ( []() -> asyncable<int> {
// cout << "aaaa" << endl;
// co_return 5;
// });
// auto i = async_ (retint());
// auto i_ = await_(i);
// cout << i_ << endl;
// Periodic a( []() -> asyncable<void> {
// cout << "corutina" << endl;
// // co_await retint();
// }, 2000);
// Periodic b( []() {
// cout << "funckija" << endl;
// }, 2000);
// Trigger<int, int> ev2int;
// Trigger<int, string> evintString;
// Trigger<> evoid;
// ev2int.on("sum", [](int a, int b) -> asyncable<void> {
// cout << "Sum " << a+b << endl;
// });
// ev2int.on("sum", [](int a, int b) -> asyncable<void> {
// cout << "Sum done" << endl;
// });
// evintString.on("substract", [](int a, string b) -> asyncable<void> {
// cout << "Substract " << a-stoi(b) << endl;
// });
// evoid.on("void", []() {
// auto a = await_ (async_ (c2(34)));
// cout << "A " << a << endl;
// });
// auto c1 = []() -> asyncable<void> {
// cout << "Roge " << endl;
// co_return;
// };
// auto a = await_ ( c2(3));
// cout << a << endl;
// await_ ([]() -> asyncable<void> {
// cout << "Hello" << endl;
// co_await c2(4);
// co_return;
// }());
async_ ([]() -> asyncable<void> {
cout << "1" << endl;
co_await sleep_co(1);
co_return;
}());
async_ ([]() -> asyncable<void> {
cout << "2" << endl;
co_await sleep_co(1);
co_return;
}());
async_ ([]() -> asyncable<void> {
cout << "3" << endl;
co_await sleep_co(1);
co_return;
}());
async_ ([]() -> asyncable<void> {
cout << "4" << endl;
co_await sleep_co(1);
co_return;
}());
async_ ([]() -> asyncable<void> {
cout << "5" << endl;
co_await sleep_co(1);
co_return;
}());
// await_ ([]() {
// cout << "Hello" << endl;
// });
// Periodic p( []() {
// async_ (
// c2(34)
// );
// }, 2000);
// await_( async_co2 ( [c1 = move(c1)]() -> asyncable<void> {
// cout << "Baba roga" << endl;
// co_await c1();
// }));
// string emited2 = "2";
// evoid.on("void", [&]() -> asyncable<void> {
// cout << "Void emited " << emited2 << endl;
// });
// evoid.tick("void");
cout << "-------------end main-------------" << endl;
_asynco_engine.run();
return 0;
}