Note! This project has moved to github.com/armmbed/mbed-events
Embed:
(wiki syntax)
Show/hide line numbers
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