Advertisement
Guest User

Untitled

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