From 9e773f55c950c803bb9d0d624a5d34e37a569474 Mon Sep 17 00:00:00 2001 From: marcelb Date: Fri, 27 Sep 2024 20:16:23 +0200 Subject: [PATCH] Fix multiple engine init problem and enable anonim init timers --- README.md | 22 +++++++++++++++ lib/asynco.hpp | 47 +------------------------------- lib/engine.hpp | 71 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/timers.hpp | 16 ++++++----- lib/trigger.hpp | 6 ++--- src/engine.cpp | 7 +++++ src/timers.cpp | 36 +++++++++++++++++++++++++ test/compile.sh | 1 + test/test.cpp | 67 ++++++++++++++++++++++++++++++---------------- 9 files changed, 194 insertions(+), 79 deletions(-) create mode 100644 lib/engine.hpp create mode 100644 src/engine.cpp create mode 100644 test/compile.sh diff --git a/README.md b/README.md index da4de63..08991a9 100644 --- a/README.md +++ b/README.md @@ -77,6 +77,28 @@ 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 diff --git a/lib/asynco.hpp b/lib/asynco.hpp index 2455f0f..d57ec0f 100644 --- a/lib/asynco.hpp +++ b/lib/asynco.hpp @@ -1,7 +1,7 @@ #ifndef _ASYNCO_ #define _ASYNCO_ -#include +#include "engine.hpp" #include using namespace std; @@ -9,51 +9,6 @@ using namespace std; namespace marcelb { namespace asynco { -#define HW_CONCURRENCY_MINIMAL 4 - -/** - * Internal anonymous class for initializing the ASIO context and thread pool - * !!! It is anonymous to protect against use in the initialization of other objects of the same type !!! -*/ -class { - public: - boost::asio::io_context io_context; - - void run() { - for (auto& runner : runners) { - runner.join(); - } - } - - private: - - unique_ptr work { [&] () { - return new boost::asio::io_service::work(io_context); - } ()}; - - vector runners { [&] () { - vector _runs; - unsigned int num_of_runners; - #ifdef NUM_OF_RUNNERS - num_of_runners = NUM_OF_RUNNERS; - #else - num_of_runners = thread::hardware_concurrency(); - if (num_of_runners < HW_CONCURRENCY_MINIMAL) { - num_of_runners = HW_CONCURRENCY_MINIMAL; - } - #endif - - for (int i=0; i +#include +using namespace std; + +#include + +namespace marcelb { +namespace asynco { + +#define HW_CONCURRENCY_MINIMAL 4 + +/** + * Internal anonymous class for initializing the ASIO context and thread pool + * !!! It is anonymous to protect against use in the initialization of other objects of the same type !!! +*/ +class Engine { + public: + boost::asio::io_context io_context; + + void run() { + for (auto& runner : runners) { + runner.join(); + } + } + + private: + + unique_ptr work { [&] () { + return new boost::asio::io_service::work(io_context); + } ()}; + + vector runners { [&] () { + vector _runs; + unsigned int num_of_runners; + #ifdef NUM_OF_RUNNERS + num_of_runners = NUM_OF_RUNNERS; + #else + num_of_runners = thread::hardware_concurrency(); + if (num_of_runners < HW_CONCURRENCY_MINIMAL) { + num_of_runners = HW_CONCURRENCY_MINIMAL; + } + #endif + + for (int i=0; i +using namespace std; #include "asynco.hpp" -#include - -using namespace std; -using namespace marcelb; -using namespace asynco; namespace marcelb { namespace asynco { @@ -153,6 +151,10 @@ class 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 f4abacc..30c43ca 100644 --- a/lib/trigger.hpp +++ b/lib/trigger.hpp @@ -1,5 +1,5 @@ -#ifndef _TRIGGER_ -#define _TRIGGER_ +#ifndef _ASYNCO_TRIGGER_ +#define _ASYNCO_TRIGGER_ #include #include @@ -8,7 +8,7 @@ using namespace std; -#include "asynco.hpp" +#include "engine.hpp" namespace marcelb { namespace asynco { namespace triggers { diff --git a/src/engine.cpp b/src/engine.cpp new file mode 100644 index 0000000..2dc7b75 --- /dev/null +++ b/src/engine.cpp @@ -0,0 +1,7 @@ +#include "../lib/engine.hpp" + +namespace marcelb::asynco { + +Engine _asynco_engine; + +}; diff --git a/src/timers.cpp b/src/timers.cpp index e9b2c49..747f785 100644 --- a/src/timers.cpp +++ b/src/timers.cpp @@ -106,4 +106,40 @@ 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/compile.sh b/test/compile.sh new file mode 100644 index 0000000..9cda8c6 --- /dev/null +++ b/test/compile.sh @@ -0,0 +1 @@ +g++ test.cpp ../src/* -o test \ No newline at end of file diff --git a/test/test.cpp b/test/test.cpp index f171108..779dd37 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -69,9 +69,9 @@ 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; @@ -129,11 +129,30 @@ int main () { // cout << "nije isteko " << endl; // } - // // // ------------------------ MAKE FUNCTIONS ASYNCHRONOUS ------------------------- + // auto d = Delayed( [](){ + // cout << "Delayed" << endl; + // }, 2000); - // /** - // * Run an function asyncronic - // */ + // 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 ------------------------- + + // // /** + // // * Run an function asyncronic + // // */ // async_ ( []() { // sleep_for(2s); // only for simulate log duration function @@ -155,13 +174,13 @@ int main () { // ); - // async(launch::async, [] () { - // cout << "Another thread in async style!" << endl; - // }); + // // async(launch::async, [] () { + // // cout << "Another thread in async style!" << endl; + // // }); - // /** - // * Call class method - // */ + // // /** + // // * Call class method + // // */ // clm classes; // async_ ( [&classes] () { @@ -170,17 +189,17 @@ int main () { // sleep(5); - // /** - // * await_ after runned as async - // */ + // // /** + // // * await_ after runned as async + // // */ - // auto a = async_ ( []() { + // auto aa = async_ ( []() { // sleep_for(2s); // only for simulate log duration function // cout << "async_ 2" << endl; // return 5; // }); - // cout << await_(a) << endl; + // cout << await_(aa) << endl; // cout << "print after async_ 2" << endl; // /** @@ -271,17 +290,19 @@ int main () { // ); // } - // auto await_all = [&] () { + // auto await_all2 = [&] () { // for (int i=0; i ev2int; // trigger evintString;