Timer.h 2.4 KB

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