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.
Event.h
- Committer:
- Christopher Haster
- Date:
- 2016-05-10
- Revision:
- 14:5abf2ccf2dbf
- Parent:
- 13:b84e049b2d9c
- Child:
- 17:6d564266850e
File content as of revision 14:5abf2ccf2dbf:
/* Event * * Pendable event */ #ifndef EVENT_H #define EVENT_H #include "EventQueue.h" #include "FuncPtr.h" #include "Binder.h" /** Pendable event class */ template <typename F> class Event; /** Pendable event class */ template <typename A0, typename A1, typename A2, typename A3, typename A4> class Event<void(A0, A1, A2, A3, A4)> { public: /** Create an event bound to a queue */ Event(EventQueue *queue=0, FuncPtr<void(A0, A1, A2, A3, A4)> func=0) { _delay = 0; _period = -1; attach(queue, func); } /** Create an event bound to a queue */ template <typename T, typename M> Event(EventQueue *queue, T *obj, M method) { _delay = 0; _period = -1; attach(queue, obj, method); } /** Attach an event to a queue */ void attach(EventQueue *queue) { _queue = queue; } /** Attach a callback to an event */ void attach(FuncPtr<void(A0, A1, A2, A3, A4)> func) { _func.attach(func); } /** Attach a callback to an event */ template <typename T, typename M> void attach(T *obj, M method) { attach(FuncPtr<void(A0, A1, A2, A3, A4)>(obj, method)); } /** Attach a func to an event */ void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3, A4)> func) { attach(queue); attach(func); } /** Attach an event to a queue */ template <typename T, typename M> void attach(EventQueue *queue, T *obj, M method) { attach(queue); attach(obj, method); } /** Set delay for when the event is dispatched after it is posted * @param ms Delay in milliseconds */ void delay(int ms) { _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { _period = ms; } /** Set tolerance hint on when the event must be called, defaults to 0 * @param ms Tolerance in milliseconds */ void tolerance(int ms) { _tolerance = ms; } /** Post the event onto the bound queue * @param ms Max time to wait if memory is not available in milliseconds * @return True if the event was posted successfully */ bool trigger(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, int ms=-1) { return _queue->trigger( Binder<void(A0,A1,A2,A3,A4),A0,A1,A2,A3,A4>(_func,a0,a1,a2,a3,a4), _delay, _period, _tolerance, ms); } /** Post the event onto the bound queue */ void call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { trigger(a0, a1, a2, a3, a4); } /** Post the event onto the bound queue */ void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return call(a0, a1, a2, a3, a4); } /** Test if event has been bound */ operator bool() const { return _func && _queue; } /** Static thunk for passing as C-style function * @param data Event to dispatch passed as void pointer */ static void thunk(void *data, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { return static_cast<Event<void(A0, A1, A2, A3, A4)>*>(data) ->call(a0, a1, a2, a3, a4); } private: FuncPtr<void(A0,A1,A2,A3,A4)> _func; EventQueue *_queue; int _delay; int _period; int _tolerance; }; /** Pendable event class */ template <typename A0, typename A1, typename A2, typename A3> class Event<void(A0, A1, A2, A3)> { public: /** Create an event bound to a queue */ Event(EventQueue *queue=0, FuncPtr<void(A0, A1, A2, A3)> func=0) { _delay = 0; _period = -1; attach(queue, func); } /** Create an event bound to a queue */ template <typename T, typename M> Event(EventQueue *queue, T *obj, M method) { _delay = 0; _period = -1; attach(queue, obj, method); } /** Attach an event to a queue */ void attach(EventQueue *queue) { _queue = queue; } /** Attach a callback to an event */ void attach(FuncPtr<void(A0, A1, A2, A3)> func) { _func.attach(func); } /** Attach a callback to an event */ template <typename T, typename M> void attach(T *obj, M method) { attach(FuncPtr<void(A0, A1, A2, A3)>(obj, method)); } /** Attach a func to an event */ void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3)> func) { attach(queue); attach(func); } /** Attach an event to a queue */ template <typename T, typename M> void attach(EventQueue *queue, T *obj, M method) { attach(queue); attach(obj, method); } /** Set delay for when the event is dispatched after it is posted * @param ms Delay in milliseconds */ void delay(int ms) { _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { _period = ms; } /** Set tolerance hint on when the event must be called, defaults to 0 * @param ms Tolerance in milliseconds */ void tolerance(int ms) { _tolerance = ms; } /** Post the event onto the bound queue * @param ms Max time to wait if memory is not available in milliseconds * @return True if the event was posted successfully */ bool trigger(A0 a0, A1 a1, A2 a2, A3 a3, int ms=-1) { return _queue->trigger( Binder<void(A0,A1,A2,A3),A0,A1,A2,A3>(_func,a0,a1,a2,a3), _delay, _period, _tolerance, ms); } /** Post the event onto the bound queue */ void call(A0 a0, A1 a1, A2 a2, A3 a3) { trigger(a0, a1, a2, a3); } /** Post the event onto the bound queue */ void operator()(A0 a0, A1 a1, A2 a2, A3 a3) { return call(a0, a1, a2, a3); } /** Test if event has been bound */ operator bool() const { return _func && _queue; } /** Static thunk for passing as C-style function * @param data Event to dispatch passed as void pointer */ static void thunk(void *data, A0 a0, A1 a1, A2 a2, A3 a3) { return static_cast<Event<void(A0, A1, A2, A3)>*>(data) ->call(a0, a1, a2, a3); } private: FuncPtr<void(A0,A1,A2,A3)> _func; EventQueue *_queue; int _delay; int _period; int _tolerance; }; /** Pendable event class */ template <typename A0, typename A1, typename A2> class Event<void(A0, A1, A2)> { public: /** Create an event bound to a queue */ Event(EventQueue *queue=0, FuncPtr<void(A0, A1, A2)> func=0) { _delay = 0; _period = -1; attach(queue, func); } /** Create an event bound to a queue */ template <typename T, typename M> Event(EventQueue *queue, T *obj, M method) { _delay = 0; _period = -1; attach(queue, obj, method); } /** Attach an event to a queue */ void attach(EventQueue *queue) { _queue = queue; } /** Attach a callback to an event */ void attach(FuncPtr<void(A0, A1, A2)> func) { _func.attach(func); } /** Attach a callback to an event */ template <typename T, typename M> void attach(T *obj, M method) { attach(FuncPtr<void(A0, A1, A2)>(obj, method)); } /** Attach a func to an event */ void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2)> func) { attach(queue); attach(func); } /** Attach an event to a queue */ template <typename T, typename M> void attach(EventQueue *queue, T *obj, M method) { attach(queue); attach(obj, method); } /** Set delay for when the event is dispatched after it is posted * @param ms Delay in milliseconds */ void delay(int ms) { _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { _period = ms; } /** Set tolerance hint on when the event must be called, defaults to 0 * @param ms Tolerance in milliseconds */ void tolerance(int ms) { _tolerance = ms; } /** Post the event onto the bound queue * @param ms Max time to wait if memory is not available in milliseconds * @return True if the event was posted successfully */ bool trigger(A0 a0, A1 a1, A2 a2, int ms=-1) { return _queue->trigger( Binder<void(A0,A1,A2),A0,A1,A2>(_func,a0,a1,a2), _delay, _period, _tolerance, ms); } /** Post the event onto the bound queue */ void call(A0 a0, A1 a1, A2 a2) { trigger(a0, a1, a2); } /** Post the event onto the bound queue */ void operator()(A0 a0, A1 a1, A2 a2) { return call(a0, a1, a2); } /** Test if event has been bound */ operator bool() const { return _func && _queue; } /** Static thunk for passing as C-style function * @param data Event to dispatch passed as void pointer */ static void thunk(void *data, A0 a0, A1 a1, A2 a2) { return static_cast<Event<void(A0, A1, A2)>*>(data) ->call(a0, a1, a2); } private: FuncPtr<void(A0,A1,A2)> _func; EventQueue *_queue; int _delay; int _period; int _tolerance; }; /** Pendable event class */ template <typename A0, typename A1> class Event<void(A0, A1)> { public: /** Create an event bound to a queue */ Event(EventQueue *queue=0, FuncPtr<void(A0, A1)> func=0) { _delay = 0; _period = -1; attach(queue, func); } /** Create an event bound to a queue */ template <typename T, typename M> Event(EventQueue *queue, T *obj, M method) { _delay = 0; _period = -1; attach(queue, obj, method); } /** Attach an event to a queue */ void attach(EventQueue *queue) { _queue = queue; } /** Attach a callback to an event */ void attach(FuncPtr<void(A0, A1)> func) { _func.attach(func); } /** Attach a callback to an event */ template <typename T, typename M> void attach(T *obj, M method) { attach(FuncPtr<void(A0, A1)>(obj, method)); } /** Attach a func to an event */ void attach(EventQueue *queue, FuncPtr<void(A0, A1)> func) { attach(queue); attach(func); } /** Attach an event to a queue */ template <typename T, typename M> void attach(EventQueue *queue, T *obj, M method) { attach(queue); attach(obj, method); } /** Set delay for when the event is dispatched after it is posted * @param ms Delay in milliseconds */ void delay(int ms) { _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { _period = ms; } /** Set tolerance hint on when the event must be called, defaults to 0 * @param ms Tolerance in milliseconds */ void tolerance(int ms) { _tolerance = ms; } /** Post the event onto the bound queue * @param ms Max time to wait if memory is not available in milliseconds * @return True if the event was posted successfully */ bool trigger(A0 a0, A1 a1, int ms=-1) { return _queue->trigger( Binder<void(A0,A1),A0,A1>(_func,a0,a1), _delay, _period, _tolerance, ms); } /** Post the event onto the bound queue */ void call(A0 a0, A1 a1) { trigger(a0, a1); } /** Post the event onto the bound queue */ void operator()(A0 a0, A1 a1) { return call(a0, a1); } /** Test if event has been bound */ operator bool() const { return _func && _queue; } /** Static thunk for passing as C-style function * @param data Event to dispatch passed as void pointer */ static void thunk(void *data, A0 a0, A1 a1) { return static_cast<Event<void(A0, A1)>*>(data) ->call(a0, a1); } private: FuncPtr<void(A0,A1)> _func; EventQueue *_queue; int _delay; int _period; int _tolerance; }; /** Pendable event class */ template <typename A0> class Event<void(A0)> { public: /** Create an event bound to a queue */ Event(EventQueue *queue=0, FuncPtr<void(A0)> func=0) { _delay = 0; _period = -1; attach(queue, func); } /** Create an event bound to a queue */ template <typename T, typename M> Event(EventQueue *queue, T *obj, M method) { _delay = 0; _period = -1; attach(queue, obj, method); } /** Attach an event to a queue */ void attach(EventQueue *queue) { _queue = queue; } /** Attach a callback to an event */ void attach(FuncPtr<void(A0)> func) { _func.attach(func); } /** Attach a callback to an event */ template <typename T, typename M> void attach(T *obj, M method) { attach(FuncPtr<void(A0)>(obj, method)); } /** Attach a func to an event */ void attach(EventQueue *queue, FuncPtr<void(A0)> func) { attach(queue); attach(func); } /** Attach an event to a queue */ template <typename T, typename M> void attach(EventQueue *queue, T *obj, M method) { attach(queue); attach(obj, method); } /** Set delay for when the event is dispatched after it is posted * @param ms Delay in milliseconds */ void delay(int ms) { _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { _period = ms; } /** Set tolerance hint on when the event must be called, defaults to 0 * @param ms Tolerance in milliseconds */ void tolerance(int ms) { _tolerance = ms; } /** Post the event onto the bound queue * @param ms Max time to wait if memory is not available in milliseconds * @return True if the event was posted successfully */ bool trigger(A0 a0, int ms=-1) { return _queue->trigger( Binder<void(A0),A0>(_func,a0), _delay, _period, _tolerance, ms); } /** Post the event onto the bound queue */ void call(A0 a0) { trigger(a0); } /** Post the event onto the bound queue */ void operator()(A0 a0) { return call(a0); } /** Test if event has been bound */ operator bool() const { return _func && _queue; } /** Static thunk for passing as C-style function * @param data Event to dispatch passed as void pointer */ static void thunk(void *data, A0 a0) { return static_cast<Event<void(A0)>*>(data) ->call(a0); } private: FuncPtr<void(A0)> _func; EventQueue *_queue; int _delay; int _period; int _tolerance; }; /** Pendable event class */ template <> class Event<void()> { public: /** Create an event bound to a queue */ Event(EventQueue *queue=0, FuncPtr<void()> func=0) { _delay = 0; _period = -1; attach(queue, func); } /** Create an event bound to a queue */ template <typename T, typename M> Event(EventQueue *queue, T *obj, M method) { _delay = 0; _period = -1; attach(queue, obj, method); } /** Attach an event to a queue */ void attach(EventQueue *queue) { _queue = queue; } /** Attach a callback to an event */ void attach(FuncPtr<void()> func) { _func.attach(func); } /** Attach a callback to an event */ template <typename T, typename M> void attach(T *obj, M method) { attach(FuncPtr<void()>(obj, method)); } /** Attach a func to an event */ void attach(EventQueue *queue, FuncPtr<void()> func) { attach(queue); attach(func); } /** Attach an event to a queue */ template <typename T, typename M> void attach(EventQueue *queue, T *obj, M method) { attach(queue); attach(obj, method); } /** Set delay for when the event is dispatched after it is posted * @param ms Delay in milliseconds */ void delay(int ms) { _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { _period = ms; } /** Set tolerance hint on when the event must be called, defaults to 0 * @param ms Tolerance in milliseconds */ void tolerance(int ms) { _tolerance = ms; } /** Post the event onto the bound queue * @param ms Max time to wait if memory is not available in milliseconds * @return True if the event was posted successfully */ bool trigger(int ms=-1) { return _queue->trigger(_func, _delay, _period, _tolerance, ms); } /** Post the event onto the bound queue */ void call() { trigger(); } /** Post the event onto the bound queue */ void operator()() { return call(); } /** Test if event has been bound */ operator bool() const { return _func && _queue; } /** Static thunk for passing as C-style function * @param data Event to dispatch passed as void pointer */ static void thunk(void *data) { return static_cast<Event<void()>*>(data) ->call(); } private: FuncPtr<void()> _func; EventQueue *_queue; int _delay; int _period; int _tolerance; }; #endif