Snippets

Amin Ahmadi Pure C++11 Generic Timer Class

Created by Amin Ahmadi last modified
#include "timer.hpp"

Timer::Timer(const std::chrono::milliseconds &interval,
             const std::function<void ()> &task,
             bool singleShot)
    : mInterval(interval),
      mTask(task),
      mSingleShot(singleShot),
      mRunning(false)
{
}

Timer::~Timer()
{
    Stop();
}

bool Timer::IsRunning() const
{
    return mRunning;
}

void Timer::Start()
{
    Stop();

    mRunning = true;
    mThread = std::thread([this]
    {
        while (mRunning)
        {
            std::unique_lock<std::mutex> lock(mRunCondMutex);
            auto waitResult = mRunCondition.wait_for(lock, mInterval, [this]{ return !mRunning; });
            if (mRunning && !waitResult)
                mTask();

            if(mSingleShot)
                mRunning = false;
        }
    });
}

void Timer::SetSingleShot(bool enabled)
{
    mSingleShot = enabled;
}

void Timer::Stop()
{
    std::unique_lock<std::mutex> lock(mStopMutex);
    mRunning = false;
    mRunCondition.notify_all();
    if(mThread.joinable())
        mThread.join();
}
#ifndef TIMER_H
#define TIMER_H

#include <chrono>
#include <functional>
#include <atomic>
#include <thread>
#include <condition_variable>

class Timer
{

public:
    Timer(const std::chrono::milliseconds &interval,
          const std::function<void ()> &task,
          bool singleShot);
    ~Timer();

    void Start();
    void Stop();
    void SetSingleShot(bool enabled = true);
    bool IsRunning() const;

private:
    std::chrono::milliseconds mInterval;
    std::function<void ()> mTask;
    std::atomic_bool mSingleShot;
    std::atomic_bool mRunning;
    std::condition_variable mRunCondition;
    std::mutex mRunCondMutex;
    std::thread mThread;
    std::mutex mStopMutex;

};

#endif // TIMER_H

Comments (0)