Compare commits
No commits in common. "coroutines" and "dev" have entirely different histories.
coroutines
...
dev
@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.10)
|
|||||||
project(Asynco)
|
project(Asynco)
|
||||||
|
|
||||||
# Postavi verziju projekta
|
# Postavi verziju projekta
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
|
||||||
# Pronađi Boost biblioteku (ako nije uobičajeni direktorijum, postavi put)
|
# Pronađi Boost biblioteku (ako nije uobičajeni direktorijum, postavi put)
|
||||||
|
174
README.md
174
README.md
@ -1,13 +1,13 @@
|
|||||||
|
|
||||||
# Asynco
|
# Asynco
|
||||||
|
|
||||||
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.
|
A C++ library for event-driven asynchronous multi-threaded programming.
|
||||||
|
|
||||||
## Motivation
|
## Motivation
|
||||||
|
|
||||||
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 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 asynchronous filesystem was included solely to demonstrate how users can wrap any time- or I/O-intensive functions for asynchronous execution.
|
The asynchronous filesystem is provided solely to guide users on how to wrap any time- or IO-intensive function for asynchronous execution.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
@ -16,13 +16,12 @@ The asynchronous filesystem was included solely to demonstrate how users can wra
|
|||||||
- Header only
|
- Header only
|
||||||
- Asynchronous programming
|
- Asynchronous programming
|
||||||
- Multithread
|
- 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)
|
- Typed events (on, tick, off) (like EventEmitter from JS: on, emit, etc)
|
||||||
- Event loops
|
- Event loops
|
||||||
- Multiple parallel execution loops
|
- Multiple parallel execution loops
|
||||||
- Asynchronous file IO
|
- Asynchronous file IO
|
||||||
- Based on ASIO (Boost Asio)
|
- Based on ASIO (Boost Asio)
|
||||||
- On C++20 support Boost.Asio coroutines
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Just download the latest release and unzip it into your project.
|
Just download the latest release and unzip it into your project.
|
||||||
@ -31,13 +30,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
|
#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/asynco.hpp" // async_ (), await_()
|
||||||
#include "asynco/lib/triggers.hpp" // Trigger (event emitter)
|
#include "asynco/lib/triggers.hpp" // trigger (event emitter)
|
||||||
#include "asynco/lib/timers.hpp" // Periodic, Delayed (like setInterval and setTimeout from JS)
|
#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/filesystem.hpp" // for async read and write files
|
||||||
#include "asynco/lib/define.hpp" // async_, await_, asyncable_ defines
|
|
||||||
|
|
||||||
using namespace marcelb;
|
using namespace marcelb;
|
||||||
using namespace asynco;
|
using namespace asynco;
|
||||||
|
using namespace triggers;
|
||||||
|
|
||||||
// At the end of the main function, always set
|
// At the end of the main function, always set
|
||||||
_asynco_engine.run();
|
_asynco_engine.run();
|
||||||
@ -47,15 +46,11 @@ return 0;
|
|||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
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.
|
Time asynchronous functions
|
||||||
|
|
||||||
### Timers
|
|
||||||
|
|
||||||
We have two timer classes, Periodic (which runs a callback function periodically), and Delayed (delayed runs a callback function only once).
|
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
// start periodic
|
// start periodic
|
||||||
Periodic inter1 ([]() {
|
periodic inter1 ([]() {
|
||||||
cout << "Interval 1" << endl;
|
cout << "Interval 1" << endl;
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
@ -69,7 +64,7 @@ int t = inter1.ticks();
|
|||||||
bool stoped = inter1.stoped();
|
bool stoped = inter1.stoped();
|
||||||
|
|
||||||
// start delayed
|
// start delayed
|
||||||
Delayed time1 ( [] () {
|
delayed time1 ( [] () {
|
||||||
cout << "Timeout 1 " << endl;
|
cout << "Timeout 1 " << endl;
|
||||||
}, 10000);
|
}, 10000);
|
||||||
|
|
||||||
@ -82,10 +77,30 @@ int t = time1.expired();
|
|||||||
// is it stopped
|
// is it stopped
|
||||||
bool stoped = time1.stoped();
|
bool stoped = time1.stoped();
|
||||||
|
|
||||||
```
|
// If you don't want to save in a variable, but you want to start a timer, use these functions
|
||||||
### Make functions asynchronous
|
// And you can also save them, they are only of the shared pointer type
|
||||||
|
|
||||||
Running functions at runtime, asynchronous execution, uses the `async_` call and its return type is `std::future<T>`
|
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
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
/**
|
/**
|
||||||
@ -124,11 +139,12 @@ clm classes;
|
|||||||
async_ ( [&classes] () {
|
async_ ( [&classes] () {
|
||||||
classes.classMethode();
|
classes.classMethode();
|
||||||
});
|
});
|
||||||
```
|
|
||||||
|
|
||||||
To wait for the result (blocking the flow) use `await_` (basically nothing more than a `.get()` call on a future object)
|
|
||||||
|
|
||||||
```c++
|
|
||||||
|
/**
|
||||||
|
* await_ after runned as async
|
||||||
|
*/
|
||||||
|
|
||||||
auto a = async_ ( []() {
|
auto a = async_ ( []() {
|
||||||
sleep_for(2s); // only for simulating long duration function
|
sleep_for(2s); // only for simulating long duration function
|
||||||
@ -148,20 +164,10 @@ cout << await_(async_ ( [] () {
|
|||||||
return 4;
|
return 4;
|
||||||
})) << endl;
|
})) << endl;
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
If you want to run asynchronously but need the result immediately, you can use a shorter notation
|
/**
|
||||||
|
* Await all
|
||||||
```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_ ( []() {
|
auto a = async_ ( []() {
|
||||||
cout << "A" << endl;
|
cout << "A" << endl;
|
||||||
@ -212,18 +218,13 @@ auto await_all = [&] () {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
```
|
|
||||||
Just an example:
|
|
||||||
|
|
||||||
```c++
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sleep with delayed sleep implement
|
* Sleep with delayed sleep implement
|
||||||
**/
|
*/
|
||||||
|
|
||||||
void sleep_to (int _time) {
|
void sleep_to (int _time) {
|
||||||
promise<void> _promise;
|
promise<void> _promise;
|
||||||
Delayed t( [&]() {
|
delayed t( [&]() {
|
||||||
_promise.set_value();
|
_promise.set_value();
|
||||||
}, _time);
|
}, _time);
|
||||||
|
|
||||||
@ -238,7 +239,7 @@ sleep_to(3000);
|
|||||||
|
|
||||||
void promise_reject (int _time) {
|
void promise_reject (int _time) {
|
||||||
promise<void> _promise;
|
promise<void> _promise;
|
||||||
Delayed t( [&]() {
|
delayed t( [&]() {
|
||||||
try {
|
try {
|
||||||
// simulate except
|
// simulate except
|
||||||
throw runtime_error("Error simulation");
|
throw runtime_error("Error simulation");
|
||||||
@ -257,19 +258,16 @@ try {
|
|||||||
cout<< err.what() << endl;
|
cout<< err.what() << endl;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
Events
|
||||||
### Triggers
|
|
||||||
|
|
||||||
The library implements Triggers, which are basically typed Events.
|
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
/**
|
/**
|
||||||
* initialization of typed events
|
* initialization of typed events
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Trigger<int, int> ev2int;
|
trigger<int, int> ev2int;
|
||||||
Trigger<int, string> evintString;
|
trigger<int, string> evintString;
|
||||||
Trigger<> evoid;
|
trigger<> evoid;
|
||||||
|
|
||||||
ev2int.on("sum", [](int a, int b) {
|
ev2int.on("sum", [](int a, int b) {
|
||||||
cout << "Sum " << a+b << endl;
|
cout << "Sum " << a+b << endl;
|
||||||
@ -314,14 +312,14 @@ evoid.tick("void"); // nothing is happening
|
|||||||
Extend own class whit events
|
Extend own class whit events
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
class myOwnClass : public Trigger<int> {
|
class myOwnClass : public trigger<int> {
|
||||||
public:
|
public:
|
||||||
myOwnClass() : Trigger() {};
|
myOwnClass() : trigger() {};
|
||||||
};
|
};
|
||||||
|
|
||||||
myOwnClass myclass;
|
myOwnClass myclass;
|
||||||
|
|
||||||
Delayed t( [&] {
|
delayed t( [&] {
|
||||||
myclass.tick("constructed", 1);
|
myclass.tick("constructed", 1);
|
||||||
}, 200);
|
}, 200);
|
||||||
|
|
||||||
@ -336,8 +334,8 @@ Implementing a class with multiple triggers of different types
|
|||||||
```c++
|
```c++
|
||||||
|
|
||||||
class ClassWithTriggers {
|
class ClassWithTriggers {
|
||||||
Trigger<int> emitter1;
|
trigger<int> emitter1;
|
||||||
Trigger<string> emitter2;
|
trigger<string> emitter2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
template<typename... T>
|
template<typename... T>
|
||||||
@ -379,7 +377,7 @@ mt.tick("string", string("Hello world"));
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Another example:
|
|
||||||
Asynchronous file IO
|
Asynchronous file IO
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
@ -421,70 +419,6 @@ 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
|
## License
|
||||||
|
|
||||||
[APACHE 2.0](http://www.apache.org/licenses/LICENSE-2.0/)
|
[APACHE 2.0](http://www.apache.org/licenses/LICENSE-2.0/)
|
||||||
|
@ -3,13 +3,8 @@
|
|||||||
|
|
||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#if __cplusplus >= 202002L
|
using namespace std;
|
||||||
#include <boost/asio/awaitable.hpp>
|
|
||||||
#include <boost/asio/co_spawn.hpp>
|
|
||||||
#include <boost/asio/use_awaitable.hpp>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace marcelb {
|
namespace marcelb {
|
||||||
namespace asynco {
|
namespace asynco {
|
||||||
@ -24,34 +19,6 @@ auto async_(F&& f, Args&&... args) -> future<typename result_of<F(Args...)>::typ
|
|||||||
return res;
|
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
|
* Block until the asynchronous call completes
|
||||||
*/
|
*/
|
||||||
@ -69,53 +36,26 @@ T await_(future<T>&& r) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the function asynchronously an block until completes
|
* Block until the asynchronous call completes or time expired
|
||||||
*/
|
*/
|
||||||
template<class F, class... Args>
|
template<typename T>
|
||||||
auto await_(F&& f, Args&&... args) -> typename result_of<F(Args...)>::type {
|
T await_(future<T>& r, uint64_t time) {
|
||||||
return await_(
|
if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) {
|
||||||
async_(f, args...)
|
throw runtime_error("Asynchronous execution timed out");
|
||||||
);
|
}
|
||||||
|
return r.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#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
|
* Block until the asynchronous call completes or time expired
|
||||||
*/
|
*/
|
||||||
// template<typename T>
|
template<typename T>
|
||||||
// T await_(future<T>& r, uint64_t time) {
|
T await_(future<T>&& r, uint64_t time) {
|
||||||
// if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) {
|
if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) {
|
||||||
// throw runtime_error("Asynchronous execution timed out");
|
throw runtime_error("Asynchronous execution timed out");
|
||||||
// }
|
}
|
||||||
// return r.get();
|
return move(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();
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,10 +11,6 @@ namespace asynco {
|
|||||||
#define async_ marcelb::asynco::async_
|
#define async_ marcelb::asynco::async_
|
||||||
#define await_ marcelb::asynco::await_
|
#define await_ marcelb::asynco::await_
|
||||||
|
|
||||||
#if __cplusplus >= 202002L
|
|
||||||
#define asyncable boost::asio::awaitable
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ int64_t rtime_us();
|
|||||||
/**
|
/**
|
||||||
* Core timer class for construct time async functions
|
* Core timer class for construct time async functions
|
||||||
*/
|
*/
|
||||||
class Timer {
|
class timer {
|
||||||
boost::asio::steady_timer st;
|
boost::asio::steady_timer st;
|
||||||
bool _stop = false;
|
bool _stop = false;
|
||||||
bool repeate;
|
bool repeate;
|
||||||
@ -35,13 +35,14 @@ class Timer {
|
|||||||
/**
|
/**
|
||||||
* A method to assign a callback wrapper and a reinitialization algorithm
|
* A method to assign a callback wrapper and a reinitialization algorithm
|
||||||
*/
|
*/
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The constructor creates the steady_timer and accompanying variables and runs a method to initialize the timer
|
* 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
|
* Stop timer
|
||||||
@ -67,21 +68,21 @@ class Timer {
|
|||||||
/**
|
/**
|
||||||
* The destructor stops the timer
|
* The destructor stops the timer
|
||||||
*/
|
*/
|
||||||
~Timer();
|
~timer();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class periodic for periodic execution of the callback in time in ms
|
* Class periodic for periodic execution of the callback in time in ms
|
||||||
*/
|
*/
|
||||||
class Periodic {
|
class periodic {
|
||||||
shared_ptr<Timer> _timer;
|
shared_ptr<timer> _timer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor initializes a shared pointer of type timer
|
* Constructor initializes a shared pointer of type timer
|
||||||
*/
|
*/
|
||||||
Periodic(function<void()> callback, uint64_t time);
|
periodic(function<void()> callback, uint64_t time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop periodic
|
* Stop periodic
|
||||||
@ -107,21 +108,21 @@ class Periodic {
|
|||||||
/**
|
/**
|
||||||
* The destructor stops the periodic
|
* The destructor stops the periodic
|
||||||
*/
|
*/
|
||||||
~Periodic();
|
~periodic();
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class delayed for delayed callback execution in ms
|
* Class delayed for delayed callback execution in ms
|
||||||
*/
|
*/
|
||||||
class Delayed {
|
class delayed {
|
||||||
shared_ptr<Timer> _timer;
|
shared_ptr<timer> _timer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor initializes a shared pointer of type timer
|
* Constructor initializes a shared pointer of type timer
|
||||||
*/
|
*/
|
||||||
Delayed(function<void()> callback, uint64_t time);
|
delayed(function<void()> callback, uint64_t time);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop delayed
|
* Stop delayed
|
||||||
@ -146,10 +147,13 @@ class Delayed {
|
|||||||
/**
|
/**
|
||||||
* The destructor stops the 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);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,13 +11,14 @@ using namespace std;
|
|||||||
#include "engine.hpp"
|
#include "engine.hpp"
|
||||||
namespace marcelb {
|
namespace marcelb {
|
||||||
namespace asynco {
|
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
|
* These events are typed according to the arguments of the callback function
|
||||||
*/
|
*/
|
||||||
template<typename... T>
|
template<typename... T>
|
||||||
class Trigger {
|
class trigger {
|
||||||
private:
|
private:
|
||||||
mutex m_eve;
|
mutex m_eve;
|
||||||
unordered_map<string, vector<function<void(T...)>>> triggers;
|
unordered_map<string, vector<function<void(T...)>>> triggers;
|
||||||
@ -47,7 +48,7 @@ class Trigger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove an Trigger listener from an event
|
* Remove an trigger listener from an event
|
||||||
*/
|
*/
|
||||||
void off(const string& key) {
|
void off(const string& key) {
|
||||||
lock_guard _off(m_eve);
|
lock_guard _off(m_eve);
|
||||||
@ -55,7 +56,7 @@ class Trigger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove all Trigger listener
|
* Remove all trigger listener
|
||||||
*/
|
*/
|
||||||
void off() {
|
void off() {
|
||||||
lock_guard _off(m_eve);
|
lock_guard _off(m_eve);
|
||||||
@ -64,7 +65,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) {
|
unsigned int listeners(const string& key) {
|
||||||
return triggers[key].size();
|
return triggers[key].size();
|
||||||
@ -84,6 +85,7 @@ class Trigger {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ int64_t rtime_us() {
|
|||||||
.count();
|
.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::init() {
|
void timer::init() {
|
||||||
st.async_wait( [this] (const boost::system::error_code&) {
|
st.async_wait( [this] (const boost::system::error_code&) {
|
||||||
if (!_stop) {
|
if (!_stop) {
|
||||||
callback();
|
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)),
|
st(_asynco_engine.io_context, boost::asio::chrono::milliseconds(_time)),
|
||||||
_stop(false),
|
_stop(false),
|
||||||
repeate(_repeate),
|
repeate(_repeate),
|
||||||
@ -37,74 +37,109 @@ Timer::Timer (function<void()> _callback, uint64_t _time, bool _repeate) :
|
|||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::stop() {
|
void timer::stop() {
|
||||||
_stop = true;
|
_stop = true;
|
||||||
st.cancel();
|
st.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::now() {
|
void timer::now() {
|
||||||
st.cancel();
|
st.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t Timer::ticks() {
|
uint64_t timer::ticks() {
|
||||||
return _ticks;
|
return _ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Timer::stoped() {
|
bool timer::stoped() {
|
||||||
return _stop;
|
return _stop;
|
||||||
}
|
}
|
||||||
|
|
||||||
Timer::~Timer() {
|
timer::~timer() {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Periodic::Periodic(function<void()> callback, uint64_t time) :
|
periodic::periodic(function<void()> callback, uint64_t time) :
|
||||||
_timer(make_shared<Timer> (callback, time, true)) {
|
_timer(make_shared<timer> (callback, time, true)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Periodic::stop() {
|
void periodic::stop() {
|
||||||
_timer->stop();
|
_timer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Periodic::now() {
|
void periodic::now() {
|
||||||
_timer->now();
|
_timer->now();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t Periodic::ticks() {
|
uint64_t periodic::ticks() {
|
||||||
return _timer->ticks();
|
return _timer->ticks();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Periodic::stoped() {
|
bool periodic::stoped() {
|
||||||
return _timer->stoped();
|
return _timer->stoped();
|
||||||
}
|
}
|
||||||
|
|
||||||
Periodic::~Periodic() {
|
periodic::~periodic() {
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Delayed::Delayed(function<void()> callback, uint64_t time) :
|
delayed::delayed(function<void()> callback, uint64_t time) :
|
||||||
_timer(make_shared<Timer> (callback, time, false)) {
|
_timer(make_shared<timer> (callback, time, false)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Delayed::stop() {
|
void delayed::stop() {
|
||||||
_timer->stop();
|
_timer->stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Delayed::now() {
|
void delayed::now() {
|
||||||
_timer->now();
|
_timer->now();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Delayed::expired() {
|
bool delayed::expired() {
|
||||||
return bool(_timer->ticks());
|
return bool(_timer->ticks());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Delayed::stoped() {
|
bool delayed::stoped() {
|
||||||
return _timer->stoped();
|
return _timer->stoped();
|
||||||
}
|
}
|
||||||
|
|
||||||
Delayed::~Delayed() {
|
delayed::~delayed() {
|
||||||
stop();
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
319
test/main.cpp
319
test/main.cpp
@ -7,6 +7,7 @@
|
|||||||
#include "define.hpp"
|
#include "define.hpp"
|
||||||
|
|
||||||
using namespace marcelb::asynco;
|
using namespace marcelb::asynco;
|
||||||
|
using namespace triggers;
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -17,97 +18,80 @@ using namespace marcelb::asynco;
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace this_thread;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
asyncable<void> c () {
|
void sleep_to (int _time) {
|
||||||
cout << "Ispisi" << endl;
|
promise<void> _promise;
|
||||||
co_await c2(0);
|
delayed t( [&]() {
|
||||||
co_return;
|
_promise.set_value();
|
||||||
}
|
}, _time);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
// void sleep_to (int _time) {
|
return _promise.get_future().get();
|
||||||
// promise<void> _promise;
|
}
|
||||||
// Delayed t( [&]() {
|
|
||||||
// _promise.set_value();
|
|
||||||
// }, _time);
|
|
||||||
|
|
||||||
// return _promise.get_future().get();
|
void notLambdaFunction() {
|
||||||
// }
|
cout << "Call to not lambda function" << endl;
|
||||||
|
}
|
||||||
|
|
||||||
// void promise_reject (int _time) {
|
class clm {
|
||||||
// promise<void> _promise;
|
public:
|
||||||
// Delayed t( [&]() {
|
void classMethode() {
|
||||||
// try {
|
cout << "Call class method" << endl;
|
||||||
// // simulate except
|
}
|
||||||
// throw runtime_error("Error simulation");
|
};
|
||||||
// _promise.set_value();
|
|
||||||
// } catch (...) {
|
|
||||||
// _promise.set_exception(current_exception());
|
|
||||||
// }
|
|
||||||
// }, _time);
|
|
||||||
|
|
||||||
// return _promise.get_future().get();
|
// ------------------ EXTEND OWN CLASS WITH EVENTS -------------------
|
||||||
// }
|
|
||||||
|
|
||||||
// void notLambdaFunction() {
|
class myOwnClass : public trigger<int> {
|
||||||
// cout << "Call to not lambda function" << endl;
|
public:
|
||||||
// }
|
myOwnClass() : trigger() {};
|
||||||
|
};
|
||||||
// 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 ------------------
|
// ----------------- MULTIPLE TRIGGERS IN ONE CLASS ------------------
|
||||||
|
|
||||||
// class ClassWithTriggers {
|
class ClassWithTriggers {
|
||||||
// Trigger<int> emitter1;
|
trigger<int> emitter1;
|
||||||
// Trigger<string> emitter2;
|
trigger<string> emitter2;
|
||||||
|
|
||||||
// public:
|
public:
|
||||||
// template<typename... T>
|
template<typename... T>
|
||||||
// void on(const string& key, function<void(T...)> callback) {
|
void on(const string& key, function<void(T...)> callback) {
|
||||||
// if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, int>) {
|
if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, int>) {
|
||||||
// emitter1.on(key, callback);
|
emitter1.on(key, callback);
|
||||||
// }
|
}
|
||||||
// else if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, string>) {
|
else if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, string>) {
|
||||||
// emitter2.on(key, callback);
|
emitter2.on(key, callback);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
// template <typename... Args>
|
template <typename... Args>
|
||||||
// void tick(const string& key, Args&&... args) {
|
void tick(const string& key, Args&&... args) {
|
||||||
// if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, int>) {
|
if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, int>) {
|
||||||
// emitter1.tick(key, forward<Args>(args)...);
|
emitter1.tick(key, forward<Args>(args)...);
|
||||||
// }
|
}
|
||||||
// else if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, string>) {
|
else if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, string>) {
|
||||||
// emitter2.tick(key, forward<Args>(args)...);
|
emitter2.tick(key, forward<Args>(args)...);
|
||||||
// }
|
}
|
||||||
// else {
|
else {
|
||||||
// static_assert(sizeof...(Args) == 0, "Unsupported number or types of arguments");
|
static_assert(sizeof...(Args) == 0, "Unsupported number or types of arguments");
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
// };
|
};
|
||||||
|
|
||||||
|
|
||||||
int main () {
|
int main () {
|
||||||
@ -117,36 +101,36 @@ int main () {
|
|||||||
// --------------- TIME ASYNCHRONOUS FUNCTIONS --------------
|
// --------------- TIME ASYNCHRONOUS FUNCTIONS --------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init Periodic and delayed; clear Periodic and delayed
|
* Init periodic and delayed; clear periodic and delayed
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Periodic inter1 ([&]() {
|
// periodic inter1 ([&]() {
|
||||||
// cout << "Periodic prvi " << rtime_ms() - start << endl;
|
// cout << "periodic prvi " << rtime_ms() - start << endl;
|
||||||
// }, 1000);
|
// }, 1000);
|
||||||
|
|
||||||
// Periodic inter2 ([&]() {
|
// periodic inter2 ([&]() {
|
||||||
// cout << "Periodic drugi " << rtime_ms() - start << endl;
|
// cout << "periodic drugi " << rtime_ms() - start << endl;
|
||||||
// }, 2000);
|
// }, 2000);
|
||||||
|
|
||||||
// Periodic inter3 ([&]() {
|
// periodic inter3 ([&]() {
|
||||||
// cout << "Periodic treći " << rtime_ms() - start << endl;
|
// cout << "periodic treći " << rtime_ms() - start << endl;
|
||||||
// }, 1000);
|
// }, 1000);
|
||||||
|
|
||||||
// Periodic inter4 ([&]() {
|
// periodic inter4 ([&]() {
|
||||||
// // cout << "Periodic cetvrti " << rtime_ms() - start << endl;
|
// // cout << "periodic cetvrti " << rtime_ms() - start << endl;
|
||||||
// cout << "Ticks " << inter3.ticks() << endl;
|
// cout << "Ticks " << inter3.ticks() << endl;
|
||||||
// }, 500);
|
// }, 500);
|
||||||
|
|
||||||
// Periodic inter5 ([&]() {
|
// periodic inter5 ([&]() {
|
||||||
// cout << "Periodic peti " << rtime_ms() - start << endl;
|
// cout << "periodic peti " << rtime_ms() - start << endl;
|
||||||
// }, 2000);
|
// }, 2000);
|
||||||
|
|
||||||
// Periodic inter6 ([&]() {
|
// periodic inter6 ([&]() {
|
||||||
// cout << "Periodic sesti " << rtime_ms() - start << endl;
|
// cout << "periodic sesti " << rtime_ms() - start << endl;
|
||||||
// }, 3000);
|
// }, 3000);
|
||||||
|
|
||||||
// Delayed time1 ( [&] () {
|
// delayed time1 ( [&] () {
|
||||||
// cout << "Close Periodic 1 i 2 " << rtime_ms() - start << endl;
|
// cout << "Close periodic 1 i 2 " << rtime_ms() - start << endl;
|
||||||
// inter1.stop();
|
// inter1.stop();
|
||||||
// cout << "inter1.stop " << endl;
|
// cout << "inter1.stop " << endl;
|
||||||
// inter2.stop();
|
// inter2.stop();
|
||||||
@ -154,8 +138,8 @@ int main () {
|
|||||||
// }, 8000);
|
// }, 8000);
|
||||||
|
|
||||||
|
|
||||||
// Delayed time2 ([&] () {
|
// delayed time2 ([&] () {
|
||||||
// cout << "Close Periodic 3 " << rtime_ms() - start << endl;
|
// cout << "Close periodic 3 " << rtime_ms() - start << endl;
|
||||||
// inter3.stop();
|
// inter3.stop();
|
||||||
// cout << "Stoped " << inter3.stoped() << endl;
|
// cout << "Stoped " << inter3.stoped() << endl;
|
||||||
// // time1.stop();
|
// // time1.stop();
|
||||||
@ -260,7 +244,7 @@ int main () {
|
|||||||
// })) << endl;
|
// })) << endl;
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * Sleep with Delayed sleep implement
|
// * Sleep with delayed sleep implement
|
||||||
// */
|
// */
|
||||||
|
|
||||||
// sleep_to(3000);
|
// sleep_to(3000);
|
||||||
@ -351,9 +335,9 @@ int main () {
|
|||||||
// * initialization of typed events
|
// * initialization of typed events
|
||||||
// */
|
// */
|
||||||
|
|
||||||
// Trigger<int, int> ev2int;
|
// trigger<int, int> ev2int;
|
||||||
// Trigger<int, string> evintString;
|
// trigger<int, string> evintString;
|
||||||
// Trigger<> evoid;
|
// trigger<> evoid;
|
||||||
|
|
||||||
// ev2int.on("sum", [](int a, int b) {
|
// ev2int.on("sum", [](int a, int b) {
|
||||||
// cout << "Sum " << a+b << endl;
|
// cout << "Sum " << a+b << endl;
|
||||||
@ -406,7 +390,7 @@ int main () {
|
|||||||
|
|
||||||
// myOwnClass myclass;
|
// myOwnClass myclass;
|
||||||
|
|
||||||
// Delayed t( [&] {
|
// delayed t( [&] {
|
||||||
// myclass.tick("constructed", 1);
|
// myclass.tick("constructed", 1);
|
||||||
// }, 200);
|
// }, 200);
|
||||||
|
|
||||||
@ -420,18 +404,18 @@ int main () {
|
|||||||
// *
|
// *
|
||||||
// */
|
// */
|
||||||
|
|
||||||
// ClassWithTriggers mt;
|
ClassWithTriggers mt;
|
||||||
|
|
||||||
// mt.on<int>("int", function<void(int)>([&](int i) {
|
mt.on<int>("int", function<void(int)>([&](int i) {
|
||||||
// cout << "Emit int " << i << endl;
|
cout << "Emit int " << i << endl;
|
||||||
// }));
|
}));
|
||||||
|
|
||||||
// mt.on<string>("string", function<void(string)>([&](string s) {
|
mt.on<string>("string", function<void(string)>([&](string s) {
|
||||||
// cout << "Emit string " << s << endl;
|
cout << "Emit string " << s << endl;
|
||||||
// }));
|
}));
|
||||||
|
|
||||||
// mt.tick("int", 5);
|
mt.tick("int", 5);
|
||||||
// mt.tick("string", string("Hello world"));
|
mt.tick("string", string("Hello world"));
|
||||||
|
|
||||||
|
|
||||||
// auto status = fs::read("test1.txt");
|
// auto status = fs::read("test1.txt");
|
||||||
@ -462,124 +446,9 @@ int main () {
|
|||||||
|
|
||||||
// // ----------------------------------------------------------------------------------------------------
|
// // ----------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
cout << "Run" << endl;
|
||||||
// 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();
|
_asynco_engine.run();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user