Timer.h 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. #ifndef UTIL_TIMER_H
  2. #define UTIL_TIMER_H
  3. #include <atomic>
  4. #include <functional>
  5. #include <thread>
  6. #include "Helpers.h"
  7. namespace PresenceDetection {
  8. namespace Util {
  9. class Timer
  10. {
  11. public:
  12. Timer();
  13. ~Timer();
  14. Timer(const Timer&) = delete;
  15. Timer& operator= (const Timer&) = delete;
  16. Timer(Timer&& other);
  17. Timer& operator= (Timer&& other);
  18. bool operator==(const Timer& other) const;
  19. bool operator==(const std::string& identifier) const;
  20. public:
  21. std::string Identifier() const;
  22. template <typename ...FunctionArguments, typename ...Arguments>
  23. void StartSingle(int interval, std::function<void(FunctionArguments...)> const & function, Arguments && ...arguments)
  24. {
  25. Start(TimerType::Single, interval, function, std::forward<Arguments>(arguments)...);
  26. }
  27. template <typename ...FunctionArguments, typename ...Arguments>
  28. void StartContinuous(int interval, std::function<void(FunctionArguments...)> const & function, Arguments && ...arguments)
  29. {
  30. Start(TimerType::Continuous, interval, function, std::forward<Arguments>(arguments)...);
  31. }
  32. void Stop();
  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 interval, 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, interval, function, &arguments...]()
  55. {
  56. auto argumentsCopy = std::make_tuple(std::forward<Arguments>(arguments)...);
  57. m_run.store(true, std::memory_order_release);
  58. while (m_run.load(std::memory_order_acquire))
  59. {
  60. std::this_thread::sleep_for(std::chrono::milliseconds(interval));
  61. Helpers::execute(function, argumentsCopy);
  62. if (TimerType::Single)
  63. m_run.store(false, std::memory_order_release);
  64. }
  65. });
  66. while (!IsRunning())
  67. {
  68. }
  69. }
  70. private:
  71. std::atomic<bool> m_run;
  72. std::string m_identifier;
  73. std::thread m_thread;
  74. };
  75. } // namespace Util
  76. } // namespace PresenceDetection
  77. #endif // UTIL_TIMER_H