Timer.h 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #ifndef TIMER_H
  2. #define TIMER_H
  3. #include "TimerHelpers.h"
  4. #include <atomic>
  5. #include <condition_variable>
  6. #include <functional>
  7. #include <memory>
  8. #include <mutex>
  9. #include <thread>
  10. namespace Timer {
  11. class Timer
  12. {
  13. public:
  14. Timer();
  15. ~Timer();
  16. Timer(const Timer&) = delete;
  17. Timer& operator= (const Timer&) = delete;
  18. bool operator==(const Timer& other) const;
  19. public:
  20. std::string Identifier() const;
  21. template <typename ...FunctionArguments, typename ...Arguments>
  22. void StartSingle(int milliSeconds, std::function<void(FunctionArguments...)> const & function, Arguments && ...arguments)
  23. {
  24. Start(TimerType::Single, milliSeconds, function, std::forward<Arguments>(arguments)...);
  25. }
  26. template <typename ...FunctionArguments, typename ...Arguments>
  27. void StartContinuous(int milliSeconds, std::function<void(FunctionArguments...)> const & function, Arguments && ...arguments)
  28. {
  29. Start(TimerType::Continuous, milliSeconds, function, std::forward<Arguments>(arguments)...);
  30. }
  31. void Stop();
  32. void Abort();
  33. bool IsRunning() const noexcept;
  34. void Wait();
  35. private:
  36. class TimerType
  37. {
  38. public:
  39. enum type
  40. {
  41. Unknown,
  42. Single,
  43. Continuous
  44. };
  45. };
  46. private:
  47. template <typename ...FunctionArguments, typename ...Arguments>
  48. void Start(TimerType::type type, int milliSeconds, std::function<void(FunctionArguments...)> const & function, Arguments && ...arguments)
  49. {
  50. if (type == TimerType::Unknown)
  51. return;
  52. if (m_run.load(std::memory_order_acquire))
  53. Stop();
  54. m_thread = std::thread([this, type, milliSeconds, function, &arguments...]()
  55. {
  56. auto argumentsCopy = std::make_tuple(std::forward<Arguments>(arguments)...);
  57. m_run.store(true, std::memory_order_release);
  58. m_aborted = false;
  59. while (m_run.load(std::memory_order_acquire))
  60. {
  61. std::unique_lock<std::mutex> lock(m_mutex);
  62. if (!m_conditionVariable.wait_for(lock, std::chrono::milliseconds(milliSeconds), [&]{return m_aborted;}))
  63. {
  64. Helpers::execute(function, argumentsCopy);
  65. if (type == TimerType::Single)
  66. m_run.store(false, std::memory_order_release);
  67. }
  68. }
  69. });
  70. #ifdef __linux__
  71. pthread_setname_np(m_thread.native_handle(), "Timer");
  72. #endif
  73. while (!IsRunning())
  74. {
  75. }
  76. }
  77. private:
  78. std::atomic<bool> m_run;
  79. bool m_aborted;
  80. std::mutex m_mutex;
  81. std::condition_variable m_conditionVariable;
  82. std::string m_identifier;
  83. std::thread m_thread;
  84. };
  85. typedef std::unique_ptr<Timer> TimerPointer;
  86. } // namespace Timer
  87. #endif // TIMER_H