parent
03b11840f4
commit
d3c7b3a91b
@ -0,0 +1,164 @@ |
||||
#ifndef _ASYNCO_ |
||||
#define _ASYNCO_ |
||||
|
||||
#include <vector> |
||||
#include <mutex> |
||||
#include <future> |
||||
#include <thread> |
||||
|
||||
using namespace std; |
||||
|
||||
namespace marcelb { |
||||
|
||||
class interval; |
||||
class timeout; |
||||
|
||||
class loop_core { |
||||
vector<interval> intervals; |
||||
vector<timeout> timeouts; |
||||
time_t sampling; |
||||
mutex i_m, t_m; |
||||
future<void> bot; |
||||
|
||||
loop_core() { |
||||
bot = async(launch::async, [this] () { |
||||
loop(); |
||||
}); |
||||
// on_async.put_task( [this] () {
|
||||
// loop();
|
||||
// });
|
||||
} |
||||
|
||||
void run(interval& _interval) { |
||||
lock_guard<mutex> lock(i_m); |
||||
intervals.push_back(_interval); |
||||
update_sampling(); |
||||
} |
||||
|
||||
void run(timeout& _timeout) { |
||||
lock_guard<mutex> lock(t_m); |
||||
timeouts.push_back(_timeout); |
||||
update_sampling(); |
||||
} |
||||
|
||||
void loop() { |
||||
while (true) { |
||||
for (auto& _interval : intervals) { |
||||
int64_t now = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count(); |
||||
if (now - _interval.execute >= _interval._duration) { |
||||
_interval.callback(); |
||||
_interval.execute = now; |
||||
} |
||||
} |
||||
|
||||
for (int i=0; i<timeouts.size(); i++) { |
||||
int64_t now = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count(); |
||||
if (now - timeouts[i]._construct >= timeouts[i]._duration) { |
||||
auto& _timeout = timeouts[i]; |
||||
{ |
||||
lock_guard<mutex> lock(t_m); |
||||
timeouts.erase(timeouts.begin() + i); |
||||
} |
||||
_timeout.callback(); |
||||
} |
||||
} |
||||
this_thread::sleep_for(chrono::milliseconds(sampling)); |
||||
} |
||||
} |
||||
|
||||
void update_sampling() { |
||||
sampling = 0; |
||||
for (auto& _interval : intervals) { |
||||
sampling += _interval._duration; |
||||
} |
||||
for (auto& _timeout : timeouts) { |
||||
sampling += _timeout._duration; |
||||
} |
||||
sampling /= (intervals.size() + timeouts.size())*2; |
||||
} |
||||
|
||||
|
||||
}; |
||||
|
||||
loop_core co_loop; |
||||
|
||||
|
||||
|
||||
|
||||
class interval { |
||||
public: |
||||
bool run = true; |
||||
function<void()> callback; |
||||
const time_t _duration; |
||||
time_t execute = 0; |
||||
|
||||
// public:
|
||||
interval(function<void()> func, const time_t duration): callback(func), _duration(duration) { |
||||
#ifndef ON_ASYNC |
||||
throw string("Not on_async defined!"); |
||||
#endif |
||||
|
||||
auto task = [&] () { |
||||
while (run) { |
||||
// this_thread::sleep_for(chrono::milliseconds(_duration));
|
||||
// if (run) {
|
||||
callback(); |
||||
// }
|
||||
} |
||||
}; |
||||
|
||||
// on_async.put_task(task);
|
||||
co_loop.run(this*); |
||||
} |
||||
|
||||
void clear() { |
||||
run = false; |
||||
} |
||||
|
||||
~interval() { |
||||
clear(); |
||||
} |
||||
}; |
||||
|
||||
class timeout { |
||||
public: |
||||
bool run = true; |
||||
function<void()> callback; |
||||
const time_t _duration; |
||||
int64_t _construct = |
||||
chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()) |
||||
.count(); |
||||
|
||||
// public:
|
||||
timeout(function<void()> f, const time_t duration): callback(f), _duration(duration) { |
||||
#ifndef ON_ASYNC |
||||
throw string("Not on_async defined!"); |
||||
#endif |
||||
|
||||
auto task = [&] () { |
||||
// int64_t _start =
|
||||
// chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch())
|
||||
// .count();
|
||||
// this_thread::sleep_for(chrono::milliseconds(_duration - (_start - _construct)));
|
||||
if (run) { |
||||
callback(); |
||||
} |
||||
}; |
||||
|
||||
// on_async.put_task(task);
|
||||
co_loop.run(this*); |
||||
} |
||||
|
||||
void clear() { |
||||
run = false; |
||||
} |
||||
|
||||
~timeout() { |
||||
clear(); |
||||
} |
||||
}; |
||||
|
||||
|
||||
} |
||||
|
||||
#endif |
Loading…
Reference in new issue