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:
- 14:5abf2ccf2dbf
- Parent:
- 13:b84e049b2d9c
- Child:
- 17:6d564266850e
--- a/Event.h Fri Apr 22 22:32:35 2016 -0500 +++ b/Event.h Tue May 10 07:51:44 2016 -0500 @@ -22,29 +22,21 @@ public: /** Create an event bound to a queue */ - Event(EventQueue *queue=0, FuncPtr<void(A0, A1, A2, A3, A4)> callback=0) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; - attach(queue, callback); + 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) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; + _delay = 0; + _period = -1; attach(queue, obj, method); } - /** Safe lifetime management - */ - ~Event() { - cancel(); - } - /** Attach an event to a queue */ void attach(EventQueue *queue) { @@ -53,8 +45,8 @@ /** Attach a callback to an event */ - void attach(FuncPtr<void(A0, A1, A2, A3, A4)> callback) { - _callback.attach(callback); + void attach(FuncPtr<void(A0, A1, A2, A3, A4)> func) { + _func.attach(func); } /** Attach a callback to an event @@ -64,11 +56,11 @@ attach(FuncPtr<void(A0, A1, A2, A3, A4)>(obj, method)); } - /** Attach a callback to an event + /** Attach a func to an event */ - void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3, A4)> callback) { + void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3, A4)> func) { attach(queue); - attach(callback); + attach(func); } /** Attach an event to a queue @@ -83,36 +75,31 @@ * @param ms Delay in milliseconds */ void delay(int ms) { - _event.delay = ms; + _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { - _event.period = 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) { - (void)ms; // currently ignored + _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) { - if (_event.registered) { - return false; - } - - _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); - return true; + 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 @@ -130,7 +117,7 @@ /** Test if event has been bound */ operator bool() const { - return _callback && _queue; + return _func && _queue; } /** Static thunk for passing as C-style function @@ -141,17 +128,12 @@ ->call(a0, a1, a2, a3, a4); } - /** Cancel a pending event - */ - void cancel() { - _queue->event_unregister(&_event); - } - private: + FuncPtr<void(A0,A1,A2,A3,A4)> _func; 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; + int _delay; + int _period; + int _tolerance; }; /** Pendable event class @@ -161,29 +143,21 @@ public: /** Create an event bound to a queue */ - Event(EventQueue *queue=0, FuncPtr<void(A0, A1, A2, A3)> callback=0) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; - attach(queue, callback); + 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) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; + _delay = 0; + _period = -1; attach(queue, obj, method); } - /** Safe lifetime management - */ - ~Event() { - cancel(); - } - /** Attach an event to a queue */ void attach(EventQueue *queue) { @@ -192,8 +166,8 @@ /** Attach a callback to an event */ - void attach(FuncPtr<void(A0, A1, A2, A3)> callback) { - _callback.attach(callback); + void attach(FuncPtr<void(A0, A1, A2, A3)> func) { + _func.attach(func); } /** Attach a callback to an event @@ -203,11 +177,11 @@ attach(FuncPtr<void(A0, A1, A2, A3)>(obj, method)); } - /** Attach a callback to an event + /** Attach a func to an event */ - void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3)> callback) { + void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3)> func) { attach(queue); - attach(callback); + attach(func); } /** Attach an event to a queue @@ -222,35 +196,31 @@ * @param ms Delay in milliseconds */ void delay(int ms) { - _event.delay = ms; + _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { - _event.period = 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) { - (void)ms; // currently ignored + _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) { - if (_event.registered) { - return false; - } - - _bind.attach(_callback, a0, a1, a2, a3); - _event.callback = Binder<void(A0, A1, A2, A3), A0, A1, A2, A3>::thunk; - _event.data = &_bind; - _queue->event_register(&_event, _event.delay); - return true; + 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 @@ -268,7 +238,7 @@ /** Test if event has been bound */ operator bool() const { - return _callback && _queue; + return _func && _queue; } /** Static thunk for passing as C-style function @@ -279,17 +249,12 @@ ->call(a0, a1, a2, a3); } - /** Cancel a pending event - */ - void cancel() { - _queue->event_unregister(&_event); - } - private: + FuncPtr<void(A0,A1,A2,A3)> _func; EventQueue *_queue; - EventQueue::event _event; - FuncPtr<void(A0, A1, A2, A3)> _callback; - Binder<void(A0, A1, A2, A3), A0, A1, A2, A3> _bind; + int _delay; + int _period; + int _tolerance; }; /** Pendable event class @@ -299,29 +264,21 @@ public: /** Create an event bound to a queue */ - Event(EventQueue *queue=0, FuncPtr<void(A0, A1, A2)> callback=0) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; - attach(queue, callback); + 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) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; + _delay = 0; + _period = -1; attach(queue, obj, method); } - /** Safe lifetime management - */ - ~Event() { - cancel(); - } - /** Attach an event to a queue */ void attach(EventQueue *queue) { @@ -330,8 +287,8 @@ /** Attach a callback to an event */ - void attach(FuncPtr<void(A0, A1, A2)> callback) { - _callback.attach(callback); + void attach(FuncPtr<void(A0, A1, A2)> func) { + _func.attach(func); } /** Attach a callback to an event @@ -341,11 +298,11 @@ attach(FuncPtr<void(A0, A1, A2)>(obj, method)); } - /** Attach a callback to an event + /** Attach a func to an event */ - void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2)> callback) { + void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2)> func) { attach(queue); - attach(callback); + attach(func); } /** Attach an event to a queue @@ -360,35 +317,31 @@ * @param ms Delay in milliseconds */ void delay(int ms) { - _event.delay = ms; + _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { - _event.period = 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) { - (void)ms; // currently ignored + _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) { - if (_event.registered) { - return false; - } - - _bind.attach(_callback, a0, a1, a2); - _event.callback = Binder<void(A0, A1, A2), A0, A1, A2>::thunk; - _event.data = &_bind; - _queue->event_register(&_event, _event.delay); - return true; + 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 @@ -406,7 +359,7 @@ /** Test if event has been bound */ operator bool() const { - return _callback && _queue; + return _func && _queue; } /** Static thunk for passing as C-style function @@ -417,17 +370,12 @@ ->call(a0, a1, a2); } - /** Cancel a pending event - */ - void cancel() { - _queue->event_unregister(&_event); - } - private: + FuncPtr<void(A0,A1,A2)> _func; EventQueue *_queue; - EventQueue::event _event; - FuncPtr<void(A0, A1, A2)> _callback; - Binder<void(A0, A1, A2), A0, A1, A2> _bind; + int _delay; + int _period; + int _tolerance; }; /** Pendable event class @@ -437,29 +385,21 @@ public: /** Create an event bound to a queue */ - Event(EventQueue *queue=0, FuncPtr<void(A0, A1)> callback=0) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; - attach(queue, callback); + 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) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; + _delay = 0; + _period = -1; attach(queue, obj, method); } - /** Safe lifetime management - */ - ~Event() { - cancel(); - } - /** Attach an event to a queue */ void attach(EventQueue *queue) { @@ -468,8 +408,8 @@ /** Attach a callback to an event */ - void attach(FuncPtr<void(A0, A1)> callback) { - _callback.attach(callback); + void attach(FuncPtr<void(A0, A1)> func) { + _func.attach(func); } /** Attach a callback to an event @@ -479,11 +419,11 @@ attach(FuncPtr<void(A0, A1)>(obj, method)); } - /** Attach a callback to an event + /** Attach a func to an event */ - void attach(EventQueue *queue, FuncPtr<void(A0, A1)> callback) { + void attach(EventQueue *queue, FuncPtr<void(A0, A1)> func) { attach(queue); - attach(callback); + attach(func); } /** Attach an event to a queue @@ -498,35 +438,31 @@ * @param ms Delay in milliseconds */ void delay(int ms) { - _event.delay = ms; + _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { - _event.period = 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) { - (void)ms; // currently ignored + _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) { - if (_event.registered) { - return false; - } - - _bind.attach(_callback, a0, a1); - _event.callback = Binder<void(A0, A1), A0, A1>::thunk; - _event.data = &_bind; - _queue->event_register(&_event, _event.delay); - return true; + 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 @@ -544,7 +480,7 @@ /** Test if event has been bound */ operator bool() const { - return _callback && _queue; + return _func && _queue; } /** Static thunk for passing as C-style function @@ -555,17 +491,12 @@ ->call(a0, a1); } - /** Cancel a pending event - */ - void cancel() { - _queue->event_unregister(&_event); - } - private: + FuncPtr<void(A0,A1)> _func; EventQueue *_queue; - EventQueue::event _event; - FuncPtr<void(A0, A1)> _callback; - Binder<void(A0, A1), A0, A1> _bind; + int _delay; + int _period; + int _tolerance; }; /** Pendable event class @@ -575,29 +506,21 @@ public: /** Create an event bound to a queue */ - Event(EventQueue *queue=0, FuncPtr<void(A0)> callback=0) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; - attach(queue, callback); + 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) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; + _delay = 0; + _period = -1; attach(queue, obj, method); } - /** Safe lifetime management - */ - ~Event() { - cancel(); - } - /** Attach an event to a queue */ void attach(EventQueue *queue) { @@ -606,8 +529,8 @@ /** Attach a callback to an event */ - void attach(FuncPtr<void(A0)> callback) { - _callback.attach(callback); + void attach(FuncPtr<void(A0)> func) { + _func.attach(func); } /** Attach a callback to an event @@ -617,11 +540,11 @@ attach(FuncPtr<void(A0)>(obj, method)); } - /** Attach a callback to an event + /** Attach a func to an event */ - void attach(EventQueue *queue, FuncPtr<void(A0)> callback) { + void attach(EventQueue *queue, FuncPtr<void(A0)> func) { attach(queue); - attach(callback); + attach(func); } /** Attach an event to a queue @@ -636,35 +559,31 @@ * @param ms Delay in milliseconds */ void delay(int ms) { - _event.delay = ms; + _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { - _event.period = 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) { - (void)ms; // currently ignored + _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) { - if (_event.registered) { - return false; - } - - _bind.attach(_callback, a0); - _event.callback = Binder<void(A0), A0>::thunk; - _event.data = &_bind; - _queue->event_register(&_event, _event.delay); - return true; + 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 @@ -682,7 +601,7 @@ /** Test if event has been bound */ operator bool() const { - return _callback && _queue; + return _func && _queue; } /** Static thunk for passing as C-style function @@ -693,17 +612,12 @@ ->call(a0); } - /** Cancel a pending event - */ - void cancel() { - _queue->event_unregister(&_event); - } - private: + FuncPtr<void(A0)> _func; EventQueue *_queue; - EventQueue::event _event; - FuncPtr<void(A0)> _callback; - Binder<void(A0), A0> _bind; + int _delay; + int _period; + int _tolerance; }; /** Pendable event class @@ -711,39 +625,23 @@ template <> class Event<void()> { 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=0, FuncPtr<void()> callback=0) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; - attach(queue, callback); + 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) { - memset(&_event, 0, sizeof _event); - _event.delay = 0; - _event.period = -1; + _delay = 0; + _period = -1; attach(queue, obj, method); } - /** Safe lifetime management - */ - ~Event() { - cancel(); - } - /** Attach an event to a queue */ void attach(EventQueue *queue) { @@ -752,8 +650,8 @@ /** Attach a callback to an event */ - void attach(FuncPtr<void()> callback) { - _callback.attach(callback); + void attach(FuncPtr<void()> func) { + _func.attach(func); } /** Attach a callback to an event @@ -763,11 +661,11 @@ attach(FuncPtr<void()>(obj, method)); } - /** Attach a callback to an event + /** Attach a func to an event */ - void attach(EventQueue *queue, FuncPtr<void()> callback) { + void attach(EventQueue *queue, FuncPtr<void()> func) { attach(queue); - attach(callback); + attach(func); } /** Attach an event to a queue @@ -782,34 +680,29 @@ * @param ms Delay in milliseconds */ void delay(int ms) { - _event.delay = ms; + _delay = ms; } /** Set event to repeat periodically after it is posted * @param ms Period in milliseconds */ void period(int ms) { - _event.period = 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) { - (void)ms; // currently ignored + _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() { - if (_event.registered) { - return false; - } - - _event.callback = FuncPtr<void()>::thunk; - _event.data = &_callback; - _queue->event_register(&_event, _event.delay); - return true; + bool trigger(int ms=-1) { + return _queue->trigger(_func, _delay, _period, _tolerance, ms); } /** Post the event onto the bound queue @@ -827,7 +720,7 @@ /** Test if event has been bound */ operator bool() const { - return _callback && _queue; + return _func && _queue; } /** Static thunk for passing as C-style function @@ -838,16 +731,12 @@ ->call(); } - /** Cancel a pending event - */ - void cancel() { - _queue->event_unregister(&_event); - } - private: + FuncPtr<void()> _func; EventQueue *_queue; - EventQueue::event _event; - FuncPtr<void()> _callback; + int _delay; + int _period; + int _tolerance; };