/* * Copyright (C) 2014 Pavel Kirienko */ #pragma once #include #include #include #include #include namespace uavcan { class Timer; struct TimerEvent { MonotonicTime scheduled_deadline; MonotonicTime current_timestamp; Timer* timer; TimerEvent(Timer* timer, MonotonicTime scheduled_deadline, MonotonicTime current_timestamp) : scheduled_deadline(scheduled_deadline) , current_timestamp(current_timestamp) , timer(timer) { } }; class Timer : private DeadlineHandler { MonotonicDuration period_; void handleDeadline(MonotonicTime current_timestamp); public: using DeadlineHandler::stop; using DeadlineHandler::isRunning; using DeadlineHandler::getDeadline; using DeadlineHandler::getScheduler; explicit Timer(Scheduler& scheduler) : DeadlineHandler(scheduler) , period_(MonotonicDuration::getInfinite()) { } void startOneShotWithDeadline(MonotonicTime deadline); void startOneShotWithDelay(MonotonicDuration delay); void startPeriodic(MonotonicDuration period); MonotonicDuration getPeriod() const { return period_; } virtual void handleTimerEvent(const TimerEvent& event) = 0; }; template class TimerEventForwarder : public Timer { Callback callback_; public: explicit TimerEventForwarder(Scheduler& node) : Timer(node) , callback_() { } TimerEventForwarder(Scheduler& node, Callback callback) : Timer(node) , callback_(callback) { } const Callback& getCallback() const { return callback_; } void setCallback(const Callback& callback) { callback_ = callback; } void handleTimerEvent(const TimerEvent& event) { if (try_implicit_cast(callback_, true)) callback_(event); else handleFatalError("Invalid timer callback"); } }; }