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: Event.h
- Revision:
- 4:30883e8633b4
- Parent:
- 3:6dccdc36651f
- Child:
- 12:1feb78280125
--- a/Event.h Wed Apr 20 14:31:17 2016 -0500 +++ b/Event.h Sun Apr 17 23:50:50 2016 -0500 @@ -17,6 +17,122 @@ /** 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 unbound event + */ + Event() { + memset(&_event, 0, sizeof _event); + _event.delay = 0; + _event.period = -1; + } + + /** Create an event bound to a queue + */ + Event(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3, A4)> callback) { + memset(&_event, 0, sizeof _event); + _event.delay = 0; + _event.period = -1; + attach(queue, callback); + } + + /** Create an event bound to a queue + */ + template <typename T, typename M> + Event(EventQueue *queue, T *obj, M method) { + memset(&_event, 0, sizeof _event); + _event.delay = 0; + _event.period = -1; + attach(queue, obj, method); + } + + /** Safe lifetime management + */ + ~Event() { + cancel(); + } + + /** Attach an event to a queue + */ + void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3, A4)> callback) { + _queue = queue; + _callback.attach(callback); + } + + /** Attach an event to a queue + */ + template <typename T, typename M> + void attach(EventQueue *queue, T *obj, M method) { + _queue = queue; + _callback.attach(FuncPtr<void(A0, A1, A2, A3, A4)>(obj, method)); + } + + /** Set delay for when the event is dispatched after it is posted + * @param ms Delay in milliseconds + */ + void delay(int ms) { + _event.delay = ms; + } + + /** Set event to repeat periodically after it is posted + * @param ms period in milliseconds + */ + void period(int ms) { + _event.period = ms; + } + + /** Set tolerance hint on when the event must be called, defaults to 0 + * @param ms tolerance in milliseconds + */ + void tolerance(int ms) { + (void)ms; // currently ignored + } + + /** Post the event onto the bound queue + */ + void call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) { + _bind.attach(_callback, a0, a1, a2, a3, a4); + _event.callback = Binder<void(A0, A1, A2, A3, A4), A0, A1, A2, A3, A4>::thunk; + _event.data = &_bind; + _queue->event_register(&_event, _event.delay); + } + + /** 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 _callback && _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); + } + + /** Cancel a pending event + */ + void cancel() { + _queue->event_unregister(&_event); + } + +private: + EventQueue *_queue; + EventQueue::event _event; + FuncPtr<void(A0, A1, A2, A3, A4)> _callback; + Binder<void(A0, A1, A2, A3, A4), A0, A1, A2, A3, A4> _bind; +}; + +/** Pendable event class + */ template <typename A0, typename A1, typename A2, typename A3> class Event<void(A0, A1, A2, A3)> { public: