From 105c15b06bd77e65842a2201f54b28e761158b6a Mon Sep 17 00:00:00 2001 From: marcelb Date: Mon, 25 Mar 2024 20:24:41 +0100 Subject: [PATCH] Merge and namespace edit --- .vscode/settings.json | 43 ++++++- README.md | 49 +++++--- lib/asynco.hpp | 4 +- lib/event.hpp | 4 + lib/filesystem.hpp | 23 ++-- lib/rotor.hpp | 6 + lib/runner.hpp | 2 + test/test.cpp | 260 +++++++++++++++++++----------------------- 8 files changed, 223 insertions(+), 168 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7fefd1d..aaed338 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -28,6 +28,47 @@ "algorithm": "cpp", "string": "cpp", "string_view": "cpp", - "fstream": "cpp" + "fstream": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwctype": "cpp", + "any": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "codecvt": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "cstdint": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "system_error": "cpp", + "iomanip": "cpp", + "istream": "cpp", + "limits": "cpp", + "numbers": "cpp", + "semaphore": "cpp", + "sstream": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "cinttypes": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "variant": "cpp" } } \ No newline at end of file diff --git a/README.md b/README.md index 6afdc2b..5b0d11d 100644 --- a/README.md +++ b/README.md @@ -20,15 +20,17 @@ A C++ library for event-driven asynchronous multi-threaded programming. Just download the latest release and unzip it into your project. ```c++ -#define NUM_OF_RUNNERS 2 // To change the number of threads used by asynco +#define NUM_OF_RUNNERS 8 // To change the number of threads used by atask, without this it runs according to the number of cores -#include "asynco/lib/asynco.hpp" // asynco(), wait() -#include "asynco/lib/event.hpp" // event -#include "asynco/lib/rotor.hpp" // interval, timeout -#include "asynco/lib/runner.hpp" // for own loop -#include "asynco/lib/filesystem.hpp"// for async read and write files +#include "asynco/lib/asynco.hpp" // atask(), wait() +#include "asynco/lib/event.hpp" // event +#include "asynco/lib/rotor.hpp" // interval, timeout +#include "asynco/lib/runner.hpp" // for own loop +#include "asynco/lib/filesystem.hpp" // for async read and write files using namespace marcelb; +using namespace asynco; +using namespace events; ``` @@ -60,9 +62,9 @@ Make functions asynchronous * Run an lambda function asynchronously */ -asynco( []() { +atask( []() { sleep_for(2s); // only for simulating long duration function - cout << "asynco" << endl; + cout << "atask" << endl; return 5; }); @@ -75,7 +77,7 @@ void notLambdaFunction() { cout << "Call to not lambda function" << endl; } -asynco (notLambdaFunction); +atask (notLambdaFunction); /** * Run class method @@ -89,7 +91,7 @@ class clm { }; clm classes; -asynco( [&classes] () { +atask( [&classes] () { classes.classMethode(); }); @@ -99,9 +101,9 @@ asynco( [&classes] () { * Wait after runned as async */ -auto a = asynco( []() { +auto a = atask( []() { sleep_for(2s); // only for simulating long duration function - cout << "asynco" << endl; + cout << "atask" << endl; return 5; }); @@ -111,7 +113,7 @@ cout << wait(a) << endl; * Wait async function call and use i cout */ -cout << wait(asynco( [] () { +cout << wait(atask( [] () { sleep_for(chrono::seconds(1)); // only for simulating long duration function cout << "wait end" << endl; return 4; @@ -233,7 +235,7 @@ Asynchronous file IO ```c++ string data_; -asynco_read("test.txt", [&data_] (string data, exception* error) { +fs::read("test.txt", [&data_] (string data, exception* error) { if (error) { cout << "Error " << error->what() << endl; } else { @@ -243,13 +245,30 @@ asynco_read("test.txt", [&data_] (string data, exception* error) { } }); -asynco_write("test1.txt", "Hello night", [] (exception* error) { +fs::write("test1.txt", "Hello world", [] (exception* error) { if (error) { cout << "Error " << error->what() << endl; } else { cout << "Write successfuly" << endl; } }); + +auto future_data = fs::read("test.txt"); + +try { + string data = wait(future_data); +} catch (exception& err) { + cout << err.what() << endl; +} + +auto future_status = fs::write("test.txt", "Hello world"); + +try { + wait(future_status); +} catch (exception& err) { + cout << err.what() << endl; +} + ``` ## License diff --git a/lib/asynco.hpp b/lib/asynco.hpp index 9bdd4e7..afd99c6 100644 --- a/lib/asynco.hpp +++ b/lib/asynco.hpp @@ -6,12 +6,13 @@ using namespace std; namespace marcelb { +namespace asynco { /** * Run the function asynchronously */ template -auto asynco(F&& f, Args&&... args) -> future::type> { +auto atask(F&& f, Args&&... args) -> future::type> { using return_type = typename result_of::type; future res = _asyncon.put_task(bind(forward(f), forward(args)...)); @@ -34,6 +35,7 @@ T wait(future&& r) { return move(r).get(); } +} } #endif \ No newline at end of file diff --git a/lib/event.hpp b/lib/event.hpp index 3d24174..cb70873 100644 --- a/lib/event.hpp +++ b/lib/event.hpp @@ -11,6 +11,8 @@ using namespace std; namespace marcelb { +namespace asynco { +namespace events { /** * Event class, for event-driven programming. @@ -57,6 +59,8 @@ class event { }; +} +} } #endif \ No newline at end of file diff --git a/lib/filesystem.hpp b/lib/filesystem.hpp index 6801d79..60eabe5 100644 --- a/lib/filesystem.hpp +++ b/lib/filesystem.hpp @@ -8,15 +8,19 @@ #include using namespace std; +using namespace marcelb; +using namespace asynco; namespace marcelb { +namespace asynco { +namespace fs { /** * Asynchronous file reading with callback after read complete */ template -void asynco_read(string path, Callback&& callback) { - asynco( [&path, callback] () { +void read(string path, Callback&& callback) { + async( [&path, callback] () { string content; try { string line; @@ -44,8 +48,8 @@ void asynco_read(string path, Callback&& callback) { /** * Asynchronous file reading */ -future asynco_read(string path) { - return asynco( [&path] () { +future read(string path) { + return async( [&path] () { string content; string line; ifstream file (path); @@ -68,8 +72,8 @@ future asynco_read(string path) { * Asynchronous file writing with callback after write complete */ template -void asynco_write(string path, string content, Callback&& callback) { - asynco( [&path, &content, callback] () { +void write(string path, string content, Callback&& callback) { + async( [&path, &content, callback] () { try { ofstream file (path); if (file.is_open()) { @@ -91,8 +95,8 @@ void asynco_write(string path, string content, Callback&& callback) { /** * Asynchronous file writing with callback after write complete */ -future asynco_write(string path, string content) { - return asynco( [&path, &content] () { +future write(string path, string content) { + return async( [&path, &content] () { ofstream file (path); if (file.is_open()) { file << content; @@ -105,7 +109,8 @@ future asynco_write(string path, string content) { }); } - +} +} } #endif \ No newline at end of file diff --git a/lib/rotor.hpp b/lib/rotor.hpp index b0cc44c..4387038 100644 --- a/lib/rotor.hpp +++ b/lib/rotor.hpp @@ -9,8 +9,10 @@ using namespace std; using namespace marcelb; +using namespace asynco; namespace marcelb { +namespace asynco { /** * Get the time in ms from the epoch @@ -28,6 +30,8 @@ int64_t rtime_us() { .count(); } +namespace { + /** * Intern class for timer async loop */ @@ -177,6 +181,7 @@ class rotor { * It is intended that there is only one global declaration */ static rotor _rotor; +} /** * Core class for pure async timer functions @@ -228,6 +233,7 @@ class timeout : public _timer_intern { }; +} } #endif diff --git a/lib/runner.hpp b/lib/runner.hpp index 678723c..387bd65 100644 --- a/lib/runner.hpp +++ b/lib/runner.hpp @@ -12,6 +12,7 @@ using namespace std; namespace marcelb { +namespace asynco { #define HW_CONCURRENCY_MINIMAL 4 @@ -129,6 +130,7 @@ class runner { */ static runner _asyncon; +} } #endif \ No newline at end of file diff --git a/test/test.cpp b/test/test.cpp index 4ef68e8..0c9984e 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -1,40 +1,42 @@ #define NUM_OF_RUNNERS 2 -// #include "../lib/asynco.hpp" -// #include "../lib/event.hpp" -// #include "../lib/rotor.hpp" -#include "../lib/filesystem.hpp" +#include "../lib/asynco.hpp" +#include "../lib/event.hpp" +#include "../lib/rotor.hpp" +// #include "../lib/filesystem.hpp" #include #include using namespace std; -using namespace marcelb; +using namespace marcelb::asynco; +using namespace events; +// using namespace asynco; using namespace this_thread; -// void sleep_to (int _time) { -// promise _promise; -// timeout t( [&]() { -// _promise.set_value(); -// }, _time); - -// return _promise.get_future().get(); -// } - -// void promise_reject (int _time) { -// promise _promise; -// timeout 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; + timeout t( [&]() { + _promise.set_value(); + }, _time); + + return _promise.get_future().get(); +} + +void promise_reject (int _time) { + promise _promise; + timeout 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 notLambdaFunction() { cout << "Call to not lambda function" << endl; @@ -49,42 +51,42 @@ class clm { // ------------------ EXTEND OWN CLASS WITH EVENTS ------------------- -// class myOwnClass : public event { -// public: -// myOwnClass() : event() {}; -// }; +class myOwnClass : public event { + public: + myOwnClass() : event() {}; +}; int main () { - // auto start = rtime_ms(); + auto start = rtime_ms(); - // --------------- TIME ASYNCHRONOUS FUNCTIONS -------------- + // // --------------- TIME ASYNCHRONOUS FUNCTIONS -------------- - /** - * Init interval and timeout; clear interval and timeout - */ + // /** + // * Init interval and timeout; clear interval and timeout + // */ - interval( [&] () { - cout << "interval 1: " << rtime_ms() - start << endl; - }, 50); + // interval( [&] () { + // cout << "interval 1: " << rtime_ms() - start << endl; + // }, 50); - interval( [&] () { - cout << "interval 1: " << rtime_ms() - start << endl; - }, 100); + // interval( [&] () { + // cout << "interval 1: " << rtime_ms() - start << endl; + // }, 100); - interval( [&] () { - cout << "interval 2: " << rtime_ms() - start << endl; - }, 200); + // interval( [&] () { + // cout << "interval 2: " << rtime_ms() - start << endl; + // }, 200); - interval( [&] () { - cout << "interval 3: " << rtime_ms() - start << endl; - }, 300); + // interval( [&] () { + // cout << "interval 3: " << rtime_ms() - start << endl; + // }, 300); - interval( [&] () { - cout << "interval 4: " << rtime_ms() - start << endl; - }, 400); + // interval( [&] () { + // cout << "interval 4: " << rtime_ms() - start << endl; + // }, 400); // interval inter1 ([&]() { // cout << "interval prvi " << rtime_ms() - start << endl; @@ -127,13 +129,13 @@ int main () { // // ------------------------ MAKE FUNCTIONS ASYNCHRONOUS ------------------------- - // /** - // * Run an function asyncronic - // */ + /** + * Run an function asyncronic + */ - // asynco( []() { + // atask( []() { // sleep_for(2s); // only for simulate log duration function - // cout << "asynco 1" << endl; + // cout << "atask 1" << endl; // return 5; // }); @@ -141,11 +143,11 @@ int main () { // * Call not lambda function // */ - // asynco (notLambdaFunction); + // atask (notLambdaFunction); // wait ( - // asynco ( + // atask ( // notLambdaFunction // ) // ); @@ -155,7 +157,7 @@ int main () { // */ // clm classes; - // asynco( [&classes] () { + // atask( [&classes] () { // classes.classMethode(); // }); @@ -165,20 +167,20 @@ int main () { // * Wait after runned as async // */ - // auto a = asynco( []() { + // auto a = atask( []() { // sleep_for(2s); // only for simulate log duration function - // cout << "asynco 2" << endl; + // cout << "atask 2" << endl; // return 5; // }); // cout << wait(a) << endl; - // cout << "print after asynco 2" << endl; + // cout << "print after atask 2" << endl; // /** // * Wait async function call and use i cout // */ - // cout << wait(asynco( [] () { + // cout << wait(atask( [] () { // sleep_for(chrono::seconds(1)); // only for simulate log duration function // cout << "wait end" << endl; // return 4; @@ -191,9 +193,9 @@ int main () { // sleep_to(3000); // cout << "sleep_to " << rtime_ms() - start << endl; - /** - * Catch promise reject - */ + // /** + // * Catch promise reject + // */ // try { // promise_reject(3000); @@ -209,110 +211,84 @@ int main () { // */ - // asynco( [] { + // atask( [] { // cout << "idemo ..." << endl; - // asynco( [] { + // atask( [] { // cout << "ugdnježdena async funkcija " << endl; // }); // }); - // // --------------- EVENTS ------------------- + // --------------- EVENTS ------------------- - // /** - // * initialization of typed events - // */ + /** + * initialization of typed events + */ - // event ev2int; - // event evintString; - // event<> evoid; + event ev2int; + event evintString; + event<> evoid; - // ev2int.on("sum", [](int a, int b) { - // cout << "Sum " << a+b << endl; - // }); + ev2int.on("sum", [](int a, int b) { + cout << "Sum " << a+b << endl; + }); - // ev2int.on("sum", [](int a, int b) { - // cout << "Sum done" << endl; - // }); + ev2int.on("sum", [](int a, int b) { + cout << "Sum done" << endl; + }); - // evintString.on("substract", [](int a, string b) { - // cout << "Substract " << a-stoi(b) << endl; - // }); + evintString.on("substract", [](int a, string b) { + cout << "Substract " << a-stoi(b) << endl; + }); - // evoid.on("void", []() { - // cout << "Void emited" << endl; - // }); + evoid.on("void", []() { + cout << "Void emited" << endl; + }); - // string emited2 = "2"; + string emited2 = "2"; - // evoid.on("void", [&]() { - // cout << "Void emited " << emited2 << endl; - // }); + evoid.on("void", [&]() { + cout << "Void emited " << emited2 << endl; + }); - // evoid.emit("void"); - // sleep(1); + evoid.emit("void"); + sleep(1); - // /** - // * Emit - // */ + /** + * Emit + */ - // ev2int.emit("sum", 5, 8); + ev2int.emit("sum", 5, 8); - // sleep(1); - // evintString.emit("substract", 3, to_string(2)); - - // sleep(1); - // evoid.off("void"); - // evoid.emit("void"); - - // /** - // * Own class - // */ - - // myOwnClass myclass; + sleep(1); + evintString.emit("substract", 3, to_string(2)); - // timeout t( [&] { - // myclass.emit("constructed", 1); - // }, 200); + sleep(1); + evoid.off("void"); + evoid.emit("void"); - // myclass.on("constructed", [] (int i) { - // cout << "Constructed " << i << endl; - // }); + /** + * Own class + */ - string data_; + myOwnClass myclass; - // asynco_read("test.txt", [&data_] (string data, exception* error) { - // if (error) { - // cout << "Error " << error->what() << endl; - // } else { - // cout << "Data " << endl << data << endl; - // data_ = data; - // cout << "Data_" << data_ << endl; - // } - // }); + timeout t( [&] { + myclass.emit("constructed", 1); + }, 200); - // auto data = asynco_read("test4.txt"); + myclass.on("constructed", [] (int i) { + cout << "Constructed " << i << endl; + }); - // try { - // data_ = wait(data); - // cout << "data" << data_ << endl; - // } catch (exception& err) { - // cout << err.what() << endl; - // } - // asynco_write("test1.txt", "Hello night", [] (exception* error) { - // if (error) { - // cout << "Error " << error->what() << endl; - // } else { - // cout << "Write successfuly" << endl; - // } - // }); - auto status = asynco_write("test1.txt", "Hello night"); + // auto status = fs::read("test1.txt"); // try { - // wait(status); + // auto data = wait(status); + // cout << data; // } catch (exception& err) { // cout << err.what() << endl; // }