Clear, work on interval and timeout

dev-own-engine
marcelb 7 months ago
parent 03b11840f4
commit d3c7b3a91b
  1. 0
      .gitignore
  2. 5
      .vscode/settings.json
  3. 164
      example/asynco.hpp
  4. 98
      lib/asynco.hpp
  5. 36
      lib/event.hpp
  6. 3
      lib/loop.hpp
  7. BIN
      test/test
  8. 66
      test/test.cpp

@ -22,6 +22,9 @@
"tuple": "cpp", "tuple": "cpp",
"type_traits": "cpp", "type_traits": "cpp",
"utility": "cpp", "utility": "cpp",
"future": "cpp" "future": "cpp",
"*.ipp": "cpp",
"bitset": "cpp",
"algorithm": "cpp"
} }
} }

@ -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

@ -12,12 +12,85 @@ namespace marcelb {
AsyncLoop on_async; AsyncLoop on_async;
#endif #endif
class interval;
class timeout;
class loop_core {
static vector<interval> intervals;
static vector<timeout> timeouts;
time_t sampling;
mutex i_m, t_m;
loop_core() {
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();
}
}
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 { class interval {
public:
bool run = true; bool run = true;
function<void()> callback; function<void()> callback;
const time_t _duration; const time_t _duration;
time_t execute = 0;
public: // public:
interval(function<void()> func, const time_t duration): callback(func), _duration(duration) { interval(function<void()> func, const time_t duration): callback(func), _duration(duration) {
#ifndef ON_ASYNC #ifndef ON_ASYNC
throw string("Not on_async defined!"); throw string("Not on_async defined!");
@ -25,14 +98,15 @@ class interval {
auto task = [&] () { auto task = [&] () {
while (run) { while (run) {
this_thread::sleep_for(chrono::milliseconds(_duration)); // this_thread::sleep_for(chrono::milliseconds(_duration));
if (run) { // if (run) {
callback(); callback();
} // }
} }
}; };
on_async.put_task(task); // on_async.put_task(task);
co_loop.run(this*);
} }
void clear() { void clear() {
@ -45,24 +119,32 @@ class interval {
}; };
class timeout { class timeout {
public:
bool run = true; bool run = true;
function<void()> callback; function<void()> callback;
const time_t _duration; const time_t _duration;
int64_t _construct =
chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch())
.count();
public: // public:
timeout(function<void()> f, const time_t duration): callback(f), _duration(duration) { timeout(function<void()> f, const time_t duration): callback(f), _duration(duration) {
#ifndef ON_ASYNC #ifndef ON_ASYNC
throw string("Not on_async defined!"); throw string("Not on_async defined!");
#endif #endif
auto task = [&] () { auto task = [&] () {
this_thread::sleep_for(chrono::milliseconds(_duration)); // 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) { if (run) {
callback(); callback();
} }
}; };
on_async.put_task(task); // on_async.put_task(task);
co_loop.run(this*);
} }
void clear() { void clear() {

@ -5,34 +5,38 @@
#include <map> #include <map>
#include <string> #include <string>
#include <functional> #include <functional>
#include "loop.hpp"
using namespace std; using namespace std;
namespace marcelb { namespace marcelb {
#ifndef ON_ASYNC
#define ON_ASYNC
AsyncLoop on_async;
#endif
template<typename... T>
class event { class event {
map<string, function<void(const tuple<>&)>> events; private:
public: unordered_map<string, function<void(T...)>> events;
template <typename... Args> public:
void on(const string& key, function<void(Args...)> f) { void on(const string& key, function<void(T...)> callback) {
// events[key] = [f](Args... args) { events[key] = callback;
// f(args...);
// };
} }
template<typename... Args> template<typename... Args>
void emit(const string& key, Args&&... args) { void emit(const string& key, Args... args) {
if (events.find(key) == events.end()) { auto it = events.find(key);
cout << "No defined listener for event: " << key << endl; if (it != events.end()) {
return; auto callback = bind(it->second, forward<Args>(args)...);
} on_async.put_task(callback);
else {
for (auto& func : events[key]) {
func(forward<Args>(args)...);
}
} }
} }
}; };
} }

@ -80,9 +80,10 @@ class AsyncLoop {
stop = true; stop = true;
} }
cv.notify_all(); cv.notify_all();
for (thread& worker : workers) for (thread& worker : workers) {
worker.join(); worker.join();
} }
}
}; };

Binary file not shown.

@ -1,7 +1,8 @@
#include "../lib/loop.hpp" // #include "../lib/loop.hpp"
#include "../lib/asynco.hpp" // #include "../lib/asynco.hpp"
// #include "../lib/event.hpp" // #include "../example/asynco.hpp"
#include "../lib/event.hpp"
#include <iostream> #include <iostream>
#include <unistd.h> #include <unistd.h>
@ -11,37 +12,37 @@ using namespace this_thread;
#ifndef ON_ASYNC #ifndef ON_ASYNC
#define ON_ASYNC #define ON_ASYNC
AsyncLoop on_async; AsyncLoop on_async(8);
#endif #endif
int main () { int main () {
auto start = chrono::high_resolution_clock::now(); // auto start = chrono::high_resolution_clock::now();
interval inter1 ([&]() { // interval inter1 ([&]() {
cout << "interval prvi " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl; // cout << "interval prvi " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl;
}, 1000); // }, 1000);
cout << "Blokira stoka" << endl; // interval inter2 ([&]() {
// cout << "interval drugi " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl;
// }, 2000);
interval inter2 ([&]() { // interval inter3 ([&]() {
cout << "interval drugi " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl; // cout << "interval treći " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl;
}, 2000); // }, 3000);
interval inter3 ([&]() { // timeout time1 ( [&] () {
cout << "interval treći " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl; // cout << "Close interval 1 i 2 " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl;
}, 3000); // inter1.clear();
// inter2.clear();
// }, 10000);
timeout time1 ( [&] () { // timeout time2 ([&] () {
cout << "Close interval 1 i 2 " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl; // cout << "Close interval 3 " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl;
inter1.clear(); // inter3.clear();
inter2.clear(); // }, 2000);
}, 10000);
timeout time2 ([&] () { // cout << "zadataka: " << on_async.count_tasks() << " niti: " << on_async.count_threads() << endl;
cout << "Close interval 3 " << chrono::duration_cast<chrono::milliseconds>(chrono::high_resolution_clock::now() - start).count() << endl;
inter3.clear();
}, 20000);
// for (int i = 0; i < 8; ++i) { // for (int i = 0; i < 8; ++i) {
@ -87,15 +88,24 @@ int main () {
// cout << wait(run1) << endl; // cout << wait(run1) << endl;
// event dog; // event<int, int> ev2int;
// event<int, string> evintString;
// dog.on("roge", [](int a, int b) { // ev2int.on("sum", [](int a, int b) {
// cout << "Rogeee" << a << b << endl; // cout << "Sum " << a+b << endl;
// });
// evintString.on("substract", [](int a, string b) {
// cout << "Substract " << a-stoi(b) << endl;
// }); // });
// sleep(5); // sleep(5);
// dog.emit("roge", 5, 8); // ev2int.emit("sum", 5, 8);
// sleep(2);
// evintString.emit("substract", 3, to_string(2));
sleep(1000); sleep(1000);

Loading…
Cancel
Save