libuav original
Dependents: UAVCAN UAVCAN_Subscriber
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
Generated on Tue Jul 12 2022 17:17:35 by 1.7.2