Advertisement
Guest User

Untitled

a guest
Jun 1st, 2024
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.23 KB | None | 0 0
  1. // timer.hpp
  2.  
  3. #include <functional>
  4. #include <vector>
  5. #include <chrono>
  6. #include <thread>
  7. #include <mutex>
  8. #include <iostream>
  9.  
  10. #define SYSTEM_CLOCK std::chrono::system_clock
  11.  
  12. class Timer {
  13. private:
  14.     std::function<void(void *)> _callback;
  15.     uint8_t                     _stopped;
  16.     uint8_t                     _done;
  17.     void*                       _state;
  18.     uint64_t                    _delayMS;
  19.     std::chrono::nanoseconds    _acc;
  20.     std::chrono::time_point<SYSTEM_CLOCK> _lastUpdate = SYSTEM_CLOCK::now();
  21.  
  22. public:
  23.     Timer( uint64_t delayMS, const std::function<void(void *)> callback, void* state);
  24.  
  25. public:
  26.     void start();
  27.     void stop();
  28.  
  29. private:
  30.     void update();
  31.  
  32. private:
  33.     static std::vector<Timer*>  __timers;
  34.     static uint64_t             __timer_state;
  35.     static std::thread          __timer_worker_thread;
  36.     static std::mutex           __timer_sync_root;
  37.  
  38. private:
  39.     static void enqueue_timer(Timer *timer);
  40.  
  41. public:
  42.     static void init(uint64_t delayMS);
  43.     static void signalAppStopped();
  44. };
  45.  
  46.  
  47. // timer.cpp
  48.  
  49. #include "timer.hpp"
  50.  
  51. // instance part start
  52.  
  53. Timer::Timer(uint64_t delayMS, const std::function<void(void *)> callback, void *state){
  54.     _stopped = 1;
  55.     _done = 0;
  56.     _callback = callback;
  57.     _state = state;
  58.     _delayMS = delayMS;
  59.     _lastUpdate = std::chrono::system_clock::now();
  60.     _acc = std::chrono::milliseconds(0);
  61.     enqueue_timer(this);
  62. }
  63.  
  64. void Timer::start() { _stopped = 0; }
  65. void Timer::stop() { _stopped = 1; }
  66.  
  67. void Timer::update() {
  68.     auto temp = _lastUpdate;
  69.     _lastUpdate = std::chrono::system_clock::now();
  70.     if (_done == 1)
  71.         return;
  72.     if (_stopped == 0) {
  73.  
  74.         auto now = std::chrono::system_clock::now();
  75.         auto delta = std::chrono::duration_cast<std::chrono::milliseconds>(now - temp);
  76.         _acc = std::chrono::duration_cast<std::chrono::milliseconds>(_acc + delta);
  77.  
  78.         auto delayMS = std::chrono::milliseconds(_delayMS);
  79.         if (delayMS <= _acc) {
  80.             _done = 1;
  81.             _callback(_state);
  82.         }
  83.     }
  84. }
  85.  
  86. // instance part end
  87.  
  88.  
  89. // static part start
  90.  
  91. std::vector<Timer *> Timer::__timers;
  92. uint64_t Timer::__timer_state;
  93. std::thread Timer::__timer_worker_thread;
  94. std::mutex Timer::__timer_sync_root;
  95.  
  96. void Timer::init(uint64_t delayMS) {
  97.     __timer_state = 0;
  98.     __timer_worker_thread = std::thread( [=] () {
  99.         while (__timer_state == 0) {                
  100.         __timer_sync_root.lock();
  101.  
  102.         for(auto it = __timers.begin(); it != __timers.end(); ++it) {
  103.             auto timer = *it;
  104.             if(timer->_done == 1){
  105.             delete timer;
  106.             __timers.erase(it);
  107.             }
  108.         }
  109.        
  110.         for(auto i = 0; i < __timers.size(); i++) {
  111.             auto timer = __timers[i];
  112.             timer->update();
  113.         }
  114.        
  115.         __timer_sync_root.unlock();
  116.         std::this_thread::sleep_for(std::chrono::milliseconds(delayMS));
  117.         }
  118.     });
  119. }
  120.  
  121. void Timer::enqueue_timer(Timer *timer) {
  122.     __timer_sync_root.lock();
  123.     __timers.push_back(timer);
  124.     __timer_sync_root.unlock();
  125. }
  126.  
  127. void Timer::signalAppStopped() {
  128.     __timer_state = 1;
  129.     __timer_worker_thread.join();
  130. }
  131.  
  132. // static part end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement