Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
EventQueue.h
00001 /* EventQueue 00002 * 00003 * Flexible queue for managing events 00004 */ 00005 #ifndef EVENT_QUEUE_H 00006 #define EVENT_QUEUE_H 00007 00008 #include "Timer.h" 00009 #include "Ticker.h" 00010 #include "FuncPtr.h" 00011 #include "Binder.h" 00012 00013 00014 /** Flexible queue for managing events 00015 */ 00016 class EventQueue { 00017 public: 00018 /** Create an event queue 00019 * @param event_count Number of events to allow enqueueing at once 00020 * (default: 32) 00021 * @param event_context Max size of arguments passed with an event 00022 * (default: 0) 00023 * @param event_pointer Pointer to memory area to be used for events 00024 * (default: NULL) 00025 */ 00026 EventQueue(unsigned event_count=32, 00027 unsigned event_context=0, 00028 unsigned char *event_pointer=NULL); 00029 00030 /** Clean up event queue 00031 */ 00032 ~EventQueue(); 00033 00034 /** Dispatch pending events 00035 * @param ms Time to wait for events in milliseconds, 00036 * 0 indicates to return immediately if no events are pending 00037 */ 00038 void dispatch(int ms=-1); 00039 00040 /** Get current tick of the event queue 00041 * @return Number of milliseconds since the queue was instantiated, 00042 * this count intentionally overflows to 0 after 2^32-1 00043 */ 00044 unsigned get_tick(); 00045 00046 /** Determine if tick has been passed 00047 * @param Tick to check 00048 * @param True if tick has been passed 00049 */ 00050 bool past_tick(unsigned tick); 00051 00052 private: 00053 struct event { 00054 struct event *volatile next; 00055 unsigned target; 00056 int period; 00057 00058 void (*dispatch)(void *p); 00059 // data follows 00060 }; 00061 00062 struct event *event_alloc(unsigned size, int ms=-1); 00063 void event_dealloc(struct event *); 00064 00065 void event_trigger(struct event *e, int delay); 00066 00067 template <typename F> 00068 bool event_trigger(F func, int delay, int period, int tolerance, int ms=-1) { 00069 struct event *e = event_alloc(sizeof(F), ms); 00070 if (!e) { 00071 return false; 00072 } 00073 00074 e->period = period; 00075 (void)tolerance; // unused 00076 e->dispatch = &F::thunk; 00077 *reinterpret_cast<F*>(e+1) = func; 00078 00079 event_trigger(e, delay); 00080 return true; 00081 } 00082 00083 void tick(); 00084 00085 unsigned _event_context; 00086 void *_mem; 00087 00088 struct event *volatile _free; 00089 struct event *volatile _queue; 00090 00091 unsigned _tick; 00092 mbed::Ticker _ticker; 00093 mbed::Timer _timer; 00094 00095 template <typename F> 00096 friend class Event; 00097 00098 public: 00099 // An event loop provides three additional convenience functions 00100 // trigger - Immediately post an event to the queue 00101 // trigger_in - Post an event after a specified time in milliseconds 00102 // trigger_every - Post an event periodically in milliseconds 00103 // 00104 // Unfortunately, the lack of converting constructors in 00105 // template functions combined with a lack of variadic 00106 // templates requires 18 declarations for each function 00107 00108 /** Immediately post an event to the queue 00109 */ 00110 template <typename F, typename A0, typename A1, typename A2, typename A3, typename A4> 00111 bool trigger(F func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { 00112 return event_trigger(Binder<void(A0,A1,A2,A3,A4),A0,A1,A2,A3,A4>(func,a0,a1,a2,a3,a4), 0, -1, 0); 00113 } 00114 00115 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> 00116 bool trigger(T *obj, void (*func)(T*,A0,A1,A2,A3,A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { 00117 return trigger(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4); 00118 } 00119 00120 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> 00121 bool trigger(T *obj, void (T::*func)(A0,A1,A2,A3,A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { 00122 return trigger(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4); 00123 } 00124 00125 /** Immediately post an event to the queue 00126 */ 00127 template <typename F, typename A0, typename A1, typename A2, typename A3> 00128 bool trigger(F func, A0 a0, A1 a1, A2 a2, A3 a3) { 00129 return event_trigger(Binder<void(A0,A1,A2,A3),A0,A1,A2,A3>(func,a0,a1,a2,a3), 0, -1, 0); 00130 } 00131 00132 template <typename T, typename A0, typename A1, typename A2, typename A3> 00133 bool trigger(T *obj, void (*func)(T*,A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3) { 00134 return trigger(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3); 00135 } 00136 00137 template <typename T, typename A0, typename A1, typename A2, typename A3> 00138 bool trigger(T *obj, void (T::*func)(A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3) { 00139 return trigger(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3); 00140 } 00141 00142 /** Immediately post an event to the queue 00143 */ 00144 template <typename F, typename A0, typename A1, typename A2> 00145 bool trigger(F func, A0 a0, A1 a1, A2 a2) { 00146 return event_trigger(Binder<void(A0,A1,A2),A0,A1,A2>(func,a0,a1,a2), 0, -1, 0); 00147 } 00148 00149 template <typename T, typename A0, typename A1, typename A2> 00150 bool trigger(T *obj, void (*func)(T*,A0,A1,A2), A0 a0, A1 a1, A2 a2) { 00151 return trigger(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2); 00152 } 00153 00154 template <typename T, typename A0, typename A1, typename A2> 00155 bool trigger(T *obj, void (T::*func)(A0,A1,A2), A0 a0, A1 a1, A2 a2) { 00156 return trigger(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2); 00157 } 00158 00159 /** Immediately post an event to the queue 00160 */ 00161 template <typename F, typename A0, typename A1> 00162 bool trigger(F func, A0 a0, A1 a1) { 00163 return event_trigger(Binder<void(A0,A1),A0,A1>(func,a0,a1), 0, -1, 0); 00164 } 00165 00166 template <typename T, typename A0, typename A1> 00167 bool trigger(T *obj, void (*func)(T*,A0,A1), A0 a0, A1 a1) { 00168 return trigger(FuncPtr<void(A0,A1)>(obj,func),a0,a1); 00169 } 00170 00171 template <typename T, typename A0, typename A1> 00172 bool trigger(T *obj, void (T::*func)(A0,A1), A0 a0, A1 a1) { 00173 return trigger(FuncPtr<void(A0,A1)>(obj,func),a0,a1); 00174 } 00175 00176 /** Immediately post an event to the queue 00177 */ 00178 template <typename F, typename A0> 00179 bool trigger(F func, A0 a0) { 00180 return event_trigger(Binder<void(A0),A0>(func,a0), 0, -1, 0); 00181 } 00182 00183 template <typename T, typename A0> 00184 bool trigger(T *obj, void (*func)(T*,A0), A0 a0) { 00185 return trigger(FuncPtr<void(A0)>(obj,func),a0); 00186 } 00187 00188 template <typename T, typename A0> 00189 bool trigger(T *obj, void (T::*func)(A0), A0 a0) { 00190 return trigger(FuncPtr<void(A0)>(obj,func),a0); 00191 } 00192 00193 /** Immediately post an event to the queue 00194 */ 00195 template <typename F> 00196 bool trigger(F func) { 00197 return event_trigger(Binder<void()>(func), 0, -1, 0); 00198 } 00199 00200 template <typename T> 00201 bool trigger(T *obj, void (*func)(T*)) { 00202 return trigger(FuncPtr<void()>(obj,func)); 00203 } 00204 00205 template <typename T> 00206 bool trigger(T *obj, void (T::*func)()) { 00207 return trigger(FuncPtr<void()>(obj,func)); 00208 } 00209 00210 /** Post an event after a specified time 00211 * @param ms Delay in milliseconds 00212 */ 00213 template <typename F, typename A0, typename A1, typename A2, typename A3, typename A4> 00214 bool trigger_in(F func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, int ms) { 00215 return event_trigger(Binder<void(A0,A1,A2,A3,A4),A0,A1,A2,A3,A4>(func,a0,a1,a2,a3,a4), ms, -1, 0); 00216 } 00217 00218 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> 00219 bool trigger_in(T *obj, void (*func)(T*,A0,A1,A2,A3,A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, int ms) { 00220 return trigger_in(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4,ms); 00221 } 00222 00223 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> 00224 bool trigger_in(T *obj, void (T::*func)(A0,A1,A2,A3,A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, int ms) { 00225 return trigger_in(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4,ms); 00226 } 00227 00228 /** Post an event after a specified time 00229 * @param ms Delay in milliseconds 00230 */ 00231 template <typename F, typename A0, typename A1, typename A2, typename A3> 00232 bool trigger_in(F func, A0 a0, A1 a1, A2 a2, A3 a3, int ms) { 00233 return event_trigger(Binder<void(A0,A1,A2,A3),A0,A1,A2,A3>(func,a0,a1,a2,a3), ms, -1, 0); 00234 } 00235 00236 template <typename T, typename A0, typename A1, typename A2, typename A3> 00237 bool trigger_in(T *obj, void (*func)(T*,A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3, int ms) { 00238 return trigger_in(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3,ms); 00239 } 00240 00241 template <typename T, typename A0, typename A1, typename A2, typename A3> 00242 bool trigger_in(T *obj, void (T::*func)(A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3, int ms) { 00243 return trigger_in(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3,ms); 00244 } 00245 00246 /** Post an event after a specified time 00247 * @param ms Delay in milliseconds 00248 */ 00249 template <typename F, typename A0, typename A1, typename A2> 00250 bool trigger_in(F func, A0 a0, A1 a1, A2 a2, int ms) { 00251 return event_trigger(Binder<void(A0,A1,A2),A0,A1,A2>(func,a0,a1,a2), ms, -1, 0); 00252 } 00253 00254 template <typename T, typename A0, typename A1, typename A2> 00255 bool trigger_in(T *obj, void (*func)(T*,A0,A1,A2), A0 a0, A1 a1, A2 a2, int ms) { 00256 return trigger_in(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2,ms); 00257 } 00258 00259 template <typename T, typename A0, typename A1, typename A2> 00260 bool trigger_in(T *obj, void (T::*func)(A0,A1,A2), A0 a0, A1 a1, A2 a2, int ms) { 00261 return trigger_in(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2,ms); 00262 } 00263 00264 /** Post an event after a specified time 00265 * @param ms Delay in milliseconds 00266 */ 00267 template <typename F, typename A0, typename A1> 00268 bool trigger_in(F func, A0 a0, A1 a1, int ms) { 00269 return event_trigger(Binder<void(A0,A1),A0,A1>(func,a0,a1), ms, -1, 0); 00270 } 00271 00272 template <typename T, typename A0, typename A1> 00273 bool trigger_in(T *obj, void (*func)(T*,A0,A1), A0 a0, A1 a1, int ms) { 00274 return trigger_in(FuncPtr<void(A0,A1)>(obj,func),a0,a1,ms); 00275 } 00276 00277 template <typename T, typename A0, typename A1> 00278 bool trigger_in(T *obj, void (T::*func)(A0,A1), A0 a0, A1 a1, int ms) { 00279 return trigger_in(FuncPtr<void(A0,A1)>(obj,func),a0,a1,ms); 00280 } 00281 00282 /** Post an event after a specified time 00283 * @param ms Delay in milliseconds 00284 */ 00285 template <typename F, typename A0> 00286 bool trigger_in(F func, A0 a0, int ms) { 00287 return event_trigger(Binder<void(A0),A0>(func,a0), ms, -1, 0); 00288 } 00289 00290 template <typename T, typename A0> 00291 bool trigger_in(T *obj, void (*func)(T*,A0), A0 a0, int ms) { 00292 return trigger_in(FuncPtr<void(A0)>(obj,func),a0,ms); 00293 } 00294 00295 template <typename T, typename A0> 00296 bool trigger_in(T *obj, void (T::*func)(A0), A0 a0, int ms) { 00297 return trigger_in(FuncPtr<void(A0)>(obj,func),a0,ms); 00298 } 00299 00300 /** Post an event after a specified time 00301 * @param ms Delay in milliseconds 00302 */ 00303 template <typename F> 00304 bool trigger_in(F func, int ms) { 00305 return event_trigger(Binder<void()>(func), ms, -1, 0); 00306 } 00307 00308 template <typename T> 00309 bool trigger_in(T *obj, void (*func)(T*), int ms) { 00310 return trigger_in(FuncPtr<void()>(obj,func),ms); 00311 } 00312 00313 template <typename T> 00314 bool trigger_in(T *obj, void (T::*func)(), int ms) { 00315 return trigger_in(FuncPtr<void()>(obj,func),ms); 00316 } 00317 00318 /** Post an event periodically 00319 * @param ms Delay in milliseconds 00320 */ 00321 template <typename F, typename A0, typename A1, typename A2, typename A3, typename A4> 00322 bool trigger_every(F func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, int ms) { 00323 return event_trigger(Binder<void(A0,A1,A2,A3,A4),A0,A1,A2,A3,A4>(func,a0,a1,a2,a3,a4), 0, ms, 0); 00324 } 00325 00326 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> 00327 bool trigger_every(T *obj, void (*func)(T*,A0,A1,A2,A3,A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, int ms) { 00328 return trigger_every(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4,ms); 00329 } 00330 00331 template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> 00332 bool trigger_every(T *obj, void (T::*func)(A0,A1,A2,A3,A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, int ms) { 00333 return trigger_every(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4,ms); 00334 } 00335 00336 /** Post an event periodically 00337 * @param ms Delay in milliseconds 00338 */ 00339 template <typename F, typename A0, typename A1, typename A2, typename A3> 00340 bool trigger_every(F func, A0 a0, A1 a1, A2 a2, A3 a3, int ms) { 00341 return event_trigger(Binder<void(A0,A1,A2,A3),A0,A1,A2,A3>(func,a0,a1,a2,a3), 0, ms, 0); 00342 } 00343 00344 template <typename T, typename A0, typename A1, typename A2, typename A3> 00345 bool trigger_every(T *obj, void (*func)(T*,A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3, int ms) { 00346 return trigger_every(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3,ms); 00347 } 00348 00349 template <typename T, typename A0, typename A1, typename A2, typename A3> 00350 bool trigger_every(T *obj, void (T::*func)(A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3, int ms) { 00351 return trigger_every(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3,ms); 00352 } 00353 00354 /** Post an event periodically 00355 * @param ms Delay in milliseconds 00356 */ 00357 template <typename F, typename A0, typename A1, typename A2> 00358 bool trigger_every(F func, A0 a0, A1 a1, A2 a2, int ms) { 00359 return event_trigger(Binder<void(A0,A1,A2),A0,A1,A2>(func,a0,a1,a2), 0, ms, 0); 00360 } 00361 00362 template <typename T, typename A0, typename A1, typename A2> 00363 bool trigger_every(T *obj, void (*func)(T*,A0,A1,A2), A0 a0, A1 a1, A2 a2, int ms) { 00364 return trigger_every(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2,ms); 00365 } 00366 00367 template <typename T, typename A0, typename A1, typename A2> 00368 bool trigger_every(T *obj, void (T::*func)(A0,A1,A2), A0 a0, A1 a1, A2 a2, int ms) { 00369 return trigger_every(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2,ms); 00370 } 00371 00372 /** Post an event periodically 00373 * @param ms Delay in milliseconds 00374 */ 00375 template <typename F, typename A0, typename A1> 00376 bool trigger_every(F func, A0 a0, A1 a1, int ms) { 00377 return event_trigger(Binder<void(A0,A1),A0,A1>(func,a0,a1), 0, ms, 0); 00378 } 00379 00380 template <typename T, typename A0, typename A1> 00381 bool trigger_every(T *obj, void (*func)(T*,A0,A1), A0 a0, A1 a1, int ms) { 00382 return trigger_every(FuncPtr<void(A0,A1)>(obj,func),a0,a1,ms); 00383 } 00384 00385 template <typename T, typename A0, typename A1> 00386 bool trigger_every(T *obj, void (T::*func)(A0,A1), A0 a0, A1 a1, int ms) { 00387 return trigger_every(FuncPtr<void(A0,A1)>(obj,func),a0,a1,ms); 00388 } 00389 00390 /** Post an event periodically 00391 * @param ms Delay in milliseconds 00392 */ 00393 template <typename F, typename A0> 00394 bool trigger_every(F func, A0 a0, int ms) { 00395 return event_trigger(Binder<void(A0),A0>(func,a0), 0, ms, 0); 00396 } 00397 00398 template <typename T, typename A0> 00399 bool trigger_every(T *obj, void (*func)(T*,A0), A0 a0, int ms) { 00400 return trigger_every(FuncPtr<void(A0)>(obj,func),a0,ms); 00401 } 00402 00403 template <typename T, typename A0> 00404 bool trigger_every(T *obj, void (T::*func)(A0), A0 a0, int ms) { 00405 return trigger_every(FuncPtr<void(A0)>(obj,func),a0,ms); 00406 } 00407 00408 /** Post an event periodically 00409 * @param ms Delay in milliseconds 00410 */ 00411 template <typename F> 00412 bool trigger_every(F func, int ms) { 00413 return event_trigger(Binder<void()>(func), 0, ms, 0); 00414 } 00415 00416 template <typename T> 00417 bool trigger_every(T *obj, void (*func)(T*), int ms) { 00418 return trigger_every(FuncPtr<void()>(obj,func),ms); 00419 } 00420 00421 template <typename T> 00422 bool trigger_every(T *obj, void (T::*func)(), int ms) { 00423 return trigger_every(FuncPtr<void()>(obj,func),ms); 00424 } 00425 }; 00426 00427 00428 #endif
Generated on Wed Jul 13 2022 19:57:07 by
1.7.2