Write examples and tests, refaktor, tested
This commit is contained in:
parent
e76623bef0
commit
748fd0a586
@ -25,6 +25,9 @@ target_link_libraries(asynco Boost::system)
|
||||
# Dodaj testove
|
||||
add_subdirectory(test)
|
||||
|
||||
add_compile_options(-w)
|
||||
|
||||
|
||||
|
||||
# Instaliraj biblioteku
|
||||
# install(TARGETS asynco DESTINATION lib)
|
||||
|
225
README.md
225
README.md
@ -13,14 +13,12 @@ The asynchronous filesystem was included solely to demonstrate how users can wra
|
||||
|
||||
- Object oriented
|
||||
- Small and easy to integrate
|
||||
- Header only
|
||||
- Asynchronous programming
|
||||
- Multithread
|
||||
- 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
|
||||
@ -28,37 +26,64 @@ The asynchronous filesystem was included solely to demonstrate how users can wra
|
||||
Just download the latest release and unzip it into your project.
|
||||
|
||||
```c++
|
||||
#define NUM_OF_RUNNERS 8 // To change the number of threads used by asynco, without this it runs according to the number of cores
|
||||
// for default global runtime
|
||||
|
||||
#include "asynco/lib/asynco_default.hpp"
|
||||
|
||||
#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/filesystem.hpp" // for async read and write files
|
||||
#include "asynco/lib/define.hpp" // async_, await_, asyncable_ defines
|
||||
|
||||
using namespace marcelb;
|
||||
using namespace asynco;
|
||||
|
||||
// At the end of the main function, always set
|
||||
Asynco_Default_Runtime.run();
|
||||
return 0;
|
||||
int main() {
|
||||
asynco_default_run();
|
||||
|
||||
// code
|
||||
|
||||
asynco_default_join()
|
||||
return 0;
|
||||
}
|
||||
|
||||
// own instace of runtime
|
||||
|
||||
#include "asynco/lib/asynco.hpp"
|
||||
|
||||
using namespace marcelb;
|
||||
using namespace asynco;
|
||||
|
||||
int main() {
|
||||
Asynco asynco;
|
||||
asynco.run(2);
|
||||
|
||||
// code
|
||||
|
||||
asynco.join();
|
||||
return 0;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## 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.
|
||||
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, and coroutines.
|
||||
|
||||
### Timers
|
||||
|
||||
We have two timer classes, Periodic (which runs a callback function periodically), and Delayed (delayed runs a callback function only once).
|
||||
We have one timer classes, int two mode Periodic (which runs a callback function periodically), and Delayed (delayed runs a callback function only once).
|
||||
|
||||
```c++
|
||||
// start periodic
|
||||
Periodic inter1 ([]() {
|
||||
Timer inter1 = periodic ([]() {
|
||||
cout << "Interval 1" << endl;
|
||||
}, 1000);
|
||||
|
||||
// or usint own instance runtime
|
||||
/**
|
||||
* Asynco asynco;
|
||||
* asynco.run(2);
|
||||
* Timer inter1 = asynco.periodic ([]() {
|
||||
* cout << "Interval 1" << endl;
|
||||
* }, 1000);
|
||||
*/
|
||||
// stop periodic
|
||||
inter1.stop();
|
||||
|
||||
@ -69,7 +94,7 @@ int t = inter1.ticks();
|
||||
bool stoped = inter1.stoped();
|
||||
|
||||
// start delayed
|
||||
Delayed time1 ( [] () {
|
||||
Timer time1 = delayed( [] () {
|
||||
cout << "Timeout 1 " << endl;
|
||||
}, 10000);
|
||||
|
||||
@ -93,7 +118,7 @@ Running functions at runtime, asynchronous execution, uses the `async_` call and
|
||||
*/
|
||||
|
||||
async_ ( []() {
|
||||
sleep_for(2s); // only for simulating long duration function
|
||||
sleep(2); // only for simulating long duration function
|
||||
cout << "nonsync " << endl;
|
||||
return 5;
|
||||
});
|
||||
@ -126,12 +151,12 @@ async_ ( [&classes] () {
|
||||
});
|
||||
```
|
||||
|
||||
To wait for the result (blocking the flow) use `await_` (basically nothing more than a `.get()` call on a future object)
|
||||
To wait for the result (blocking the flow) use `await_` (This does not block the event loop in principle. If the result is not ready for a short time, it starts another job in place while it waits.)
|
||||
|
||||
```c++
|
||||
|
||||
auto a = async_ ( []() {
|
||||
sleep_for(2s); // only for simulating long duration function
|
||||
sleep(2); // only for simulating long duration function
|
||||
cout << "nonsync " << endl;
|
||||
return 5;
|
||||
});
|
||||
@ -143,7 +168,7 @@ cout << await_(a) << endl;
|
||||
*/
|
||||
|
||||
cout << await_(async_ ( [] () {
|
||||
sleep_for(chrono::seconds(1)); // only for simulating long duration function
|
||||
sleep(1); // only for simulating long duration function
|
||||
cout << "await_ end" << endl;
|
||||
return 4;
|
||||
})) << endl;
|
||||
@ -159,104 +184,7 @@ await_ ([]() {
|
||||
});
|
||||
|
||||
```
|
||||
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;
|
||||
return 3;
|
||||
});
|
||||
|
||||
auto b = async_ ( []() {
|
||||
cout << "B" << endl;
|
||||
throw runtime_error("Test exception");
|
||||
return;
|
||||
});
|
||||
|
||||
auto c = async_ ( []() {
|
||||
cout << "C" << endl;
|
||||
return "Hello";
|
||||
});
|
||||
|
||||
int a_;
|
||||
string c_;
|
||||
|
||||
auto await_all = [&] () {
|
||||
a_ = await_(a);
|
||||
await_(b);
|
||||
c_ = await_(c);
|
||||
};
|
||||
|
||||
try {
|
||||
await_all();
|
||||
cout << "a_ " << a_ << " c_ " << c_ << endl;
|
||||
} catch (const exception& exc) {
|
||||
cout << exc.what() << endl;
|
||||
}
|
||||
|
||||
// // same type
|
||||
|
||||
vector<future<void>> fut_vec;
|
||||
for (int i=0; i<5; i++) {
|
||||
fut_vec.push_back(
|
||||
async_ ( [i]() {
|
||||
cout << "Async_ " << i << endl;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
auto await_all = [&] () {
|
||||
for (int i=0; i<fut_vec.size(); i++) {
|
||||
await_ (fut_vec[i]);
|
||||
}
|
||||
};
|
||||
|
||||
```
|
||||
Just an example:
|
||||
|
||||
```c++
|
||||
|
||||
/**
|
||||
* Sleep with delayed sleep implement
|
||||
**/
|
||||
|
||||
void sleep_to (int _time) {
|
||||
promise<void> _promise;
|
||||
Delayed t( [&]() {
|
||||
_promise.set_value();
|
||||
}, _time);
|
||||
|
||||
return _promise.get_future().get();
|
||||
}
|
||||
|
||||
sleep_to(3000);
|
||||
|
||||
/**
|
||||
* Catch promise reject
|
||||
*/
|
||||
|
||||
void promise_reject (int _time) {
|
||||
promise<void> _promise;
|
||||
Delayed t( [&]() {
|
||||
try {
|
||||
// simulate except
|
||||
throw runtime_error("Error simulation");
|
||||
_promise.set_value();
|
||||
} catch (...) {
|
||||
_promise.set_exception(current_exception());
|
||||
}
|
||||
}, _time);
|
||||
|
||||
return _promise.get_future().get();
|
||||
}
|
||||
|
||||
try {
|
||||
promise_reject(3000);
|
||||
} catch (runtime_error err) {
|
||||
cout<< err.what() << endl;
|
||||
}
|
||||
```
|
||||
Here too you can use your own runtime instance, only the methods are `.async()` and `.await()`
|
||||
|
||||
### Triggers
|
||||
|
||||
@ -267,9 +195,9 @@ The library implements Triggers, which are basically typed Events.
|
||||
* initialization of typed events
|
||||
*/
|
||||
|
||||
Trigger<int, int> ev2int;
|
||||
Trigger<int, string> evintString;
|
||||
Trigger<> evoid;
|
||||
Trigger<int, int> ev2int = trigger<int, int>();
|
||||
Trigger<int, string> evintString = trigger<int, string>();
|
||||
Trigger<> evoid = trigger<>();
|
||||
|
||||
ev2int.on("sum", [](int a, int b) {
|
||||
cout << "Sum " << a+b << endl;
|
||||
@ -316,7 +244,7 @@ Extend own class whit events
|
||||
```c++
|
||||
class myOwnClass : public Trigger<int> {
|
||||
public:
|
||||
myOwnClass() : Trigger() {};
|
||||
myOwnClass() : Trigger(asynco_default_runtime()) {};
|
||||
};
|
||||
|
||||
myOwnClass myclass;
|
||||
@ -340,6 +268,8 @@ class ClassWithTriggers {
|
||||
Trigger<string> emitter2;
|
||||
|
||||
public:
|
||||
ClassWithTriggers(): emitter1(asynco_default_runtime()), emitter2(asynco_default_runtime()) {}
|
||||
|
||||
template<typename... T>
|
||||
void on(const string& key, function<void(T...)> callback) {
|
||||
if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, int>) {
|
||||
@ -379,48 +309,6 @@ mt.tick("string", string("Hello world"));
|
||||
|
||||
```
|
||||
|
||||
Another example:
|
||||
Asynchronous file IO
|
||||
|
||||
```c++
|
||||
string data_;
|
||||
|
||||
fs::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;
|
||||
}
|
||||
});
|
||||
|
||||
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 = await_(future_data);
|
||||
} catch (exception& err) {
|
||||
cout << err.what() << endl;
|
||||
}
|
||||
|
||||
auto future_status = fs::write("test.txt", "Hello world");
|
||||
|
||||
try {
|
||||
await_(future_status);
|
||||
} catch (exception& err) {
|
||||
cout << err.what() << endl;
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Coroutine
|
||||
|
||||
If `define.hpp` is included, you can initialize coroutines using `asyncable<T>`; if not, just use `boost::asio::awaitable<T>`.
|
||||
@ -473,17 +361,8 @@ await_ ([]() -> asyncable<void> {
|
||||
|
||||
```
|
||||
|
||||
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_`.
|
||||
|
||||
Here too you can use your own runtime instance, only the methods are `.async()` and `.await()`
|
||||
|
||||
## License
|
||||
|
||||
|
@ -11,16 +11,15 @@
|
||||
using namespace std;
|
||||
|
||||
#include <boost/asio.hpp>
|
||||
using namespace boost::asio;
|
||||
|
||||
#include "timers.hpp"
|
||||
#include "trigger.hpp"
|
||||
|
||||
#if __cplusplus >= 202002L
|
||||
#include <boost/asio/awaitable.hpp>
|
||||
#include <boost/asio/co_spawn.hpp>
|
||||
#include <boost/asio/use_awaitable.hpp>
|
||||
#endif
|
||||
using namespace boost::asio;
|
||||
|
||||
#include "timers.hpp"
|
||||
#include "trigger.hpp"
|
||||
|
||||
namespace marcelb {
|
||||
namespace asynco {
|
||||
@ -37,10 +36,10 @@ class Asynco {
|
||||
public:
|
||||
io_context io_ctx;
|
||||
|
||||
// Asynco(uint8_t threads = thread::hardware_concurrency());
|
||||
|
||||
void run(uint8_t threads = thread::hardware_concurrency());
|
||||
|
||||
void run_on_this();
|
||||
|
||||
void join();
|
||||
|
||||
/**
|
||||
@ -48,8 +47,6 @@ public:
|
||||
*/
|
||||
template<class F, class... Args>
|
||||
auto async(F&& f, Args&&... args) -> future<invoke_result_t<F, Args...>> {
|
||||
cout << "async" << endl;
|
||||
|
||||
using return_type = invoke_result_t<F, Args...>;
|
||||
future<return_type> res = io_ctx.post(boost::asio::use_future(bind(forward<F>(f), forward<Args>(args)...)));
|
||||
return res;
|
||||
@ -157,7 +154,7 @@ public:
|
||||
|
||||
template<typename... T>
|
||||
Trigger<T...> trigger() {
|
||||
return Trigger<T...>(this);
|
||||
return Trigger<T...>(*this);
|
||||
}
|
||||
|
||||
|
||||
|
@ -8,15 +8,12 @@ namespace asynco {
|
||||
|
||||
|
||||
extern Asynco Asynco_Default_Runtime;
|
||||
// Asynco& Asynco_Default_Runtime();
|
||||
|
||||
/**
|
||||
* Run the function asynchronously
|
||||
*/
|
||||
template<class F, class... Args>
|
||||
auto async_(F&& f, Args&&... args) -> future<invoke_result_t<F, Args...>> {
|
||||
cout << "async_default" << endl;
|
||||
|
||||
return Asynco_Default_Runtime.async(bind(forward<F>(f), forward<Args>(args)...));
|
||||
}
|
||||
|
||||
@ -104,6 +101,18 @@ Trigger<T...> trigger() {
|
||||
#define asyncable boost::asio::awaitable
|
||||
#endif
|
||||
|
||||
Asynco& asynco_default_runtime();
|
||||
|
||||
void asynco_default_run();
|
||||
|
||||
void asynco_default_run_on_this();
|
||||
|
||||
void asynco_default_join();
|
||||
|
||||
io_context& asynco_default_io_context();
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,10 +25,9 @@ class Trigger {
|
||||
mutex m_eve;
|
||||
unordered_map<string, vector<function<void(T...)>>> triggers;
|
||||
|
||||
Trigger(Asynco& _engine)
|
||||
: engine(_engine) {}
|
||||
|
||||
public:
|
||||
Trigger(Asynco& _engine)
|
||||
: engine(_engine) {}
|
||||
|
||||
/**
|
||||
* Defines event by key, and callback function
|
||||
|
@ -5,25 +5,25 @@ namespace marcelb::asynco {
|
||||
|
||||
void Asynco::init_loops_in_threads(uint8_t threads) {
|
||||
for (int i=0; i<threads; i++) {
|
||||
cout << "loops init " << endl;
|
||||
|
||||
_runners.push_back(thread ( [this] () {
|
||||
io_ctx.run();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
// Asynco::Asynco(uint8_t threads){//:
|
||||
// // _work(io_service::work(io_ctx)) {
|
||||
// run(threads);
|
||||
// }
|
||||
|
||||
void Asynco::run(uint8_t threads) {
|
||||
_work = make_unique<io_service::work>(io_ctx);
|
||||
cout << "Asynco" << endl;
|
||||
init_loops_in_threads(threads);
|
||||
}
|
||||
|
||||
void Asynco::run_on_this() {
|
||||
if (!_work) {
|
||||
cout << "POKRENE SE KREIRANJE WORK PTR";
|
||||
_work = make_unique<io_service::work>(io_ctx);
|
||||
}
|
||||
io_ctx.run();
|
||||
}
|
||||
|
||||
void Asynco::join() {
|
||||
for (auto& runner : _runners) {
|
||||
runner.join();
|
||||
|
@ -5,11 +5,6 @@ namespace marcelb::asynco {
|
||||
|
||||
Asynco Asynco_Default_Runtime;
|
||||
|
||||
// Asynco& Asynco_Default_Runtime() {
|
||||
// static Asynco _default; // ili koliko već treba
|
||||
// return _default;
|
||||
// }
|
||||
|
||||
Timer delayed(function<void()> callback, uint64_t time) {
|
||||
return Timer(Asynco_Default_Runtime.io_ctx, callback, time, TimerType::Delayed);
|
||||
}
|
||||
@ -18,4 +13,24 @@ Timer periodic(function<void()> callback, uint64_t time) {
|
||||
return Timer(Asynco_Default_Runtime.io_ctx, callback, time, TimerType::Periodic);
|
||||
}
|
||||
|
||||
Asynco& asynco_default_runtime() {
|
||||
return Asynco_Default_Runtime;
|
||||
}
|
||||
|
||||
void asynco_default_run() {
|
||||
Asynco_Default_Runtime.run();
|
||||
}
|
||||
|
||||
void asynco_default_run_on_this() {
|
||||
Asynco_Default_Runtime.run_on_this();
|
||||
}
|
||||
|
||||
void asynco_default_join() {
|
||||
Asynco_Default_Runtime.join();
|
||||
}
|
||||
|
||||
io_context& asynco_default_io_context() {
|
||||
return Asynco_Default_Runtime.io_ctx;
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -34,7 +34,6 @@ Timer::Timer (io_context& _io_ctx, function<void()> _callback, uint64_t _time, T
|
||||
type(_type),
|
||||
callback(_callback),
|
||||
time(_time) {
|
||||
cout << "Timer" << endl;
|
||||
init();
|
||||
}
|
||||
|
||||
|
@ -1,14 +1,29 @@
|
||||
# add_executable(asynco_test main.cpp)
|
||||
|
||||
# # Linkaj test sa Asynco bibliotekom
|
||||
# target_link_libraries(asynco_test asynco Boost::system)
|
||||
|
||||
add_executable(asynco_default main_default.cpp)
|
||||
|
||||
# Linkaj test sa Asynco bibliotekom
|
||||
target_link_libraries(asynco_default asynco Boost::system)
|
||||
|
||||
add_executable(asynco_asynco main_asynco.cpp)
|
||||
add_executable(asynco_init main_init.cpp)
|
||||
target_link_libraries(asynco_init asynco Boost::system)
|
||||
|
||||
# Linkaj test sa Asynco bibliotekom
|
||||
target_link_libraries(asynco_asynco asynco Boost::system)
|
||||
add_executable(asynco_async_default main_async_default.cpp)
|
||||
target_link_libraries(asynco_async_default asynco Boost::system)
|
||||
|
||||
add_executable(asynco_async main_async.cpp)
|
||||
target_link_libraries(asynco_async asynco Boost::system)
|
||||
|
||||
add_executable(asynco_timers_default main_timers_default.cpp)
|
||||
target_link_libraries(asynco_timers_default asynco Boost::system)
|
||||
|
||||
add_executable(asynco_timers main_timers.cpp)
|
||||
target_link_libraries(asynco_timers asynco Boost::system)
|
||||
|
||||
add_executable(asynco_trigger_default main_trigger_default.cpp)
|
||||
target_link_libraries(asynco_trigger_default asynco Boost::system)
|
||||
|
||||
add_executable(asynco_trigger main_trigger.cpp)
|
||||
target_link_libraries(asynco_trigger asynco Boost::system)
|
||||
|
||||
add_executable(asynco_coroutine_default main_coroutine_default.cpp)
|
||||
target_link_libraries(asynco_coroutine_default asynco Boost::system)
|
||||
|
||||
add_executable(asynco_coroutine main_coroutine.cpp)
|
||||
target_link_libraries(asynco_coroutine asynco Boost::system)
|
625
test/main.cpp
625
test/main.cpp
@ -1,625 +0,0 @@
|
||||
#define NUM_OF_RUNNERS 4
|
||||
|
||||
#include "asynco.hpp"
|
||||
#include "trigger.hpp"
|
||||
#include "filesystem.hpp"
|
||||
#include "timers.hpp"
|
||||
#include "define.hpp"
|
||||
|
||||
using namespace marcelb::asynco;
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <thread>
|
||||
#include <future>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
using namespace this_thread;
|
||||
|
||||
// asyncable<int> c2 (int a) {
|
||||
// co_return a*2;
|
||||
// }
|
||||
|
||||
// asyncable<void> sleep_co (int a) {
|
||||
// sleep(a);
|
||||
// cout << "Gotov" << endl;
|
||||
// co_return;
|
||||
// }
|
||||
|
||||
|
||||
// asyncable<void> c () {
|
||||
// cout << "Ispisi" << endl;
|
||||
// co_await c2(0);
|
||||
// co_return;
|
||||
// }
|
||||
|
||||
|
||||
|
||||
// void sleep_to (int _time) {
|
||||
// promise<void> _promise;
|
||||
// Delayed t( [&]() {
|
||||
// _promise.set_value();
|
||||
// }, _time);
|
||||
|
||||
// return _promise.get_future().get();
|
||||
// }
|
||||
|
||||
// void sleep_to (int _time) {
|
||||
// promise<void> _promise;
|
||||
// Delayed t( [&]() {
|
||||
// _promise.set_value();
|
||||
// }, _time);
|
||||
// await_ (_promise.get_future(), 100);
|
||||
// }
|
||||
|
||||
// future<void> sleep_to (int _time) {
|
||||
// promise<void> _promise;
|
||||
// future<void> _future = _promise.get_future();
|
||||
|
||||
// Delayed t( [&]() {
|
||||
// _promise.set_value();
|
||||
// }, _time);
|
||||
|
||||
// return _future;
|
||||
// }
|
||||
|
||||
// void promise_reject (int _time) {
|
||||
// promise<void> _promise;
|
||||
// Delayed t( [&]() {
|
||||
// try {
|
||||
// // simulate except
|
||||
// throw runtime_error("Error simulation");
|
||||
// _promise.set_value();
|
||||
// } catch (...) {
|
||||
// _promise.set_exception(current_exception());
|
||||
// }
|
||||
// }, _time);
|
||||
|
||||
// return _promise.get_future().get();
|
||||
// }
|
||||
|
||||
// void notLambdaFunction() {
|
||||
// cout << "Call to not lambda function" << endl;
|
||||
// }
|
||||
|
||||
// class clm {
|
||||
// public:
|
||||
// void classMethode() {
|
||||
// cout << "Call class method" << endl;
|
||||
// }
|
||||
// };
|
||||
|
||||
// // // ------------------ EXTEND OWN CLASS WITH EVENTS -------------------
|
||||
|
||||
// class myOwnClass : public Trigger<int> {
|
||||
// public:
|
||||
// myOwnClass() : Trigger() {};
|
||||
// };
|
||||
|
||||
// // ----------------- MULTIPLE TRIGGERS IN ONE CLASS ------------------
|
||||
|
||||
// class ClassWithTriggers {
|
||||
// Trigger<int> emitter1;
|
||||
// Trigger<string> emitter2;
|
||||
|
||||
// public:
|
||||
// template<typename... T>
|
||||
// void on(const string& key, function<void(T...)> callback) {
|
||||
// if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, int>) {
|
||||
// emitter1.on(key, callback);
|
||||
// }
|
||||
// else if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, string>) {
|
||||
// emitter2.on(key, callback);
|
||||
// }
|
||||
// }
|
||||
|
||||
// template <typename... Args>
|
||||
// void tick(const string& key, Args&&... args) {
|
||||
// if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, int>) {
|
||||
// emitter1.tick(key, forward<Args>(args)...);
|
||||
// }
|
||||
// else if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, string>) {
|
||||
// emitter2.tick(key, forward<Args>(args)...);
|
||||
// }
|
||||
// else {
|
||||
// static_assert(sizeof...(Args) == 0, "Unsupported number or types of arguments");
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
|
||||
int main () {
|
||||
|
||||
auto start = rtime_ms();
|
||||
|
||||
// --------------- TIME ASYNCHRONOUS FUNCTIONS --------------
|
||||
|
||||
/**
|
||||
* Init Periodic and delayed; clear Periodic and delayed
|
||||
*/
|
||||
|
||||
// Periodic inter1 ([&]() {
|
||||
// cout << "Periodic prvi " << rtime_ms() - start << endl;
|
||||
// }, 1000);
|
||||
|
||||
// Periodic inter2 ([&]() {
|
||||
// cout << "Periodic drugi " << rtime_ms() - start << endl;
|
||||
// }, 2000);
|
||||
|
||||
// Periodic inter3 ([&]() {
|
||||
// cout << "Periodic treći " << rtime_ms() - start << endl;
|
||||
// }, 1000);
|
||||
|
||||
// Periodic inter4 ([&]() {
|
||||
// // cout << "Periodic cetvrti " << rtime_ms() - start << endl;
|
||||
// cout << "Ticks " << inter3.ticks() << endl;
|
||||
// }, 500);
|
||||
|
||||
// Periodic inter5 ([&]() {
|
||||
// cout << "Periodic peti " << rtime_ms() - start << endl;
|
||||
// }, 2000);
|
||||
|
||||
// Periodic inter6 ([&]() {
|
||||
// cout << "Periodic sesti " << rtime_ms() - start << endl;
|
||||
// }, 3000);
|
||||
|
||||
// Delayed time1 ( [&] () {
|
||||
// cout << "Close Periodic 1 i 2 " << rtime_ms() - start << endl;
|
||||
// inter1.stop();
|
||||
// cout << "inter1.stop " << endl;
|
||||
// inter2.stop();
|
||||
// cout << "inter2.stop " << endl;
|
||||
// }, 8000);
|
||||
|
||||
|
||||
// Delayed time2 ([&] () {
|
||||
// cout << "Close Periodic 3 " << rtime_ms() - start << endl;
|
||||
// inter3.stop();
|
||||
// cout << "Stoped " << inter3.stoped() << endl;
|
||||
// // time1.stop();
|
||||
// }, 5000);
|
||||
|
||||
|
||||
// if (time2.expired()) {
|
||||
// cout << "isteko " << endl;
|
||||
// } else {
|
||||
// cout << "nije isteko " << endl;
|
||||
// }
|
||||
|
||||
// // sleep(6);
|
||||
|
||||
// if (time2.expired()) {
|
||||
// cout << "isteko " << endl;
|
||||
// } else {
|
||||
// cout << "nije isteko " << endl;
|
||||
// }
|
||||
|
||||
// // // // ------------------------ MAKE FUNCTIONS ASYNCHRONOUS -------------------------
|
||||
|
||||
// // /**
|
||||
// // * Run an function asyncronic
|
||||
// // */
|
||||
|
||||
// async_ ( []() {
|
||||
// sleep_for(2s); // only for simulate log duration function
|
||||
// cout << "asynco 1" << endl;
|
||||
// return 5;
|
||||
// });
|
||||
|
||||
// /**
|
||||
// * Call not lambda function
|
||||
// */
|
||||
|
||||
// async_ (notLambdaFunction);
|
||||
|
||||
|
||||
// await_ (
|
||||
// async_ (
|
||||
// notLambdaFunction
|
||||
// )
|
||||
// );
|
||||
|
||||
|
||||
// // async(launch::async, [] () {
|
||||
// // cout << "Another thread in async style!" << endl;
|
||||
// // });
|
||||
|
||||
// // /**
|
||||
// // * Call class method
|
||||
// // */
|
||||
|
||||
// clm classes;
|
||||
// async_ ( [&classes] () {
|
||||
// classes.classMethode();
|
||||
// });
|
||||
|
||||
// sleep(5);
|
||||
|
||||
// // /**
|
||||
// // * await_ after runned as async
|
||||
// // */
|
||||
|
||||
// auto aa = async_ ( []() {
|
||||
// sleep_for(2s); // only for simulate log duration function
|
||||
// cout << "async_ 2" << endl;
|
||||
// return 5;
|
||||
// });
|
||||
|
||||
// cout << await_(aa) << endl;
|
||||
// cout << "print after async_ 2" << endl;
|
||||
|
||||
// /**
|
||||
// * await_ async function call and use i cout
|
||||
// */
|
||||
|
||||
// cout << await_(async_ ( [] () {
|
||||
// sleep_for(chrono::seconds(1)); // only for simulate log duration function
|
||||
// cout << "await_ end" << endl;
|
||||
// return 4;
|
||||
// })) << endl;
|
||||
|
||||
// /**
|
||||
// * Sleep with Delayed sleep implement
|
||||
// */
|
||||
|
||||
// sleep_to(3000);
|
||||
// cout << "sleep_to " << rtime_ms() - start << endl;
|
||||
|
||||
// /**
|
||||
// * Catch promise reject
|
||||
// */
|
||||
|
||||
// try {
|
||||
// promise_reject(3000);
|
||||
// } catch (runtime_error err) {
|
||||
// cout<< err.what() << endl;
|
||||
// }
|
||||
|
||||
// cout << "promise_reject " << rtime_ms() - start << endl;
|
||||
|
||||
|
||||
// /**
|
||||
// * Nested asynchronous invocation
|
||||
// */
|
||||
|
||||
|
||||
// async_ ( [] {
|
||||
// cout << "idemo ..." << endl;
|
||||
// async_ ( [] {
|
||||
// cout << "ugdnježdena async funkcija " << endl;
|
||||
// });
|
||||
// });
|
||||
|
||||
|
||||
// // -------------------------- AWAIT ALL ----------------------------------
|
||||
|
||||
auto a = async_ ( []() {
|
||||
cout << "A" << endl;
|
||||
return 3;
|
||||
});
|
||||
|
||||
auto b = async_ ( []() {
|
||||
cout << "B" << endl;
|
||||
// throw runtime_error("Test exception");
|
||||
return;
|
||||
});
|
||||
|
||||
auto c = async_ ( []() {
|
||||
cout << "C" << endl;
|
||||
return "Hello";
|
||||
});
|
||||
|
||||
int a_;
|
||||
string c_;
|
||||
|
||||
// auto all = await_(a, c);
|
||||
// cout << get<0>(all) << get<1>(all) << endl;
|
||||
|
||||
// ili
|
||||
|
||||
tie(a_, c_) = await_(a, c);
|
||||
cout << a_ << c_ << endl;
|
||||
|
||||
int d_;
|
||||
float e_;
|
||||
tie(d_, e_) = await_( async_ ( []() {return 1;}), async_ ([](){ return 4.3;}));
|
||||
|
||||
cout << d_ << e_ << endl;
|
||||
|
||||
|
||||
// auto await_all = [&] () {
|
||||
// a_ = await_(a);
|
||||
// await_(b);
|
||||
// c_ = await_(c);
|
||||
// };
|
||||
|
||||
// try {
|
||||
// await_all();
|
||||
// cout << "a_ " << a_ << " c_ " << c_ << endl;
|
||||
// } catch (const exception& exc) {
|
||||
// cout << exc.what() << endl;
|
||||
// }
|
||||
|
||||
// // // same type
|
||||
|
||||
// vector<future<void>> fut_vec;
|
||||
// for (int i=0; i<5; i++) {
|
||||
// fut_vec.push_back(
|
||||
// async_ ( [i]() {
|
||||
// cout << "Async_ " << i << endl;
|
||||
// })
|
||||
// );
|
||||
// }
|
||||
|
||||
// auto await_all2 = [&] () {
|
||||
// for (int i=0; i<fut_vec.size(); i++) {
|
||||
// await_ (fut_vec[i]);
|
||||
// }
|
||||
// };
|
||||
|
||||
// await_all2();
|
||||
|
||||
// // --------------- EVENTS -------------------
|
||||
|
||||
// /**
|
||||
// * initialization of typed events
|
||||
// */
|
||||
|
||||
// Trigger<int, int> ev2int;
|
||||
// Trigger<int, string> evintString;
|
||||
// Trigger<> evoid;
|
||||
|
||||
// ev2int.on("sum", [](int a, int b) {
|
||||
// cout << "Sum " << a+b << 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;
|
||||
// });
|
||||
|
||||
// evoid.on("void", []() {
|
||||
// cout << "Void emited" << endl;
|
||||
// });
|
||||
|
||||
// string emited2 = "2";
|
||||
|
||||
// evoid.on("void", [&]() {
|
||||
// cout << "Void emited " << emited2 << endl;
|
||||
// });
|
||||
|
||||
// evoid.tick("void");
|
||||
// sleep(1);
|
||||
|
||||
// /**
|
||||
// * Emit
|
||||
// */
|
||||
|
||||
// ev2int.tick("sum", 5, 8);
|
||||
|
||||
|
||||
// sleep(1);
|
||||
// evintString.tick("substract", 3, to_string(2));
|
||||
|
||||
// sleep(1);
|
||||
// evoid.off("void");
|
||||
// evoid.tick("void");
|
||||
|
||||
|
||||
// cout << "Ukupno 2 int " << ev2int.listeners() << endl;
|
||||
// cout << "Ukupno evintString " << evintString.listeners() << endl;
|
||||
// cout << "Ukupno evoid " << evoid.listeners() << endl;
|
||||
// cout << "Ukupno 2 int " << ev2int.listeners("sum") << endl;
|
||||
|
||||
// /**
|
||||
// * Own class
|
||||
// */
|
||||
|
||||
// myOwnClass myclass;
|
||||
|
||||
// Delayed t( [&] {
|
||||
// myclass.tick("constructed", 1);
|
||||
// }, 200);
|
||||
|
||||
// myclass.on("constructed", [] (int i) {
|
||||
// cout << "Constructed " << i << endl;
|
||||
// });
|
||||
|
||||
// /**
|
||||
// *
|
||||
// * Use class with multiple triggers
|
||||
// *
|
||||
// */
|
||||
|
||||
// ClassWithTriggers mt;
|
||||
|
||||
// mt.on<int>("int", function<void(int)>([&](int i) {
|
||||
// cout << "Emit int " << i << endl;
|
||||
// }));
|
||||
|
||||
// mt.on<string>("string", function<void(string)>([&](string s) {
|
||||
// cout << "Emit string " << s << endl;
|
||||
// }));
|
||||
|
||||
// mt.tick("int", 5);
|
||||
// mt.tick("string", string("Hello world"));
|
||||
|
||||
|
||||
// auto status = fs::read("test1.txt");
|
||||
|
||||
|
||||
// try {
|
||||
// auto data = await_(status);
|
||||
// cout << data;
|
||||
// } catch (exception& err) {
|
||||
// cout << err.what() << endl;
|
||||
// }
|
||||
|
||||
|
||||
// string data_;
|
||||
// auto start_read = rtime_us();
|
||||
|
||||
// fs::read("test1.txt", [&data_, &start_read] (string data, exception* error) {
|
||||
// if (error) {
|
||||
// cout << "Error " << error->what() << endl;
|
||||
// } else {
|
||||
// // cout << "Data " << endl << data << endl;
|
||||
// // data_ = data;
|
||||
// // cout << "Data_" << data_ << endl;
|
||||
// cout << "read " << rtime_us() - start_read << 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_ ( [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");
|
||||
|
||||
|
||||
|
||||
|
||||
// vector<future<void>> 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_Default_Runtime.run();
|
||||
return 0;
|
||||
}
|
||||
|
84
test/main_async.cpp
Normal file
84
test/main_async.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
#include "../lib/asynco.hpp"
|
||||
using namespace marcelb::asynco;
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
Asynco asynco;
|
||||
|
||||
void notLambdaFunction() {
|
||||
cout << "Call to not lambda function" << endl;
|
||||
}
|
||||
|
||||
|
||||
class clm {
|
||||
public:
|
||||
void classMethode() {
|
||||
cout << "Call class method" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
void sleep_to (int _time) {
|
||||
promise<void> _promise;
|
||||
Timer t = asynco.delayed( [&]() {
|
||||
_promise.set_value();
|
||||
}, _time);
|
||||
|
||||
return asynco.await(_promise.get_future());
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
asynco.run(2);
|
||||
|
||||
/**
|
||||
* Run an lambda function asynchronously
|
||||
*/
|
||||
|
||||
asynco.async ( []() {
|
||||
cout << "async " << endl;
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Run not lambda function
|
||||
*/
|
||||
|
||||
asynco.async (notLambdaFunction);
|
||||
|
||||
/**
|
||||
* Run class method
|
||||
*/
|
||||
|
||||
clm classes;
|
||||
asynco.async ( [&classes] () {
|
||||
classes.classMethode();
|
||||
});
|
||||
|
||||
//------------------AWAIT----------------------
|
||||
|
||||
auto a = asynco.async ( []() {
|
||||
sleep_to(1000); //only for simulating long duration function
|
||||
return 5;
|
||||
});
|
||||
|
||||
cout << asynco.await(a) << endl;
|
||||
|
||||
/**
|
||||
* await async function call and use i cout
|
||||
*/
|
||||
|
||||
cout << asynco.await(asynco.async ( [] () {
|
||||
sleep_to(1000);
|
||||
cout << "await_ end" << endl;
|
||||
return 4;
|
||||
})) << endl;
|
||||
|
||||
|
||||
asynco.await ([]() { // run in runtime and await now
|
||||
cout << "Hello" << endl;
|
||||
});
|
||||
|
||||
asynco.join();
|
||||
return 0;
|
||||
}
|
82
test/main_async_default.cpp
Normal file
82
test/main_async_default.cpp
Normal file
@ -0,0 +1,82 @@
|
||||
#include "../lib/asynco_default.hpp"
|
||||
using namespace marcelb::asynco;
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
void notLambdaFunction() {
|
||||
cout << "Call to not lambda function" << endl;
|
||||
}
|
||||
|
||||
|
||||
class clm {
|
||||
public:
|
||||
void classMethode() {
|
||||
cout << "Call class method" << endl;
|
||||
}
|
||||
};
|
||||
|
||||
void sleep_to (int _time) {
|
||||
promise<void> _promise;
|
||||
Timer t = delayed( [&]() {
|
||||
_promise.set_value();
|
||||
}, _time);
|
||||
|
||||
return await_(_promise.get_future());
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
||||
asynco_default_run();
|
||||
|
||||
/**
|
||||
* Run an lambda function asynchronously
|
||||
*/
|
||||
|
||||
async_ ( []() {
|
||||
cout << "async " << endl;
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Run not lambda function
|
||||
*/
|
||||
|
||||
async_ (notLambdaFunction);
|
||||
|
||||
/**
|
||||
* Run class method
|
||||
*/
|
||||
|
||||
clm classes;
|
||||
async_ ( [&classes] () {
|
||||
classes.classMethode();
|
||||
});
|
||||
|
||||
//------------------AWAIT----------------------
|
||||
|
||||
auto a = async_ ( []() {
|
||||
sleep_to(1000); //only for simulating long duration function
|
||||
return 5;
|
||||
});
|
||||
|
||||
cout << await_(a) << endl;
|
||||
|
||||
/**
|
||||
* await async function call and use i cout
|
||||
*/
|
||||
|
||||
cout << await_(async_ ( [] () {
|
||||
sleep_to(1000);
|
||||
cout << "await_ end" << endl;
|
||||
return 4;
|
||||
})) << endl;
|
||||
|
||||
|
||||
await_ ([]() { // run in runtime and await now
|
||||
cout << "Hello" << endl;
|
||||
});
|
||||
|
||||
asynco_default_join();
|
||||
return 0;
|
||||
}
|
42
test/main_coroutine.cpp
Normal file
42
test/main_coroutine.cpp
Normal file
@ -0,0 +1,42 @@
|
||||
#include "../lib/asynco.hpp"
|
||||
using namespace marcelb::asynco;
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
|
||||
Asynco asynco; // or global
|
||||
asynco.run(2);
|
||||
|
||||
asyncable<int> c2(int a) {
|
||||
co_return a * 2;
|
||||
}
|
||||
|
||||
asynco.async(c2(4));
|
||||
|
||||
asynco.async([]() -> asyncable<void> {
|
||||
std::cout << "Hello" << std::endl;
|
||||
co_await c2(4);
|
||||
co_return;
|
||||
}());
|
||||
|
||||
|
||||
int r = asynco.await(
|
||||
asynco.async(
|
||||
c2(10)
|
||||
));
|
||||
|
||||
|
||||
auto a = asynco.await( c2(3));
|
||||
cout << a << endl;
|
||||
|
||||
asynco.await([]() -> asyncable<void> {
|
||||
cout << "Hello" << endl;
|
||||
co_return;
|
||||
}());
|
||||
|
||||
|
||||
asynco.join();
|
||||
return 0;
|
||||
}
|
40
test/main_coroutine_default.cpp
Normal file
40
test/main_coroutine_default.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "../lib/asynco_default.hpp"
|
||||
using namespace marcelb::asynco;
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
asynco_default_run();
|
||||
|
||||
asyncable<int> c2(int a) {
|
||||
co_return a * 2;
|
||||
}
|
||||
|
||||
async_(c2(4));
|
||||
|
||||
async_([]() -> asyncable<void> {
|
||||
std::cout << "Hello" << std::endl;
|
||||
co_await c2(4);
|
||||
co_return;
|
||||
}());
|
||||
|
||||
|
||||
int r = await_(
|
||||
async_(
|
||||
c2(10)
|
||||
));
|
||||
|
||||
|
||||
auto a = await_ ( c2(3));
|
||||
cout << a << endl;
|
||||
|
||||
await_ ([]() -> asyncable<void> {
|
||||
cout << "Hello" << endl;
|
||||
co_return;
|
||||
}());
|
||||
|
||||
|
||||
asynco_default_join();
|
||||
return 0;
|
||||
}
|
@ -5,18 +5,10 @@ using namespace marcelb::asynco;
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
Asynco_Default_Runtime.run();
|
||||
cout << "main" << endl;
|
||||
asynco_default_run();
|
||||
|
||||
async_([](){
|
||||
cout << "idemo" << endl;
|
||||
});
|
||||
// code
|
||||
|
||||
auto interval = periodic([&](){
|
||||
cout << "idemo" << endl;
|
||||
}, 1000);
|
||||
|
||||
|
||||
Asynco_Default_Runtime.join();
|
||||
asynco_default_join();
|
||||
return 0;
|
||||
}
|
@ -9,10 +9,7 @@ int main() {
|
||||
Asynco asynco;
|
||||
asynco.run(2);
|
||||
|
||||
auto interval = asynco.periodic([](){
|
||||
cout << "idemo" << endl;
|
||||
}, 1000);
|
||||
|
||||
// code
|
||||
|
||||
asynco.join();
|
||||
return 0;
|
41
test/main_timers.cpp
Normal file
41
test/main_timers.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include "../lib/asynco.hpp"
|
||||
using namespace marcelb::asynco;
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
Asynco asynco;
|
||||
asynco.run(2);
|
||||
|
||||
Timer inter1 = asynco.periodic ([]() {
|
||||
cout << "Interval 1" << endl;
|
||||
}, 1000);
|
||||
|
||||
// stop periodic
|
||||
inter1.stop();
|
||||
|
||||
// how many times it has expired
|
||||
int ti = inter1.ticks();
|
||||
|
||||
// is it stopped
|
||||
bool stoped_i = inter1.stoped();
|
||||
|
||||
// start delayed
|
||||
Timer time1 = asynco.delayed ( [] () {
|
||||
cout << "Timeout 1 " << endl;
|
||||
}, 10000);
|
||||
|
||||
// stop delayed
|
||||
time1.stop();
|
||||
|
||||
// is it expired
|
||||
int tt = time1.expired();
|
||||
|
||||
// is it stopped
|
||||
bool stoped_t = time1.stoped();
|
||||
|
||||
|
||||
asynco.join();
|
||||
return 0;
|
||||
}
|
40
test/main_timers_default.cpp
Normal file
40
test/main_timers_default.cpp
Normal file
@ -0,0 +1,40 @@
|
||||
#include "../lib/asynco_default.hpp"
|
||||
using namespace marcelb::asynco;
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
|
||||
int main() {
|
||||
asynco_default_run();
|
||||
|
||||
Timer inter1 = periodic ([]() {
|
||||
cout << "Interval 1" << endl;
|
||||
}, 1000);
|
||||
|
||||
// stop periodic
|
||||
inter1.stop();
|
||||
|
||||
// how many times it has expired
|
||||
int ti = inter1.ticks();
|
||||
|
||||
// is it stopped
|
||||
bool stoped_i = inter1.stoped();
|
||||
|
||||
// start delayed
|
||||
Timer time1 = delayed ( [] () {
|
||||
cout << "Timeout 1 " << endl;
|
||||
}, 10000);
|
||||
|
||||
// stop delayed
|
||||
time1.stop();
|
||||
|
||||
// is it expired
|
||||
int tt = time1.expired();
|
||||
|
||||
// is it stopped
|
||||
bool stoped_t = time1.stoped();
|
||||
|
||||
asynco_default_join();
|
||||
return 0;
|
||||
}
|
124
test/main_trigger.cpp
Normal file
124
test/main_trigger.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
#include "../lib/asynco.hpp"
|
||||
using namespace marcelb::asynco;
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
Asynco asynco;
|
||||
|
||||
class ClassWithTriggers {
|
||||
Trigger<int> emitter1;
|
||||
Trigger<string> emitter2;
|
||||
|
||||
public:
|
||||
ClassWithTriggers(): emitter1(asynco), emitter2(asynco) {}
|
||||
|
||||
template<typename... T>
|
||||
void on(const string& key, function<void(T...)> callback) {
|
||||
if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, int>) {
|
||||
emitter1.on(key, callback);
|
||||
}
|
||||
else if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, string>) {
|
||||
emitter2.on(key, callback);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void tick(const string& key, Args&&... args) {
|
||||
if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, int>) {
|
||||
emitter1.tick(key, forward<Args>(args)...);
|
||||
}
|
||||
else if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, string>) {
|
||||
emitter2.tick(key, forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
static_assert(sizeof...(Args) == 0, "Unsupported number or types of arguments");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
asynco.run(2);
|
||||
|
||||
/**
|
||||
* initialization of typed events
|
||||
*/
|
||||
|
||||
Trigger<int, int> ev2int = asynco.trigger<int, int>();
|
||||
Trigger<int, string> evintString = asynco.trigger<int, string>();
|
||||
Trigger<> evoid = asynco.trigger<>();
|
||||
|
||||
|
||||
ev2int.on("sum", [](int a, int b) {
|
||||
cout << "Sum " << a+b << endl;
|
||||
});
|
||||
|
||||
evintString.on("substract", [](int a, string b) {
|
||||
cout << "Substract " << a-stoi(b) << endl;
|
||||
});
|
||||
|
||||
evoid.on("void", []() {
|
||||
cout << "Void emited" << endl;
|
||||
});
|
||||
|
||||
// multiple listeners
|
||||
|
||||
string emited2 = "2";
|
||||
|
||||
evoid.on("void", [&]() {
|
||||
cout << "Void emited " << emited2 << endl;
|
||||
});
|
||||
|
||||
sleep(1);
|
||||
|
||||
/**
|
||||
* Emit
|
||||
*/
|
||||
|
||||
ev2int.tick("sum", 5, 8);
|
||||
|
||||
sleep(1);
|
||||
evintString.tick("substract", 3, to_string(2));
|
||||
|
||||
sleep(1);
|
||||
evoid.tick("void");
|
||||
|
||||
// Turn off the event listener
|
||||
|
||||
evoid.off("void");
|
||||
evoid.tick("void"); // nothing is happening
|
||||
|
||||
|
||||
class myOwnClass : public Trigger<int> {
|
||||
public:
|
||||
myOwnClass() : Trigger(asynco) {};
|
||||
};
|
||||
|
||||
myOwnClass myclass;
|
||||
|
||||
Timer t = asynco.delayed( [&] {
|
||||
myclass.tick("constructed", 1);
|
||||
}, 200);
|
||||
|
||||
myclass.on("constructed", [] (int i) {
|
||||
cout << "Constructed " << i << endl;
|
||||
});
|
||||
|
||||
|
||||
ClassWithTriggers mt;
|
||||
|
||||
mt.on<int>("int", function<void(int)>([&](int i) {
|
||||
cout << "Emit int " << i << endl;
|
||||
}));
|
||||
|
||||
mt.on<string>("string", function<void(string)>([&](string s) {
|
||||
cout << "Emit string " << s << endl;
|
||||
}));
|
||||
|
||||
mt.tick("int", 5);
|
||||
mt.tick("string", string("Hello world"));
|
||||
|
||||
|
||||
asynco.join();
|
||||
return 0;
|
||||
}
|
118
test/main_trigger_default.cpp
Normal file
118
test/main_trigger_default.cpp
Normal file
@ -0,0 +1,118 @@
|
||||
#include "../lib/asynco_default.hpp"
|
||||
using namespace marcelb::asynco;
|
||||
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
|
||||
class ClassWithTriggers {
|
||||
Trigger<int> emitter1;
|
||||
Trigger<string> emitter2;
|
||||
|
||||
public:
|
||||
ClassWithTriggers(): emitter1(asynco_default_runtime()), emitter2(asynco_default_runtime()) {}
|
||||
|
||||
template<typename... T>
|
||||
void on(const string& key, function<void(T...)> callback) {
|
||||
if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, int>) {
|
||||
emitter1.on(key, callback);
|
||||
}
|
||||
else if constexpr (sizeof...(T) == 1 && is_same_v<tuple_element_t<0, tuple<T...>>, string>) {
|
||||
emitter2.on(key, callback);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
void tick(const string& key, Args&&... args) {
|
||||
if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, int>) {
|
||||
emitter1.tick(key, forward<Args>(args)...);
|
||||
}
|
||||
else if constexpr (sizeof...(Args) == 1 && is_same_v<tuple_element_t<0, tuple<Args...>>, string>) {
|
||||
emitter2.tick(key, forward<Args>(args)...);
|
||||
}
|
||||
else {
|
||||
static_assert(sizeof...(Args) == 0, "Unsupported number or types of arguments");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
asynco_default_run();
|
||||
|
||||
/**
|
||||
* initialization of typed events
|
||||
*/
|
||||
|
||||
Trigger<int, int> ev2int = trigger<int, int>();
|
||||
Trigger<int, string> evintString = trigger<int, string>();
|
||||
Trigger<> evoid = trigger<>();
|
||||
|
||||
ev2int.on("sum", [](int a, int b) {
|
||||
cout << "Sum " << a+b << endl;
|
||||
});
|
||||
|
||||
evintString.on("substract", [](int a, string b) {
|
||||
cout << "Substract " << a-stoi(b) << endl;
|
||||
});
|
||||
|
||||
evoid.on("void", []() {
|
||||
cout << "Void emited" << endl;
|
||||
});
|
||||
|
||||
// multiple listeners
|
||||
|
||||
string emited2 = "2";
|
||||
|
||||
evoid.on("void", [&]() {
|
||||
cout << "Void emited " << emited2 << endl;
|
||||
});
|
||||
|
||||
sleep(1);
|
||||
|
||||
/**
|
||||
* Emit
|
||||
*/
|
||||
|
||||
ev2int.tick("sum", 5, 8);
|
||||
|
||||
sleep(1);
|
||||
evintString.tick("substract", 3, to_string(2));
|
||||
|
||||
sleep(1);
|
||||
evoid.tick("void");
|
||||
|
||||
// Turn off the event listener
|
||||
|
||||
evoid.off("void");
|
||||
evoid.tick("void"); // nothing is happening
|
||||
|
||||
class myOwnClass : public Trigger<int> {
|
||||
public:
|
||||
myOwnClass() : Trigger(asynco_default_runtime()) {};
|
||||
};
|
||||
|
||||
myOwnClass myclass;
|
||||
|
||||
Timer t = delayed( [&] {
|
||||
myclass.tick("constructed", 1);
|
||||
}, 200);
|
||||
|
||||
myclass.on("constructed", [] (int i) {
|
||||
cout << "Constructed " << i << endl;
|
||||
});
|
||||
|
||||
ClassWithTriggers mt;
|
||||
|
||||
mt.on<int>("int", function<void(int)>([&](int i) {
|
||||
cout << "Emit int " << i << endl;
|
||||
}));
|
||||
|
||||
mt.on<string>("string", function<void(string)>([&](string s) {
|
||||
cout << "Emit string " << s << endl;
|
||||
}));
|
||||
|
||||
mt.tick("int", 5);
|
||||
mt.tick("string", string("Hello world"));
|
||||
|
||||
asynco_default_join();
|
||||
return 0;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user