diff --git a/CMakeLists.txt b/CMakeLists.txt index 681174e..b89631e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) diff --git a/README.md b/README.md index 900a4b9..6d36554 100644 --- a/README.md +++ b/README.md @@ -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` ```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 _promise; - delayed t( [&]() { + Delayed t( [&]() { _promise.set_value(); }, _time); @@ -239,7 +238,7 @@ sleep_to(3000); void promise_reject (int _time) { promise _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 ev2int; -trigger evintString; -trigger<> evoid; +Trigger ev2int; +Trigger 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 { +class myOwnClass : public Trigger { 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 emitter1; - trigger emitter2; + Trigger emitter1; + Trigger emitter2; public: template @@ -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`; if not, just use `boost::asio::awaitable`. + +```c++ + +asyncable 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 { + 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 { + 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/) diff --git a/lib/asynco.hpp b/lib/asynco.hpp index 6358cb0..149fa84 100644 --- a/lib/asynco.hpp +++ b/lib/asynco.hpp @@ -3,9 +3,14 @@ #include "engine.hpp" #include - using namespace std; +#if __cplusplus >= 202002L +#include +#include +#include +#endif + namespace marcelb { namespace asynco { @@ -19,21 +24,33 @@ auto async_(F&& f, Args&&... args) -> future::typ return res; } +#if __cplusplus >= 202002L /** - * Block until the asynchronous call completes + * Run the coroutine */ -template -T await_(future& r) { - return r.get(); +template +std::future async_(boost::asio::awaitable _coroutine) { + std::promise promise; + auto future = promise.get_future(); + + co_spawn(_asynco_engine.io_context, [_coroutine = std::move(_coroutine), promise = std::move(promise)]() mutable -> boost::asio::awaitable { + try { + if constexpr (!std::is_void_v) { + 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; } -/** - * Block until the asynchronous call completes -*/ -template -T await_(future&& r) { - return move(r).get(); -} +#endif /** * Block until the multiple asynchronous call completes @@ -56,27 +73,53 @@ auto await_(F&... f) -> std::tuple::type. } /** - * Block until the asynchronous call completes or time expired + * Block until the asynchronous call completes - dont block asynco engine loop */ template -T await_(future& r, uint64_t time) { - if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) { - throw runtime_error("Asynchronous execution timed out"); +T await_(future& r, uint16_t time_us = 10) { + while (r.wait_for(std::chrono::microseconds(time_us)) != std::future_status::ready) { + _asynco_engine.io_context.poll_one(); } - return r.get(); + return r.get(); } /** - * Block until the asynchronous call completes or time expired + * Block until the asynchronous call completes - dont block asynco engine loop */ template -T await_(future&& r, uint64_t time) { - if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) { - throw runtime_error("Asynchronous execution timed out"); - } +T await_(future&& r, uint16_t time_us = 10) { + while (r.wait_for(std::chrono::microseconds(time_us)) != std::future_status::ready) { + _asynco_engine.io_context.poll_one(); + } return move(r).get(); } +/** + * Run the function asynchronously an block until completes +*/ +template +auto await_(F&& f, Args&&... args) -> typename result_of::type { + return await_( + async_(f, args...) + ); +} + + +#if __cplusplus >= 202002L + +/** + * Run the coruotine and wait + */ +template +T await_(boost::asio::awaitable _coroutine) { + return await_( + async_( + move(_coroutine) + )); +} + +#endif + } } diff --git a/lib/define.hpp b/lib/define.hpp index bf2629a..b14acf4 100644 --- a/lib/define.hpp +++ b/lib/define.hpp @@ -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 + } } diff --git a/lib/timers.hpp b/lib/timers.hpp index c972166..7dc6fe5 100644 --- a/lib/timers.hpp +++ b/lib/timers.hpp @@ -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 _callback, uint64_t _time, bool _repeate); + Timer (function _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; +class Periodic { + shared_ptr _timer; public: /** * Constructor initializes a shared pointer of type timer */ - periodic(function callback, uint64_t time); + Periodic(function 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; +class Delayed { + shared_ptr _timer; public: /** * Constructor initializes a shared pointer of type timer */ - delayed(function callback, uint64_t time); + Delayed(function callback, uint64_t time); /** * Stop delayed @@ -147,13 +146,10 @@ class delayed { /** * The destructor stops the delayed */ - ~delayed(); + ~Delayed(); }; -shared_ptr Periodic(function callback, uint64_t time); -shared_ptr Delayed(function callback, uint64_t time); - } } diff --git a/lib/trigger.hpp b/lib/trigger.hpp index 30c43ca..0b37ca1 100644 --- a/lib/trigger.hpp +++ b/lib/trigger.hpp @@ -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 -class trigger { +class Trigger { private: mutex m_eve; unordered_map>> 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 { }; -} } } diff --git a/src/timers.cpp b/src/timers.cpp index 747f785..04ff1fd 100644 --- a/src/timers.cpp +++ b/src/timers.cpp @@ -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 _callback, uint64_t _time, bool _repeate) : +Timer::Timer (function _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 _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 callback, uint64_t time) : - _timer(make_shared (callback, time, true)) { +Periodic::Periodic(function callback, uint64_t time) : + _timer(make_shared (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 callback, uint64_t time) : - _timer(make_shared (callback, time, false)) { +Delayed::Delayed(function callback, uint64_t time) : + _timer(make_shared (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> periodic_calls_container; -vector> delayed_calls_container; - -shared_ptr Periodic(function callback, uint64_t time) { - shared_ptr periodic_ptr(make_shared(callback, time)); - async_ ( [&, periodic_ptr](){ - lock_guard lock(p_io); - periodic_calls_container.push_back(periodic_ptr); - for (uint32_t i=0; istoped()) { - periodic_calls_container.erase(periodic_calls_container.begin()+i); - i--; - } - } - }); - return periodic_ptr; -} - -shared_ptr Delayed(function callback, uint64_t time) { - shared_ptr delayed_ptr(make_shared(callback, time)); - async_ ( [&, delayed_ptr](){ - lock_guard lock(p_io); - delayed_calls_container.push_back(delayed_ptr); - for (uint32_t i=0; istoped() || delayed_calls_container[i]->expired()) { - delayed_calls_container.erase(delayed_calls_container.begin()+i); - i--; - } - } - }); - return delayed_ptr; -} - - }; diff --git a/test/main.cpp b/test/main.cpp index 18675c7..db14b7c 100644 --- a/test/main.cpp +++ b/test/main.cpp @@ -7,7 +7,6 @@ #include "define.hpp" using namespace marcelb::asynco; -using namespace triggers; #include #include @@ -18,80 +17,116 @@ using namespace triggers; using namespace std; using namespace this_thread; +// asyncable c2 (int a) { +// co_return a*2; +// } + +// asyncable sleep_co (int a) { +// sleep(a); +// cout << "Gotov" << endl; +// co_return; +// } -void sleep_to (int _time) { - promise _promise; - delayed t( [&]() { - _promise.set_value(); - }, _time); +// asyncable c () { +// cout << "Ispisi" << endl; +// co_await c2(0); +// co_return; +// } - return _promise.get_future().get(); -} -void promise_reject (int _time) { - promise _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 _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 sleep_to (int _time) { +// promise _promise; +// Delayed t( [&]() { +// _promise.set_value(); +// }, _time); +// await_ (_promise.get_future(), 100); +// } -// ------------------ EXTEND OWN CLASS WITH EVENTS ------------------- +// future sleep_to (int _time) { +// promise _promise; +// future _future = _promise.get_future(); + +// Delayed t( [&]() { +// _promise.set_value(); +// }, _time); -class myOwnClass : public trigger { - public: - myOwnClass() : trigger() {}; -}; +// return _future; +// } -// ----------------- MULTIPLE TRIGGERS IN ONE CLASS ------------------ +// void promise_reject (int _time) { +// promise _promise; +// Delayed t( [&]() { +// try { +// // simulate except +// throw runtime_error("Error simulation"); +// _promise.set_value(); +// } catch (...) { +// _promise.set_exception(current_exception()); +// } +// }, _time); -class ClassWithTriggers { - trigger emitter1; - trigger emitter2; +// return _promise.get_future().get(); +// } -public: - template - void on(const string& key, function callback) { - if constexpr (sizeof...(T) == 1 && is_same_v>, int>) { - emitter1.on(key, callback); - } - else if constexpr (sizeof...(T) == 1 && is_same_v>, string>) { - emitter2.on(key, callback); - } - } +// void notLambdaFunction() { +// cout << "Call to not lambda function" << endl; +// } - template - void tick(const string& key, Args&&... args) { - if constexpr (sizeof...(Args) == 1 && is_same_v>, int>) { - emitter1.tick(key, forward(args)...); - } - else if constexpr (sizeof...(Args) == 1 && is_same_v>, string>) { - emitter2.tick(key, forward(args)...); - } - else { - static_assert(sizeof...(Args) == 0, "Unsupported number or types of arguments"); - } - } -}; +// class clm { +// public: +// void classMethode() { +// cout << "Call class method" << endl; +// } +// }; + +// // // ------------------ EXTEND OWN CLASS WITH EVENTS ------------------- + +// class myOwnClass : public Trigger { +// public: +// myOwnClass() : Trigger() {}; +// }; + +// // ----------------- MULTIPLE TRIGGERS IN ONE CLASS ------------------ + +// class ClassWithTriggers { +// Trigger emitter1; +// Trigger emitter2; + +// public: +// template +// void on(const string& key, function callback) { +// if constexpr (sizeof...(T) == 1 && is_same_v>, int>) { +// emitter1.on(key, callback); +// } +// else if constexpr (sizeof...(T) == 1 && is_same_v>, string>) { +// emitter2.on(key, callback); +// } +// } + +// template +// void tick(const string& key, Args&&... args) { +// if constexpr (sizeof...(Args) == 1 && is_same_v>, int>) { +// emitter1.tick(key, forward(args)...); +// } +// else if constexpr (sizeof...(Args) == 1 && is_same_v>, string>) { +// emitter2.tick(key, forward(args)...); +// } +// else { +// static_assert(sizeof...(Args) == 0, "Unsupported number or types of arguments"); +// } +// } +// }; int main () { @@ -101,36 +136,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 +173,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(); @@ -160,25 +195,6 @@ int main () { // cout << "nije isteko " << endl; // } - // 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 ------------------------- // // /** @@ -244,7 +260,7 @@ int main () { // })) << endl; // /** - // * Sleep with delayed sleep implement + // * Sleep with Delayed sleep implement // */ // sleep_to(3000); @@ -350,9 +366,9 @@ int main () { // * initialization of typed events // */ - // trigger ev2int; - // trigger evintString; - // trigger<> evoid; + // Trigger ev2int; + // Trigger evintString; + // Trigger<> evoid; // ev2int.on("sum", [](int a, int b) { // cout << "Sum " << a+b << endl; @@ -405,7 +421,7 @@ int main () { // myOwnClass myclass; - // delayed t( [&] { + // Delayed t( [&] { // myclass.tick("constructed", 1); // }, 200); @@ -419,18 +435,18 @@ int main () { // * // */ - ClassWithTriggers mt; + // ClassWithTriggers mt; - mt.on("int", function([&](int i) { - cout << "Emit int " << i << endl; - })); + // mt.on("int", function([&](int i) { + // cout << "Emit int " << i << endl; + // })); - mt.on("string", function([&](string s) { - cout << "Emit string " << s << endl; - })); + // mt.on("string", function([&](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"); @@ -459,11 +475,151 @@ int main () { // }); - // // ---------------------------------------------------------------------------------------------------- + // ---------------------------------------------------------------------------------------------------- - cout << "Run" << endl; + + // auto i = async_ ( []() -> asyncable { + // cout << "aaaa" << endl; + // co_return 5; + // }); + + // auto i = async_ (retint()); + + // auto i_ = await_(i); + + // cout << i_ << endl; + + + // Periodic a( []() -> asyncable { + // cout << "corutina" << endl; + // // co_await retint(); + // }, 2000); + + + // Periodic b_( []() { + // cout << "funckija" << endl; + // }, 2000); + + + // Trigger ev2int; + // Trigger evintString; + // Trigger<> evoid; + + // ev2int.on("sum", [](int a, int b) -> asyncable { + // cout << "Sum " << a+b << endl; + // }); + + // ev2int.on("sum", [](int a, int b) -> asyncable { + // cout << "Sum done" << endl; + // }); + + // evintString.on("substract", [](int a, string b) -> asyncable { + // cout << "Substract " << a-stoi(b) << endl; + // }); + + // evoid.on("void", []() { + // auto a = await_ (async_ (c2(34))); + // cout << "A " << a << endl; + // }); + + + // auto c1 = []() -> asyncable { + // cout << "Roge " << endl; + // co_return; + + // }; + + // auto a = await_ ( c2(3)); + // cout << a << endl; + + + // await_ ([]() -> asyncable { + // cout << "Hello" << endl; + // co_await c2(4); + // co_return; + // }()); + + // async_ ([]() -> asyncable { + // cout << "1" << endl; + // co_await sleep_co(1); + // co_return; + // }()); + + // async_ ([]() -> asyncable { + // cout << "2" << endl; + // co_await sleep_co(1); + // co_return; + // }()); + + // async_ ([]() -> asyncable { + // cout << "3" << endl; + // co_await sleep_co(1); + // co_return; + // }()); + + // async_ ([]() -> asyncable { + // cout << "4" << endl; + // co_await sleep_co(1); + // co_return; + // }()); + + // async_ ([]() -> asyncable { + // cout << "5" << endl; + // co_await sleep_co(1); + // co_return; + // }()); + + + // await_ ([]() { + // cout << "Hello" << endl; + // }); + + // Periodic p( []() { + // async_ ( + // c2(34) + // ); + // }, 2000); + + // await_( async_ ( [c1 = move(c1)]() -> asyncable { + // cout << "Baba roga" << endl; + // co_await c1(); + // })); + + // string emited2 = "2"; + + // evoid.on("void", [&]() -> asyncable { + // cout << "Void emited " << emited2 << endl; + // }); + + // evoid.tick("void"); + + + + + // vector> futures; + + // for (int i=0; i<20; i++) { + // futures.push_back( + // async_([a = i](){ + // for (int i=0; i<1000; i++) { + // cout << a << " " << i << endl; + // // sleep_to(i); + // } + // }) + // ); + // } + + // for (int i=0; i<20; i++) { + // await_(futures[i]); + // // await_(futures[i]); + // } + + + + + + cout << "-------------end main------------- " << rtime_ms() - start << endl; _asynco_engine.run(); - return 0; }