libuav original

Dependents:   UAVCAN UAVCAN_Subscriber

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers timer.hpp Source File

timer.hpp

00001 /*
00002  * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
00003  */
00004 
00005 #ifndef UAVCAN_NODE_TIMER_HPP_INCLUDED
00006 #define UAVCAN_NODE_TIMER_HPP_INCLUDED
00007 
00008 #include <uavcan/std.hpp>
00009 #include <uavcan/error.hpp>
00010 #include <uavcan/build_config.hpp>
00011 #include <uavcan/util/linked_list.hpp>
00012 #include <uavcan/node/scheduler.hpp>
00013 #include <uavcan/node/abstract_node.hpp>
00014 #include <uavcan/util/templates.hpp>
00015 
00016 #if !defined(UAVCAN_CPP11) || !defined(UAVCAN_CPP_VERSION)
00017 # error UAVCAN_CPP_VERSION
00018 #endif
00019 
00020 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
00021 # include <functional>
00022 #endif
00023 
00024 namespace uavcan
00025 {
00026 
00027 class UAVCAN_EXPORT TimerBase;
00028 
00029 /**
00030  * Objects of this type will be supplied into timer callbacks.
00031  */
00032 struct UAVCAN_EXPORT TimerEvent
00033 {
00034     MonotonicTime scheduled_time;  ///< Time when the timer callback was expected to be invoked
00035     MonotonicTime real_time;       ///< True time when the timer callback was invoked
00036 
00037     TimerEvent(MonotonicTime arg_scheduled_time, MonotonicTime arg_real_time)
00038         : scheduled_time(arg_scheduled_time)
00039         , real_time(arg_real_time)
00040     { }
00041 };
00042 
00043 /**
00044  * Inherit this class if you need a timer callback method in your class.
00045  */
00046 class UAVCAN_EXPORT TimerBase : private DeadlineHandler
00047 {
00048     MonotonicDuration period_;
00049 
00050     virtual void handleDeadline(MonotonicTime current);
00051 
00052 public:
00053     using DeadlineHandler::stop;
00054     using DeadlineHandler::isRunning;
00055     using DeadlineHandler::getDeadline;
00056     using DeadlineHandler::getScheduler;
00057 
00058     explicit TimerBase(INode& node)
00059         : DeadlineHandler(node.getScheduler())
00060         , period_(MonotonicDuration::getInfinite())
00061     { }
00062 
00063     /**
00064      * Various ways to start the timer - periodically or once.
00065      * If it is running already, it will be restarted.
00066      * If the deadline is in the past, the event will fire immediately.
00067      * In periodic mode the timer does not accumulate error over time.
00068      */
00069     void startOneShotWithDeadline(MonotonicTime deadline);
00070     void startOneShotWithDelay(MonotonicDuration delay);
00071     void startPeriodic(MonotonicDuration period);
00072 
00073     /**
00074      * Returns period if the timer is in periodic mode.
00075      * Returns infinite duration if the timer is in one-shot mode or stopped.
00076      */
00077     MonotonicDuration getPeriod() const { return period_; }
00078 
00079     /**
00080      * Implement this method in your class to receive callbacks.
00081      */
00082     virtual void handleTimerEvent(const TimerEvent& event) = 0;
00083 };
00084 
00085 /**
00086  * Wrapper over TimerBase that forwards callbacks into arbitrary handlers, like
00087  * functor objects, member functions or static functions.
00088  *
00089  * Callback must be set before the first event; otherwise the event will generate a fatal error.
00090  *
00091  * Also take a look at @ref MethodBinder<>, which may come useful if C++11 features are not available.
00092  *
00093  * @tparam Callback_    Callback type. Shall accept const reference to TimerEvent as its argument.
00094  */
00095 template <typename Callback_>
00096 class UAVCAN_EXPORT TimerEventForwarder : public TimerBase
00097 {
00098 public:
00099     typedef Callback_ Callback;
00100 
00101 private:
00102     Callback callback_;
00103 
00104     virtual void handleTimerEvent(const TimerEvent& event)
00105     {
00106         if (coerceOrFallback<bool>(callback_, true))
00107         {
00108             callback_(event);
00109         }
00110         else
00111         {
00112             handleFatalError("Invalid timer callback");
00113         }
00114     }
00115 
00116 public:
00117     explicit TimerEventForwarder(INode& node)
00118         : TimerBase(node)
00119         , callback_()
00120     { }
00121 
00122     TimerEventForwarder(INode& node, const Callback& callback)
00123         : TimerBase(node)
00124         , callback_(callback)
00125     { }
00126 
00127     /**
00128      * Get/set the callback object.
00129      * Callback must be set before the first event happens; otherwise the event will generate a fatal error.
00130      */
00131     const Callback& getCallback() const { return callback_; }
00132     void setCallback(const Callback& callback) { callback_ = callback; }
00133 };
00134 
00135 
00136 #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
00137 
00138 /**
00139  * Use this timer in C++11 mode.
00140  * Callback type is std::function<>.
00141  */
00142 typedef TimerEventForwarder<std::function<void (const TimerEvent& event)> > Timer;
00143 
00144 #endif
00145 
00146 }
00147 
00148 #endif // UAVCAN_NODE_TIMER_HPP_INCLUDED