| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- #ifndef TIMER_H
- #define TIMER_H
- #include "TimerHelpers.h"
- #include <atomic>
- #include <condition_variable>
- #include <functional>
- #include <memory>
- #include <mutex>
- #include <thread>
- namespace Timer {
- class Timer
- {
- public:
- Timer();
- ~Timer();
- Timer(const Timer&) = delete;
- Timer& operator= (const Timer&) = delete;
- bool operator==(const Timer& other) 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);
- }
- }
- });
- #ifdef __linux__
- pthread_setname_np(m_thread.native_handle(), "Timer");
- #endif
- 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;
- };
- typedef std::unique_ptr<Timer> TimerPointer;
- } // namespace Timer
- #endif // TIMER_H
|