Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <atomic>
- #include <chrono>
- #include <condition_variable>
- #include <functional>
- #include <mutex>
- #include <thread>
- #include <utility>
- #include <vector>
- template<typename ... Args>
- class Signal
- {
- public:
- void connect(std::function<void(Args...)> slot)
- {
- if(slot) {
- m_slots.emplace_back(std::move(slot));
- }
- }
- void operator()(Args&&... args)
- {
- for(const auto& slot: m_slots) {
- slot(args...);
- }
- }
- private:
- std::vector<std::function<void(Args...)>> m_slots;
- };
- class Timer
- {
- public:
- using Interval = std::chrono::milliseconds;
- Signal<> timeout;
- Signal<> stopped;
- Timer() = default;
- Timer(const Timer&) = delete;
- Timer& operator=(const Timer&) = delete;
- ~Timer()
- {
- if(m_isActive) {
- // maybe log
- this->stop();
- }
- if(m_thread.joinable()){
- m_thread.join();
- }
- }
- Interval interval() const
- {
- return m_interval;
- }
- void setInterval(Interval interval)
- {
- m_interval = interval;
- }
- bool isSingleShot() const
- {
- return m_isSingleShot;
- }
- void setSingleShot(bool singleShot)
- {
- m_isSingleShot = singleShot;
- }
- void start(Interval msec)
- {
- this->setInterval(msec);
- this->start();
- }
- void start()
- {
- if(m_isActive) {
- this->stop();
- }
- m_isActive = true;
- m_thread = std::thread([this]()
- {
- while(m_isActive)
- {
- std::unique_lock<std::mutex> lk(m_mutex);
- m_condition.wait_for(lk, m_interval, [this]{ return !m_isActive;});
- if(m_isActive) // If timer was not stopped prematurely, emit timeout signal
- {
- timeout();
- m_isActive = !m_isSingleShot;
- }
- }
- });
- }
- void stop()
- {
- if(m_isActive)
- {
- m_isActive = false;
- m_condition.notify_all();
- if(m_thread.joinable()){
- m_thread.join();
- }
- stopped();
- }
- }
- bool isActive() const
- {
- return m_isActive;
- }
- private:
- std::atomic_bool m_isActive = {false};
- std::atomic_bool m_isSingleShot = {false};
- std::condition_variable m_condition;
- std::mutex m_mutex;
- std::thread m_thread;
- Interval m_interval;
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement