Note! This project has moved to github.com/armmbed/mbed-events

Dependents:   SimpleHTTPExample

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EventQueue.h Source File

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