# HG changeset patch # User David Demelier # Date 1464788482 -7200 # Node ID 409cf1aa4af96a31c05aa254315e9200ed827a5e # Parent d89a5e9e5fa7d4f1f97ac3ad21454d194f9969b6 Timer: add experimental threaded timers diff -r d89a5e9e5fa7 -r 409cf1aa4af9 modules/timer/timer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/timer/timer.cpp Wed Jun 01 15:41:22 2016 +0200 @@ -0,0 +1,85 @@ +#include + +#include "timer.hpp" + +void Timer::call() +{ + if (m_alive && m_handler) + m_handler(); +} + +void Timer::wait() +{ + std::unique_lock lock(m_mutex); + + m_condition.wait_for(lock, std::chrono::milliseconds(m_delay), [&] () { + return static_cast(!m_alive); + }); +} + +void Timer::runOne() +{ + wait(); + call(); +} + +void Timer::runForever() +{ + while (m_alive) { + wait(); + call(); + } +} + +void Timer::start() +{ + assert(!m_thread.joinable()); + + m_alive = true; + + if (m_type == Single) + m_thread = std::thread(std::bind(&Timer::runOne, this)); + else + m_thread = std::thread(std::bind(&Timer::runForever, this)); +} + +void Timer::stop() +{ + if (m_thread.joinable()) { + m_alive = false; + m_condition.notify_one(); + m_thread.join(); + } +} + + + + + + + + +#include + +int main() +{ + Timer timer(Timer::Repeat, 500); + + timer.setHandler([] () { std::puts("tu me chatouilles"); }); + auto f = std::move(timer.handler()); + timer.setHandler([&] () { + std::puts("preums"); + f(); + }); + timer.start(); + + std::this_thread::sleep_for(std::chrono::seconds(2)); + std::puts("Je coupe le son..."); + timer.stop(); + std::this_thread::sleep_for(std::chrono::seconds(5)); + std::puts("Je remets le son..."); + timer.start(); + std::this_thread::sleep_for(std::chrono::seconds(2)); + + return 0; +} \ No newline at end of file diff -r d89a5e9e5fa7 -r 409cf1aa4af9 modules/timer/timer.hpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/modules/timer/timer.hpp Wed Jun 01 15:41:22 2016 +0200 @@ -0,0 +1,65 @@ +#ifndef TIMER_HPP +#define TIMER_HPP + +#include +#include +#include +#include +#include +#include +#include + +class Timer { +public: + enum Type { + Repeat, + Single + }; + +private: + Type m_type; + std::atomic m_alive{true}; + std::thread m_thread; + std::mutex m_mutex; + std::condition_variable m_condition; + std::function m_handler; + std::uint32_t m_delay; + + void call(); + void wait(); + void runOne(); + void runForever(); + +public: + inline Timer(Type type, std::uint32_t delay) noexcept + : m_type(type) + , m_delay(delay) + { + } + + inline ~Timer() + { + stop(); + } + + inline const std::function &handler() const noexcept + { + return m_handler; + } + + inline std::function &handler() noexcept + { + return m_handler; + } + + inline void setHandler(std::function handler) + { + m_handler = std::move(handler); + } + + void start(); + + void stop(); +}; + +#endif // !TIMER_HPP \ No newline at end of file