Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // timer.hpp
- #include <functional>
- #include <vector>
- #include <chrono>
- #include <thread>
- #include <mutex>
- #include <iostream>
- #define SYSTEM_CLOCK std::chrono::system_clock
- class Timer {
- private:
- std::function<void(void *)> _callback;
- uint8_t _stopped;
- uint8_t _done;
- void* _state;
- uint64_t _delayMS;
- std::chrono::nanoseconds _acc;
- std::chrono::time_point<SYSTEM_CLOCK> _lastUpdate = SYSTEM_CLOCK::now();
- public:
- Timer( uint64_t delayMS, const std::function<void(void *)> callback, void* state);
- public:
- void start();
- void stop();
- private:
- void update();
- private:
- static std::vector<Timer*> __timers;
- static uint64_t __timer_state;
- static std::thread __timer_worker_thread;
- static std::mutex __timer_sync_root;
- private:
- static void enqueue_timer(Timer *timer);
- public:
- static void init(uint64_t delayMS);
- static void signalAppStopped();
- };
- // timer.cpp
- #include "timer.hpp"
- // instance part start
- Timer::Timer(uint64_t delayMS, const std::function<void(void *)> callback, void *state){
- _stopped = 1;
- _done = 0;
- _callback = callback;
- _state = state;
- _delayMS = delayMS;
- _lastUpdate = std::chrono::system_clock::now();
- _acc = std::chrono::milliseconds(0);
- enqueue_timer(this);
- }
- void Timer::start() { _stopped = 0; }
- void Timer::stop() { _stopped = 1; }
- void Timer::update() {
- auto temp = _lastUpdate;
- _lastUpdate = std::chrono::system_clock::now();
- if (_done == 1)
- return;
- if (_stopped == 0) {
- auto now = std::chrono::system_clock::now();
- auto delta = std::chrono::duration_cast<std::chrono::milliseconds>(now - temp);
- _acc = std::chrono::duration_cast<std::chrono::milliseconds>(_acc + delta);
- auto delayMS = std::chrono::milliseconds(_delayMS);
- if (delayMS <= _acc) {
- _done = 1;
- _callback(_state);
- }
- }
- }
- // instance part end
- // static part start
- std::vector<Timer *> Timer::__timers;
- uint64_t Timer::__timer_state;
- std::thread Timer::__timer_worker_thread;
- std::mutex Timer::__timer_sync_root;
- void Timer::init(uint64_t delayMS) {
- __timer_state = 0;
- __timer_worker_thread = std::thread( [=] () {
- while (__timer_state == 0) {
- __timer_sync_root.lock();
- for(auto it = __timers.begin(); it != __timers.end(); ++it) {
- auto timer = *it;
- if(timer->_done == 1){
- delete timer;
- __timers.erase(it);
- }
- }
- for(auto i = 0; i < __timers.size(); i++) {
- auto timer = __timers[i];
- timer->update();
- }
- __timer_sync_root.unlock();
- std::this_thread::sleep_for(std::chrono::milliseconds(delayMS));
- }
- });
- }
- void Timer::enqueue_timer(Timer *timer) {
- __timer_sync_root.lock();
- __timers.push_back(timer);
- __timer_sync_root.unlock();
- }
- void Timer::signalAppStopped() {
- __timer_state = 1;
- __timer_worker_thread.join();
- }
- // static part end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement