Compare commits
No commits in common. "dev" and "nonsync_wait" have entirely different histories.
dev
...
nonsync_wa
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,2 @@
|
|||||||
build
|
test/test
|
||||||
.vscode
|
test/*.txt
|
||||||
example
|
|
16
.vscode/c_cpp_properties.json
vendored
Normal file
16
.vscode/c_cpp_properties.json
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Linux",
|
||||||
|
"includePath": [
|
||||||
|
"${workspaceFolder}/**"
|
||||||
|
],
|
||||||
|
"defines": [],
|
||||||
|
"compilerPath": "/usr/bin/gcc",
|
||||||
|
"cStandard": "c17",
|
||||||
|
"cppStandard": "gnu++17",
|
||||||
|
"intelliSenseMode": "linux-gcc-x64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": 4
|
||||||
|
}
|
74
.vscode/settings.json
vendored
Normal file
74
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"iostream": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"thread": "cpp",
|
||||||
|
"chrono": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"condition_variable": "cpp",
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"mutex": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"ratio": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"future": "cpp",
|
||||||
|
"*.ipp": "cpp",
|
||||||
|
"bitset": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"string_view": "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"
|
||||||
|
}
|
||||||
|
}
|
28
.vscode/tasks.json
vendored
Normal file
28
.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"tasks": [
|
||||||
|
{
|
||||||
|
"type": "cppbuild",
|
||||||
|
"label": "C/C++: gcc build active file",
|
||||||
|
"command": "/usr/bin/g++",
|
||||||
|
"args": [
|
||||||
|
"-fdiagnostics-color=always",
|
||||||
|
"-g",
|
||||||
|
"${file}",
|
||||||
|
"-o",
|
||||||
|
"${fileDirname}/${fileBasenameNoExtension}"
|
||||||
|
],
|
||||||
|
"options": {
|
||||||
|
"cwd": "${fileDirname}"
|
||||||
|
},
|
||||||
|
"problemMatcher": [
|
||||||
|
"$gcc"
|
||||||
|
],
|
||||||
|
"group": {
|
||||||
|
"kind": "build",
|
||||||
|
"isDefault": true
|
||||||
|
},
|
||||||
|
"detail": "Task generated by Debugger."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version": "2.0.0"
|
||||||
|
}
|
@ -1,31 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.10)
|
|
||||||
|
|
||||||
project(Asynco)
|
|
||||||
|
|
||||||
# Postavi verziju projekta
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
|
|
||||||
# Pronađi Boost biblioteku (ako nije uobičajeni direktorijum, postavi put)
|
|
||||||
find_package(Boost REQUIRED COMPONENTS system)
|
|
||||||
|
|
||||||
# Dodaj direktorijume sa zaglavljima
|
|
||||||
include_directories(lib)
|
|
||||||
|
|
||||||
# Dodaj biblioteku
|
|
||||||
add_library(asynco STATIC
|
|
||||||
src/engine.cpp
|
|
||||||
src/timers.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
# Linkaj Asynco biblioteku sa Boost-om
|
|
||||||
target_link_libraries(asynco Boost::system)
|
|
||||||
|
|
||||||
# Dodaj testove
|
|
||||||
add_subdirectory(test)
|
|
||||||
|
|
||||||
|
|
||||||
# Instaliraj biblioteku
|
|
||||||
# install(TARGETS asynco DESTINATION lib)
|
|
||||||
# install(FILES lib/asynco.hpp lib/define.hpp lib/engine.hpp lib/filesystem.hpp lib/timers.hpp lib/trigger.hpp DESTINATION include/asynco)
|
|
||||||
#
|
|
71
README.md
71
README.md
@ -77,28 +77,6 @@ int t = time1.expired();
|
|||||||
// is it stopped
|
// is it stopped
|
||||||
bool stoped = time1.stoped();
|
bool stoped = time1.stoped();
|
||||||
|
|
||||||
// If you don't want to save in a variable, but you want to start a timer, use these functions
|
|
||||||
// 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
|
||||||
|
|
||||||
@ -329,55 +307,6 @@ myclass.on("constructed", [] (int i) {
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Implementing a class with multiple triggers of different types
|
|
||||||
|
|
||||||
```c++
|
|
||||||
|
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
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"));
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Asynchronous file IO
|
Asynchronous file IO
|
||||||
|
|
||||||
```c++
|
```c++
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef _ASYNCO_
|
#ifndef _ASYNCO_
|
||||||
#define _ASYNCO_
|
#define _ASYNCO_
|
||||||
|
|
||||||
#include "engine.hpp"
|
#include <boost/asio.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
@ -9,6 +9,51 @@ using namespace std;
|
|||||||
namespace marcelb {
|
namespace marcelb {
|
||||||
namespace asynco {
|
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<boost::asio::io_service::work> work { [&] () {
|
||||||
|
return new boost::asio::io_service::work(io_context);
|
||||||
|
} ()};
|
||||||
|
|
||||||
|
vector<thread> runners { [&] () {
|
||||||
|
vector<thread> _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<num_of_runners; i++) {
|
||||||
|
_runs.push_back(thread ( [this] () {
|
||||||
|
io_context.run();
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
return _runs;
|
||||||
|
} ()};
|
||||||
|
|
||||||
|
} _asynco_engine;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run the function asynchronously
|
* Run the function asynchronously
|
||||||
*/
|
*/
|
||||||
@ -35,28 +80,6 @@ T await_(future<T>&& r) {
|
|||||||
return move(r).get();
|
return move(r).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Block until the asynchronous call completes or time expired
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
T await_(future<T>& r, uint64_t time) {
|
|
||||||
if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) {
|
|
||||||
throw runtime_error("Asynchronous execution timed out");
|
|
||||||
}
|
|
||||||
return r.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Block until the asynchronous call completes or time expired
|
|
||||||
*/
|
|
||||||
template<typename T>
|
|
||||||
T await_(future<T>&& r, uint64_t time) {
|
|
||||||
if (r.wait_for(chrono::milliseconds(time)) == std::future_status::timeout) {
|
|
||||||
throw runtime_error("Asynchronous execution timed out");
|
|
||||||
}
|
|
||||||
return move(r).get();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
#ifndef _ASYNCO_ENGINE_
|
|
||||||
#define _ASYNCO_ENGINE_
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <memory>
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include <boost/asio.hpp>
|
|
||||||
|
|
||||||
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<boost::asio::io_service::work> work { [&] () {
|
|
||||||
return new boost::asio::io_service::work(io_context);
|
|
||||||
} ()};
|
|
||||||
|
|
||||||
vector<thread> runners { [&] () {
|
|
||||||
vector<thread> _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<num_of_runners; i++) {
|
|
||||||
_runs.push_back(thread ( [this] () {
|
|
||||||
io_context.run();
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
return _runs;
|
|
||||||
} ()};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
extern Engine _asynco_engine;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
126
lib/timers.hpp
126
lib/timers.hpp
@ -1,10 +1,12 @@
|
|||||||
#ifndef _ASYNCO_TIMERS_
|
#ifndef _TIMERS_
|
||||||
#define _ASYNCO_TIMERS_
|
#define _TIMERS_
|
||||||
|
|
||||||
#include <chrono>
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
#include "asynco.hpp"
|
#include "asynco.hpp"
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace marcelb;
|
||||||
|
using namespace asynco;
|
||||||
|
|
||||||
namespace marcelb {
|
namespace marcelb {
|
||||||
namespace asynco {
|
namespace asynco {
|
||||||
@ -13,13 +15,21 @@ namespace asynco {
|
|||||||
* Get the time in ms from the epoch
|
* Get the time in ms from the epoch
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int64_t rtime_ms();
|
int64_t rtime_ms() {
|
||||||
|
return chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now()
|
||||||
|
.time_since_epoch())
|
||||||
|
.count();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the time in us from the epoch
|
* Get the time in us from the epoch
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int64_t rtime_us();
|
int64_t rtime_us() {
|
||||||
|
return chrono::duration_cast<chrono::microseconds>(chrono::system_clock::now()
|
||||||
|
.time_since_epoch())
|
||||||
|
.count();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Core timer class for construct time async functions
|
* Core timer class for construct time async functions
|
||||||
@ -35,40 +45,71 @@ class timer {
|
|||||||
/**
|
/**
|
||||||
* A method to assign a callback wrapper and a reinitialization algorithm
|
* A method to assign a callback wrapper and a reinitialization algorithm
|
||||||
*/
|
*/
|
||||||
void init();
|
void init() {
|
||||||
|
st.async_wait( [this] (const boost::system::error_code&) {
|
||||||
|
if (!_stop) {
|
||||||
|
callback();
|
||||||
|
if (repeate) {
|
||||||
|
st = boost::asio::steady_timer(_asynco_engine.io_context, boost::asio::chrono::milliseconds(time));
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
_ticks++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The constructor creates the steady_timer and accompanying variables and runs a method to initialize the timer
|
* The constructor creates the steady_timer and accompanying variables and runs a method to initialize the timer
|
||||||
*/
|
*/
|
||||||
timer (function<void()> _callback, uint64_t _time, bool _repeate);
|
timer (function<void()> _callback, uint64_t _time, bool _repeate) :
|
||||||
|
st(_asynco_engine.io_context, boost::asio::chrono::milliseconds(_time)),
|
||||||
|
_stop(false),
|
||||||
|
repeate(_repeate),
|
||||||
|
callback(_callback),
|
||||||
|
time(_time) {
|
||||||
|
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop timer
|
* Stop timer
|
||||||
* The stop flag is set and timer remove it from the queue
|
* The stop flag is set and timer remove it from the queue
|
||||||
*/
|
*/
|
||||||
void stop();
|
void stop() {
|
||||||
|
_stop = true;
|
||||||
|
st.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run callback now
|
* Run callback now
|
||||||
* Forces the callback function to run independently of the timer
|
* Forces the callback function to run independently of the timer
|
||||||
*/
|
*/
|
||||||
void now();
|
void now() {
|
||||||
|
st.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of times the timer callback was runned
|
* Get the number of times the timer callback was runned
|
||||||
*/
|
*/
|
||||||
uint64_t ticks();
|
uint64_t ticks() {
|
||||||
|
return _ticks;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logic status of the timer stop state
|
* The logic status of the timer stop state
|
||||||
*/
|
*/
|
||||||
bool stoped();
|
bool stoped() {
|
||||||
|
return _stop;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The destructor stops the timer
|
* The destructor stops the timer
|
||||||
*/
|
*/
|
||||||
~timer();
|
~timer() {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -78,37 +119,49 @@ class periodic {
|
|||||||
shared_ptr<timer> _timer;
|
shared_ptr<timer> _timer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor initializes a shared pointer of type timer
|
* Constructor initializes a shared pointer of type timer
|
||||||
*/
|
*/
|
||||||
periodic(function<void()> callback, uint64_t time);
|
periodic(function<void()> callback, uint64_t time) :
|
||||||
|
_timer(make_shared<timer> (callback, time, true)) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop periodic
|
* Stop periodic
|
||||||
* The stop flag is set and periodic remove it from the queue
|
* The stop flag is set and periodic remove it from the queue
|
||||||
*/
|
*/
|
||||||
void stop();
|
void stop() {
|
||||||
|
_timer->stop();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run callback now
|
* Run callback now
|
||||||
* Forces the callback function to run independently of the periodic
|
* Forces the callback function to run independently of the periodic
|
||||||
*/
|
*/
|
||||||
void now();
|
void now() {
|
||||||
|
_timer->now();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of times the periodic callback was runned
|
* Get the number of times the periodic callback was runned
|
||||||
*/
|
*/
|
||||||
uint64_t ticks();
|
uint64_t ticks() {
|
||||||
|
return _timer->ticks();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logic status of the periodic stop state
|
* The logic status of the periodic stop state
|
||||||
*/
|
*/
|
||||||
bool stoped();
|
bool stoped() {
|
||||||
|
return _timer->stoped();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The destructor stops the periodic
|
* The destructor stops the periodic
|
||||||
*/
|
*/
|
||||||
~periodic();
|
~periodic() {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,43 +171,52 @@ class delayed {
|
|||||||
shared_ptr<timer> _timer;
|
shared_ptr<timer> _timer;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor initializes a shared pointer of type timer
|
* Constructor initializes a shared pointer of type timer
|
||||||
*/
|
*/
|
||||||
delayed(function<void()> callback, uint64_t time);
|
delayed(function<void()> callback, uint64_t time) :
|
||||||
|
_timer(make_shared<timer> (callback, time, false)) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stop delayed
|
* Stop delayed
|
||||||
* The stop flag is set and delayed remove it from the queue
|
* The stop flag is set and delayed remove it from the queue
|
||||||
*/
|
*/
|
||||||
void stop();
|
void stop() {
|
||||||
|
_timer->stop();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Run callback now
|
* Run callback now
|
||||||
* Forces the callback function to run independently of the delayed
|
* Forces the callback function to run independently of the delayed
|
||||||
*/
|
*/
|
||||||
void now();
|
void now() {
|
||||||
|
_timer->now();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get is the delayed callback runned
|
* Get is the delayed callback runned
|
||||||
*/
|
*/
|
||||||
bool expired();
|
bool expired() {
|
||||||
|
return bool(_timer->ticks());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The logic status of the delayed stop state
|
* The logic status of the delayed stop state
|
||||||
*/
|
*/
|
||||||
bool stoped();
|
bool stoped() {
|
||||||
|
return _timer->stoped();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The destructor stops the delayed
|
* The destructor stops the delayed
|
||||||
*/
|
*/
|
||||||
~delayed();
|
~delayed() {
|
||||||
|
stop();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
shared_ptr<periodic> Periodic(function<void()> callback, uint64_t time);
|
|
||||||
shared_ptr<delayed> Delayed(function<void()> callback, uint64_t time);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef _ASYNCO_TRIGGER_
|
#ifndef _TRIGGER_
|
||||||
#define _ASYNCO_TRIGGER_
|
#define _TRIGGER_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#include "engine.hpp"
|
#include "asynco.hpp"
|
||||||
namespace marcelb {
|
namespace marcelb {
|
||||||
namespace asynco {
|
namespace asynco {
|
||||||
namespace triggers {
|
namespace triggers {
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
#include "../lib/engine.hpp"
|
|
||||||
|
|
||||||
namespace marcelb::asynco {
|
|
||||||
|
|
||||||
Engine _asynco_engine;
|
|
||||||
|
|
||||||
};
|
|
145
src/timers.cpp
145
src/timers.cpp
@ -1,145 +0,0 @@
|
|||||||
#include "../lib/timers.hpp"
|
|
||||||
|
|
||||||
namespace marcelb::asynco {
|
|
||||||
|
|
||||||
int64_t rtime_ms() {
|
|
||||||
return chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now()
|
|
||||||
.time_since_epoch())
|
|
||||||
.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t rtime_us() {
|
|
||||||
return chrono::duration_cast<chrono::microseconds>(chrono::system_clock::now()
|
|
||||||
.time_since_epoch())
|
|
||||||
.count();
|
|
||||||
}
|
|
||||||
|
|
||||||
void timer::init() {
|
|
||||||
st.async_wait( [this] (const boost::system::error_code&) {
|
|
||||||
if (!_stop) {
|
|
||||||
callback();
|
|
||||||
if (repeate) {
|
|
||||||
st = boost::asio::steady_timer(_asynco_engine.io_context, boost::asio::chrono::milliseconds(time));
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
_ticks++;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
timer::timer (function<void()> _callback, uint64_t _time, bool _repeate) :
|
|
||||||
st(_asynco_engine.io_context, boost::asio::chrono::milliseconds(_time)),
|
|
||||||
_stop(false),
|
|
||||||
repeate(_repeate),
|
|
||||||
callback(_callback),
|
|
||||||
time(_time) {
|
|
||||||
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
|
|
||||||
void timer::stop() {
|
|
||||||
_stop = true;
|
|
||||||
st.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
void timer::now() {
|
|
||||||
st.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t timer::ticks() {
|
|
||||||
return _ticks;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool timer::stoped() {
|
|
||||||
return _stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
timer::~timer() {
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
periodic::periodic(function<void()> callback, uint64_t time) :
|
|
||||||
_timer(make_shared<timer> (callback, time, true)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void periodic::stop() {
|
|
||||||
_timer->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void periodic::now() {
|
|
||||||
_timer->now();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint64_t periodic::ticks() {
|
|
||||||
return _timer->ticks();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool periodic::stoped() {
|
|
||||||
return _timer->stoped();
|
|
||||||
}
|
|
||||||
|
|
||||||
periodic::~periodic() {
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
delayed::delayed(function<void()> callback, uint64_t time) :
|
|
||||||
_timer(make_shared<timer> (callback, time, false)) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void delayed::stop() {
|
|
||||||
_timer->stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void delayed::now() {
|
|
||||||
_timer->now();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool delayed::expired() {
|
|
||||||
return bool(_timer->ticks());
|
|
||||||
}
|
|
||||||
|
|
||||||
bool delayed::stoped() {
|
|
||||||
return _timer->stoped();
|
|
||||||
}
|
|
||||||
|
|
||||||
delayed::~delayed() {
|
|
||||||
stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
mutex p_io, d_io;
|
|
||||||
vector<shared_ptr<periodic>> periodic_calls_container;
|
|
||||||
vector<shared_ptr<delayed>> delayed_calls_container;
|
|
||||||
|
|
||||||
shared_ptr<periodic> Periodic(function<void()> callback, uint64_t time) {
|
|
||||||
shared_ptr<periodic> periodic_ptr(make_shared<periodic>(callback, time));
|
|
||||||
async_ ( [&, periodic_ptr](){
|
|
||||||
lock_guard<mutex> lock(p_io);
|
|
||||||
periodic_calls_container.push_back(periodic_ptr);
|
|
||||||
for (uint32_t i=0; i<periodic_calls_container.size(); i++) {
|
|
||||||
if (periodic_calls_container[i]->stoped()) {
|
|
||||||
periodic_calls_container.erase(periodic_calls_container.begin()+i);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return periodic_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
shared_ptr<delayed> Delayed(function<void()> callback, uint64_t time) {
|
|
||||||
shared_ptr<delayed> delayed_ptr(make_shared<delayed>(callback, time));
|
|
||||||
async_ ( [&, delayed_ptr](){
|
|
||||||
lock_guard<mutex> lock(p_io);
|
|
||||||
delayed_calls_container.push_back(delayed_ptr);
|
|
||||||
for (uint32_t i=0; i<delayed_calls_container.size(); i++) {
|
|
||||||
if (delayed_calls_container[i]->stoped() || delayed_calls_container[i]->expired()) {
|
|
||||||
delayed_calls_container.erase(delayed_calls_container.begin()+i);
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return delayed_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
};
|
|
@ -1,4 +0,0 @@
|
|||||||
add_executable(asynco_test main.cpp)
|
|
||||||
|
|
||||||
# Linkaj test sa Asynco bibliotekom
|
|
||||||
target_link_libraries(asynco_test asynco Boost::system)
|
|
@ -1,10 +1,10 @@
|
|||||||
#define NUM_OF_RUNNERS 4
|
// // #define NUM_OF_RUNNERS 2
|
||||||
|
|
||||||
#include "asynco.hpp"
|
#include "../lib/asynco.hpp"
|
||||||
#include "trigger.hpp"
|
#include "../lib/trigger.hpp"
|
||||||
#include "filesystem.hpp"
|
#include "../lib/filesystem.hpp"
|
||||||
#include "timers.hpp"
|
#include "../lib/timers.hpp"
|
||||||
#include "define.hpp"
|
#include "../lib/define.hpp"
|
||||||
|
|
||||||
using namespace marcelb::asynco;
|
using namespace marcelb::asynco;
|
||||||
using namespace triggers;
|
using namespace triggers;
|
||||||
@ -62,37 +62,6 @@ class myOwnClass : public trigger<int> {
|
|||||||
myOwnClass() : trigger() {};
|
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 () {
|
int main () {
|
||||||
|
|
||||||
@ -100,9 +69,9 @@ int main () {
|
|||||||
|
|
||||||
// --------------- TIME ASYNCHRONOUS FUNCTIONS --------------
|
// --------------- TIME ASYNCHRONOUS FUNCTIONS --------------
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Init periodic and delayed; clear periodic and delayed
|
// * Init periodic and delayed; clear periodic and delayed
|
||||||
*/
|
// */
|
||||||
|
|
||||||
// periodic inter1 ([&]() {
|
// periodic inter1 ([&]() {
|
||||||
// cout << "periodic prvi " << rtime_ms() - start << endl;
|
// cout << "periodic prvi " << rtime_ms() - start << endl;
|
||||||
@ -160,30 +129,11 @@ int main () {
|
|||||||
// cout << "nije isteko " << endl;
|
// cout << "nije isteko " << endl;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// auto d = Delayed( [](){
|
// // // ------------------------ MAKE FUNCTIONS ASYNCHRONOUS -------------------------
|
||||||
// cout << "Delayed" << endl;
|
|
||||||
// }, 2000);
|
|
||||||
|
|
||||||
// auto p = Periodic( [](){
|
// /**
|
||||||
// cout << "Periodic" << endl;
|
// * Run an function asyncronic
|
||||||
// }, 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_ ( []() {
|
// async_ ( []() {
|
||||||
// sleep_for(2s); // only for simulate log duration function
|
// sleep_for(2s); // only for simulate log duration function
|
||||||
@ -205,13 +155,13 @@ int main () {
|
|||||||
// );
|
// );
|
||||||
|
|
||||||
|
|
||||||
// // async(launch::async, [] () {
|
// async(launch::async, [] () {
|
||||||
// // cout << "Another thread in async style!" << endl;
|
// cout << "Another thread in async style!" << endl;
|
||||||
// // });
|
// });
|
||||||
|
|
||||||
// // /**
|
// /**
|
||||||
// // * Call class method
|
// * Call class method
|
||||||
// // */
|
// */
|
||||||
|
|
||||||
// clm classes;
|
// clm classes;
|
||||||
// async_ ( [&classes] () {
|
// async_ ( [&classes] () {
|
||||||
@ -220,17 +170,17 @@ int main () {
|
|||||||
|
|
||||||
// sleep(5);
|
// sleep(5);
|
||||||
|
|
||||||
// // /**
|
// /**
|
||||||
// // * await_ after runned as async
|
// * await_ after runned as async
|
||||||
// // */
|
// */
|
||||||
|
|
||||||
// auto aa = async_ ( []() {
|
// auto a = async_ ( []() {
|
||||||
// sleep_for(2s); // only for simulate log duration function
|
// sleep_for(2s); // only for simulate log duration function
|
||||||
// cout << "async_ 2" << endl;
|
// cout << "async_ 2" << endl;
|
||||||
// return 5;
|
// return 5;
|
||||||
// });
|
// });
|
||||||
|
|
||||||
// cout << await_(aa) << endl;
|
// cout << await_(a) << endl;
|
||||||
// cout << "print after async_ 2" << endl;
|
// cout << "print after async_ 2" << endl;
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
@ -321,19 +271,17 @@ int main () {
|
|||||||
// );
|
// );
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// auto await_all2 = [&] () {
|
// auto await_all = [&] () {
|
||||||
// for (int i=0; i<fut_vec.size(); i++) {
|
// for (int i=0; i<fut_vec.size(); i++) {
|
||||||
// await_ (fut_vec[i]);
|
// await_ (fut_vec[i]);
|
||||||
// }
|
// }
|
||||||
// };
|
// };
|
||||||
|
|
||||||
// await_all2();
|
// --------------- EVENTS -------------------
|
||||||
|
|
||||||
// // --------------- EVENTS -------------------
|
/**
|
||||||
|
* initialization of typed events
|
||||||
// /**
|
*/
|
||||||
// * initialization of typed events
|
|
||||||
// */
|
|
||||||
|
|
||||||
// trigger<int, int> ev2int;
|
// trigger<int, int> ev2int;
|
||||||
// trigger<int, string> evintString;
|
// trigger<int, string> evintString;
|
||||||
@ -398,24 +346,6 @@ int main () {
|
|||||||
// cout << "Constructed " << i << endl;
|
// 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");
|
// auto status = fs::read("test1.txt");
|
Loading…
x
Reference in New Issue
Block a user