| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- #ifndef UTIL_TIMER_H
- #define UTIL_TIMER_H
- #include <atomic>
- #include <condition_variable>
- #include <functional>
- #include <mutex>
- #include <thread>
- #include "Helpers.h"
- namespace PresenceDetection {
- namespace Util {
- class Timer
- {
- public:
- Timer();
- ~Timer();
- Timer(const Timer&) = delete;
- Timer& operator= (const Timer&) = delete;
- Timer(Timer&& other);
- Timer& operator= (Timer&& other);
- bool operator==(const Timer& other) const;
- bool operator==(const std::string& identifier) const;
- bool operator==(bool running) const;
- public:
- std::string Identifier() const;
- template <typename ...FunctionArguments, typename ...Arguments>
- void StartSingle(int milliSeconds, std::function<void(FunctionArguments...)> const & function, Arguments && ...arguments)
- {
- Start(TimerType::Single, milliSeconds, function, std::forward<Arguments>(arguments)...);
- }
- template <typename ...FunctionArguments, typename ...Arguments>
- void StartContinuous(int milliSeconds, std::function<void(FunctionArguments...)> const & function, Arguments && ...arguments)
- {
- Start(TimerType::Continuous, milliSeconds, function, std::forward<Arguments>(arguments)...);
- }
- void Stop();
- void Abort();
- bool IsRunning() const noexcept;
- void Wait();
- private:
- class TimerType
- {
- public:
- enum type
- {
- Unknown,
- Single,
- Continuous
- };
- };
- private:
- template <typename ...FunctionArguments, typename ...Arguments>
- void Start(TimerType::type type, int milliSeconds, std::function<void(FunctionArguments...)> const & function, Arguments && ...arguments)
- {
- if (type == TimerType::Unknown)
- return;
- if (m_run.load(std::memory_order_acquire))
- Stop();
- m_thread = std::thread([this, type, milliSeconds, function, &arguments...]()
- {
- auto argumentsCopy = std::make_tuple(std::forward<Arguments>(arguments)...);
- m_run.store(true, std::memory_order_release);
- m_aborted = false;
- while (m_run.load(std::memory_order_acquire))
- {
- std::unique_lock<std::mutex> lock(m_mutex);
- if (!m_conditionVariable.wait_for(lock, std::chrono::milliseconds(milliSeconds), [&]{return m_aborted;}))
- {
- Helpers::execute(function, argumentsCopy);
- if (type == TimerType::Single)
- m_run.store(false, std::memory_order_release);
- }
- }
- });
- while (!IsRunning())
- {
- }
- }
- private:
- std::atomic<bool> m_run;
- bool m_aborted;
- std::mutex m_mutex;
- std::condition_variable m_conditionVariable;
- std::string m_identifier;
- std::thread m_thread;
- };
- } // namespace Util
- } // namespace PresenceDetection
- #endif // UTIL_TIMER_H
|