Note! This project has moved to github.com/armmbed/mbed-events
This repository has been superceded
This project has moved to mbed-events
Composable event loops combine the cheap synchronicity of event loops with the composability of preempted threads.
Two modular event queue classes are provided:
- EventLoop - for loops coupled with a c++ managed thread
- EventQueue - for manually managed event queues
The Event class takes advantage of the extensibility of FuncPtr to allow an event to be passed through APIs as a normal function.
More information on composable event loops.
Diff: EventQueue.h
- Revision:
- 17:6d564266850e
- Parent:
- 16:ff5d48fcce1b
- Child:
- 18:765776145464
--- a/EventQueue.h Mon Apr 18 09:47:21 2016 -0500 +++ b/EventQueue.h Mon Apr 18 12:51:04 2016 -0500 @@ -54,14 +54,14 @@ // data follows }; - struct event *alloc(unsigned size, int ms=-1); - void dealloc(struct event *); + struct event *event_alloc(unsigned size, int ms=-1); + void event_dealloc(struct event *); - void trigger(struct event *e, int delay); + void event_trigger(struct event *e, int delay); template <typename F> - bool trigger(F func, int delay, int period, int tolerance, int ms=-1) { - struct event *e = alloc(sizeof(F), ms); + bool event_trigger(F func, int delay, int period, int tolerance, int ms=-1) { + struct event *e = event_alloc(sizeof(F), ms); if (!e) { return false; } @@ -71,7 +71,7 @@ e->dispatch = &F::thunk; *reinterpret_cast<F*>(e+1) = func; - trigger(e, delay); + event_trigger(e, delay); return true; } @@ -88,6 +88,340 @@ template <typename F> friend class Event; + +public: + // An event loop provides three additional convenience functions + // trigger - Immediately post an event to the queue + // trigger_in - Post an event after a specified time in milliseconds + // trigger_every - Post an event periodically in milliseconds + // + // Unfortunately, the lack of converting constructors in + // template functions combined with a lack of variadic + // templates requires 18 declarations for each function + + /** Immediately post an event to the queue */ + template <typename F, typename A0, typename A1, typename A2, typename A3, typename A4> + bool trigger(F func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return event_trigger(Binder<void(A0,A1,A2,A3,A4),A0,A1,A2,A3,A4>(func,a0,a1,a2,a3,a4), 0, -1, 0); + } + + /** Immediately post an event to the queue */ + template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> + bool trigger(T *obj, void (*func)(T*,A0,A1,A2,A3,A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return trigger(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4); + } + + /** Immediately post an event to the queue */ + template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> + bool trigger(T *obj, void (T::*func)(A0,A1,A2,A3,A4), A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + return trigger(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4); + } + + /** Immediately post an event to the queue */ + template <typename F, typename A0, typename A1, typename A2, typename A3> + bool trigger(F func, A0 a0, A1 a1, A2 a2, A3 a3) { + return event_trigger(Binder<void(A0,A1,A2,A3),A0,A1,A2,A3>(func,a0,a1,a2,a3), 0, -1, 0); + } + + /** Immediately post an event to the queue */ + template <typename T, typename A0, typename A1, typename A2, typename A3> + bool trigger(T *obj, void (*func)(T*,A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3) { + return trigger(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3); + } + + /** Immediately post an event to the queue */ + template <typename T, typename A0, typename A1, typename A2, typename A3> + bool trigger(T *obj, void (T::*func)(A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3) { + return trigger(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3); + } + + /** Immediately post an event to the queue */ + template <typename F, typename A0, typename A1, typename A2> + bool trigger(F func, A0 a0, A1 a1, A2 a2) { + return event_trigger(Binder<void(A0,A1,A2),A0,A1,A2>(func,a0,a1,a2), 0, -1, 0); + } + + /** Immediately post an event to the queue */ + template <typename T, typename A0, typename A1, typename A2> + bool trigger(T *obj, void (*func)(T*,A0,A1,A2), A0 a0, A1 a1, A2 a2) { + return trigger(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2); + } + + /** Immediately post an event to the queue */ + template <typename T, typename A0, typename A1, typename A2> + bool trigger(T *obj, void (T::*func)(A0,A1,A2), A0 a0, A1 a1, A2 a2) { + return trigger(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2); + } + + /** Immediately post an event to the queue */ + template <typename F, typename A0, typename A1> + bool trigger(F func, A0 a0, A1 a1) { + return event_trigger(Binder<void(A0,A1),A0,A1>(func,a0,a1), 0, -1, 0); + } + + /** Immediately post an event to the queue */ + template <typename T, typename A0, typename A1> + bool trigger(T *obj, void (*func)(T*,A0,A1), A0 a0, A1 a1) { + return trigger(FuncPtr<void(A0,A1)>(obj,func),a0,a1); + } + + /** Immediately post an event to the queue */ + template <typename T, typename A0, typename A1> + bool trigger(T *obj, void (T::*func)(A0,A1), A0 a0, A1 a1) { + return trigger(FuncPtr<void(A0,A1)>(obj,func),a0,a1); + } + + /** Immediately post an event to the queue */ + template <typename F, typename A0> + bool trigger(F func, A0 a0) { + return event_trigger(Binder<void(A0),A0>(func,a0), 0, -1, 0); + } + + /** Immediately post an event to the queue */ + template <typename T, typename A0> + bool trigger(T *obj, void (*func)(T*,A0), A0 a0) { + return trigger(FuncPtr<void(A0)>(obj,func),a0); + } + + /** Immediately post an event to the queue */ + template <typename T, typename A0> + bool trigger(T *obj, void (T::*func)(A0), A0 a0) { + return trigger(FuncPtr<void(A0)>(obj,func),a0); + } + + /** Immediately post an event to the queue */ + template <typename F> + bool trigger(F func) { + return event_trigger(Binder<void()>(func), 0, -1, 0); + } + + /** Immediately post an event to the queue */ + template <typename T> + bool trigger(T *obj, void (*func)(T*)) { + return trigger(FuncPtr<void()>(obj,func)); + } + + /** Immediately post an event to the queue */ + template <typename T> + bool trigger(T *obj, void (T::*func)()) { + return trigger(FuncPtr<void()>(obj,func)); + } + + /** Post an event after a specified time in milliseconds */ + template <typename F, typename A0, typename A1, typename A2, typename A3, typename A4> + bool trigger_in(F func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, int ms=-1) { + return event_trigger(Binder<void(A0,A1,A2,A3,A4),A0,A1,A2,A3,A4>(func,a0,a1,a2,a3,a4), ms, -1, 0); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> + 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=-1) { + return trigger_in(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4,ms); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> + 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=-1) { + return trigger_in(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4,ms); + } + + /** Post an event after a specified time in milliseconds */ + template <typename F, typename A0, typename A1, typename A2, typename A3> + bool trigger_in(F func, A0 a0, A1 a1, A2 a2, A3 a3, int ms=-1) { + return event_trigger(Binder<void(A0,A1,A2,A3),A0,A1,A2,A3>(func,a0,a1,a2,a3), ms, -1, 0); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T, typename A0, typename A1, typename A2, typename A3> + bool trigger_in(T *obj, void (*func)(T*,A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3, int ms=-1) { + return trigger_in(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3,ms); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T, typename A0, typename A1, typename A2, typename A3> + bool trigger_in(T *obj, void (T::*func)(A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3, int ms=-1) { + return trigger_in(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3,ms); + } + + /** Post an event after a specified time in milliseconds */ + template <typename F, typename A0, typename A1, typename A2> + bool trigger_in(F func, A0 a0, A1 a1, A2 a2, int ms=-1) { + return event_trigger(Binder<void(A0,A1,A2),A0,A1,A2>(func,a0,a1,a2), ms, -1, 0); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T, typename A0, typename A1, typename A2> + bool trigger_in(T *obj, void (*func)(T*,A0,A1,A2), A0 a0, A1 a1, A2 a2, int ms=-1) { + return trigger_in(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2,ms); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T, typename A0, typename A1, typename A2> + bool trigger_in(T *obj, void (T::*func)(A0,A1,A2), A0 a0, A1 a1, A2 a2, int ms=-1) { + return trigger_in(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2,ms); + } + + /** Post an event after a specified time in milliseconds */ + template <typename F, typename A0, typename A1> + bool trigger_in(F func, A0 a0, A1 a1, int ms=-1) { + return event_trigger(Binder<void(A0,A1),A0,A1>(func,a0,a1), ms, -1, 0); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T, typename A0, typename A1> + bool trigger_in(T *obj, void (*func)(T*,A0,A1), A0 a0, A1 a1, int ms=-1) { + return trigger_in(FuncPtr<void(A0,A1)>(obj,func),a0,a1,ms); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T, typename A0, typename A1> + bool trigger_in(T *obj, void (T::*func)(A0,A1), A0 a0, A1 a1, int ms=-1) { + return trigger_in(FuncPtr<void(A0,A1)>(obj,func),a0,a1,ms); + } + + /** Post an event after a specified time in milliseconds */ + template <typename F, typename A0> + bool trigger_in(F func, A0 a0, int ms=-1) { + return event_trigger(Binder<void(A0),A0>(func,a0), ms, -1, 0); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T, typename A0> + bool trigger_in(T *obj, void (*func)(T*,A0), A0 a0, int ms=-1) { + return trigger_in(FuncPtr<void(A0)>(obj,func),a0,ms); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T, typename A0> + bool trigger_in(T *obj, void (T::*func)(A0), A0 a0, int ms=-1) { + return trigger_in(FuncPtr<void(A0)>(obj,func),a0,ms); + } + + /** Post an event after a specified time in milliseconds */ + template <typename F> + bool trigger_in(F func, int ms=-1) { + return event_trigger(Binder<void()>(func), ms, -1, 0); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T> + bool trigger_in(T *obj, void (*func)(T*), int ms=-1) { + return trigger_in(FuncPtr<void()>(obj,func),ms); + } + + /** Post an event after a specified time in milliseconds */ + template <typename T> + bool trigger_in(T *obj, void (T::*func)(), int ms=-1) { + return trigger_in(FuncPtr<void()>(obj,func),ms); + } + + /** Post an event periodically in milliseconds */ + template <typename F, typename A0, typename A1, typename A2, typename A3, typename A4> + bool trigger_every(F func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, int ms=-1) { + return event_trigger(Binder<void(A0,A1,A2,A3,A4),A0,A1,A2,A3,A4>(func,a0,a1,a2,a3,a4), 0, ms, 0); + } + + /** Post an event periodically in milliseconds */ + template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> + 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=-1) { + return trigger_every(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4,ms); + } + + /** Post an event periodically in milliseconds */ + template <typename T, typename A0, typename A1, typename A2, typename A3, typename A4> + 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=-1) { + return trigger_every(FuncPtr<void(A0,A1,A2,A3,A4)>(obj,func),a0,a1,a2,a3,a4,ms); + } + + /** Post an event periodically in milliseconds */ + template <typename F, typename A0, typename A1, typename A2, typename A3> + bool trigger_every(F func, A0 a0, A1 a1, A2 a2, A3 a3, int ms=-1) { + return event_trigger(Binder<void(A0,A1,A2,A3),A0,A1,A2,A3>(func,a0,a1,a2,a3), 0, ms, 0); + } + + /** Post an event periodically in milliseconds */ + template <typename T, typename A0, typename A1, typename A2, typename A3> + bool trigger_every(T *obj, void (*func)(T*,A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3, int ms=-1) { + return trigger_every(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3,ms); + } + + /** Post an event periodically in milliseconds */ + template <typename T, typename A0, typename A1, typename A2, typename A3> + bool trigger_every(T *obj, void (T::*func)(A0,A1,A2,A3), A0 a0, A1 a1, A2 a2, A3 a3, int ms=-1) { + return trigger_every(FuncPtr<void(A0,A1,A2,A3)>(obj,func),a0,a1,a2,a3,ms); + } + + /** Post an event periodically in milliseconds */ + template <typename F, typename A0, typename A1, typename A2> + bool trigger_every(F func, A0 a0, A1 a1, A2 a2, int ms=-1) { + return event_trigger(Binder<void(A0,A1,A2),A0,A1,A2>(func,a0,a1,a2), 0, ms, 0); + } + + /** Post an event periodically in milliseconds */ + template <typename T, typename A0, typename A1, typename A2> + bool trigger_every(T *obj, void (*func)(T*,A0,A1,A2), A0 a0, A1 a1, A2 a2, int ms=-1) { + return trigger_every(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2,ms); + } + + /** Post an event periodically in milliseconds */ + template <typename T, typename A0, typename A1, typename A2> + bool trigger_every(T *obj, void (T::*func)(A0,A1,A2), A0 a0, A1 a1, A2 a2, int ms=-1) { + return trigger_every(FuncPtr<void(A0,A1,A2)>(obj,func),a0,a1,a2,ms); + } + + /** Post an event periodically in milliseconds */ + template <typename F, typename A0, typename A1> + bool trigger_every(F func, A0 a0, A1 a1, int ms=-1) { + return event_trigger(Binder<void(A0,A1),A0,A1>(func,a0,a1), 0, ms, 0); + } + + /** Post an event periodically in milliseconds */ + template <typename T, typename A0, typename A1> + bool trigger_every(T *obj, void (*func)(T*,A0,A1), A0 a0, A1 a1, int ms=-1) { + return trigger_every(FuncPtr<void(A0,A1)>(obj,func),a0,a1,ms); + } + + /** Post an event periodically in milliseconds */ + template <typename T, typename A0, typename A1> + bool trigger_every(T *obj, void (T::*func)(A0,A1), A0 a0, A1 a1, int ms=-1) { + return trigger_every(FuncPtr<void(A0,A1)>(obj,func),a0,a1,ms); + } + + /** Post an event periodically in milliseconds */ + template <typename F, typename A0> + bool trigger_every(F func, A0 a0, int ms=-1) { + return event_trigger(Binder<void(A0),A0>(func,a0), 0, ms, 0); + } + + /** Post an event periodically in milliseconds */ + template <typename T, typename A0> + bool trigger_every(T *obj, void (*func)(T*,A0), A0 a0, int ms=-1) { + return trigger_every(FuncPtr<void(A0)>(obj,func),a0,ms); + } + + /** Post an event periodically in milliseconds */ + template <typename T, typename A0> + bool trigger_every(T *obj, void (T::*func)(A0), A0 a0, int ms=-1) { + return trigger_every(FuncPtr<void(A0)>(obj,func),a0,ms); + } + + /** Post an event periodically in milliseconds */ + template <typename F> + bool trigger_every(F func, int ms=-1) { + return event_trigger(Binder<void()>(func), 0, ms, 0); + } + + /** Post an event periodically in milliseconds */ + template <typename T> + bool trigger_every(T *obj, void (*func)(T*), int ms=-1) { + return trigger_every(FuncPtr<void()>(obj,func),ms); + } + + /** Post an event periodically in milliseconds */ + template <typename T> + bool trigger_every(T *obj, void (T::*func)(), int ms=-1) { + return trigger_every(FuncPtr<void()>(obj,func),ms); + } };