I need to create a class to replicate the functionality of a callback timer from a library I no longer have access to.
Basically, spawn an asynchronous thread that executes some function after a timeout is reached. However, if some condition is met before the timeout, the function is not executed, and the timer is cancelled.
I am not sure how to "stop" the timer based on some condition.
This is what I have so far (based on the answer to this post C++ Non-blocking async timer by wally)
#include <iostream>
#include <chrono>
#include <thread>
#include <functional>
#include <mutex>
#include <condition_variable>
class Timer 
{
public:
   Timer(size_t time, const std::function<void(void)>& callback) : 
      time(std::chrono::milliseconds(time)),
      callback(callback) {}
   ~Timer() 
   { 
      if (started) 
      { 
         wait_thread.join(); 
         started = false; 
      } 
   }
   // TODO: Implement stop()
   void stop()
   {
      // ???
   }
   // TODO: Implement start()
   void start()
   {
      if (!started)
      {
         started = true;
         wait_thread = std::thread{ [this]() { wait_then_call(); } };
      }
      else
      {
         std::cout << "Thread " << wait_thread.get_id() << " already been started! " << std::endl;
      }
   }
private:
   void wait_then_call()
   {
      std::unique_lock<std::mutex> lck(mtx);
      for (int i = 10; i > 0; --i)
      {
         std::cout << "Thread " << wait_thread.get_id() << " countdown at: " << '\t' << i << std::endl;
         cv.wait_for(lck, time / 10);
      }
      callback();
   }
   std::mutex mtx;
   std::condition_variable cv{};
   std::chrono::milliseconds time;
   std::function <void(void)> callback;
   std::thread wait_thread;
   bool started = false;
};
Testing:
int main()
{
   auto f = []() {std::cout << "Executing Callback Function"; };
   Timer t1{ 3000, f };
   t1.start();
   Timer t2{ 10000, f };
   t2.start();
   // main thread is free to continue doing other things
}
Aucun commentaire:
Enregistrer un commentaire