Timer.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  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. bool operator==(bool running) const;
  21. public:
  22. std::string Identifier() const;
  23. template <typename ...FunctionArguments, typename ...Arguments>
  24. void StartSingle(int interval, std::function<void(FunctionArguments...)> const & function, Arguments && ...arguments)
  25. {
  26. Start(TimerType::Single, interval, function, std::forward<Arguments>(arguments)...);
  27. }
  28. template <typename ...FunctionArguments, typename ...Arguments>
  29. void StartContinuous(int interval, std::function<void(FunctionArguments...)> const & function, Arguments && ...arguments)
  30. {
  31. Start(TimerType::Continuous, interval, function, std::forward<Arguments>(arguments)...);
  32. }
  33. void Stop();
  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 interval, 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, interval, function, &arguments...]()
  56. {
  57. auto argumentsCopy = std::make_tuple(std::forward<Arguments>(arguments)...);
  58. m_run.store(true, std::memory_order_release);
  59. while (m_run.load(std::memory_order_acquire))
  60. {
  61. std::this_thread::sleep_for(std::chrono::milliseconds(interval));
  62. Helpers::execute(function, argumentsCopy);
  63. if (type == TimerType::Single)
  64. m_run.store(false, std::memory_order_release);
  65. }
  66. });
  67. while (!IsRunning())
  68. {
  69. }
  70. }
  71. private:
  72. std::atomic<bool> m_run;
  73. std::string m_identifier;
  74. std::thread m_thread;
  75. };
  76. } // namespace Util
  77. } // namespace PresenceDetection
  78. #endif // UTIL_TIMER_H