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

Dependents:   SimpleHTTPExample

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.

Committer:
Christopher Haster
Date:
Wed Apr 20 14:15:54 2016 -0500
Revision:
2:11cda6bead99
Parent:
0:b1b901ae3696
Child:
3:6dccdc36651f
Add support for delay/period on events

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Christopher Haster 0:b1b901ae3696 1 /* Event
Christopher Haster 0:b1b901ae3696 2 *
Christopher Haster 0:b1b901ae3696 3 * Pendable event
Christopher Haster 0:b1b901ae3696 4 */
Christopher Haster 0:b1b901ae3696 5 #ifndef EVENT_H
Christopher Haster 0:b1b901ae3696 6 #define EVENT_H
Christopher Haster 0:b1b901ae3696 7
Christopher Haster 0:b1b901ae3696 8 #include "EventQueue.h"
Christopher Haster 0:b1b901ae3696 9 #include "FuncPtr.h"
Christopher Haster 0:b1b901ae3696 10 #include "Binder.h"
Christopher Haster 0:b1b901ae3696 11
Christopher Haster 0:b1b901ae3696 12
Christopher Haster 0:b1b901ae3696 13 /** Pendable event class
Christopher Haster 0:b1b901ae3696 14 */
Christopher Haster 0:b1b901ae3696 15 template <typename F>
Christopher Haster 0:b1b901ae3696 16 class Event;
Christopher Haster 0:b1b901ae3696 17
Christopher Haster 0:b1b901ae3696 18 /** Pendable event class
Christopher Haster 0:b1b901ae3696 19 */
Christopher Haster 0:b1b901ae3696 20 template <typename A0, typename A1, typename A2, typename A3>
Christopher Haster 0:b1b901ae3696 21 class Event<void(A0, A1, A2, A3)> {
Christopher Haster 0:b1b901ae3696 22 public:
Christopher Haster 0:b1b901ae3696 23 /** Create an unbound event
Christopher Haster 0:b1b901ae3696 24 */
Christopher Haster 2:11cda6bead99 25 Event() {
Christopher Haster 2:11cda6bead99 26 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 27 _event.delay = 0;
Christopher Haster 2:11cda6bead99 28 _event.period = -1;
Christopher Haster 2:11cda6bead99 29 }
Christopher Haster 0:b1b901ae3696 30
Christopher Haster 0:b1b901ae3696 31 /** Create an event bound to a queue
Christopher Haster 0:b1b901ae3696 32 */
Christopher Haster 0:b1b901ae3696 33 Event(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3)> callback) {
Christopher Haster 2:11cda6bead99 34 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 35 _event.delay = 0;
Christopher Haster 2:11cda6bead99 36 _event.period = -1;
Christopher Haster 0:b1b901ae3696 37 attach(queue, callback);
Christopher Haster 0:b1b901ae3696 38 }
Christopher Haster 0:b1b901ae3696 39
Christopher Haster 0:b1b901ae3696 40 /** Safe lifetime management
Christopher Haster 0:b1b901ae3696 41 */
Christopher Haster 0:b1b901ae3696 42 ~Event() {
Christopher Haster 0:b1b901ae3696 43 cancel();
Christopher Haster 0:b1b901ae3696 44 }
Christopher Haster 0:b1b901ae3696 45
Christopher Haster 0:b1b901ae3696 46 /** Attach an event to a queue
Christopher Haster 0:b1b901ae3696 47 */
Christopher Haster 0:b1b901ae3696 48 void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3)> callback) {
Christopher Haster 0:b1b901ae3696 49 _queue = queue;
Christopher Haster 0:b1b901ae3696 50 _callback.attach(callback);
Christopher Haster 0:b1b901ae3696 51 }
Christopher Haster 0:b1b901ae3696 52
Christopher Haster 2:11cda6bead99 53 /** Set delay for when the event is dispatched after it is posted
Christopher Haster 2:11cda6bead99 54 * @param ms Delay in milliseconds
Christopher Haster 2:11cda6bead99 55 */
Christopher Haster 2:11cda6bead99 56 void delay(int ms) {
Christopher Haster 2:11cda6bead99 57 _event.delay = ms;
Christopher Haster 2:11cda6bead99 58 }
Christopher Haster 2:11cda6bead99 59
Christopher Haster 2:11cda6bead99 60 /** Set event to repeat periodically after it is posted
Christopher Haster 2:11cda6bead99 61 * @param ms period in milliseconds
Christopher Haster 2:11cda6bead99 62 */
Christopher Haster 2:11cda6bead99 63 void period(int ms) {
Christopher Haster 2:11cda6bead99 64 _event.period = ms;
Christopher Haster 2:11cda6bead99 65 }
Christopher Haster 2:11cda6bead99 66
Christopher Haster 2:11cda6bead99 67 /** Set tolerance hint on when the event must be called, defaults to 0
Christopher Haster 2:11cda6bead99 68 * @param ms tolerance in milliseconds
Christopher Haster 2:11cda6bead99 69 */
Christopher Haster 2:11cda6bead99 70 void tolerance(int ms) {
Christopher Haster 2:11cda6bead99 71 (void)ms; // currently ignored
Christopher Haster 2:11cda6bead99 72 }
Christopher Haster 2:11cda6bead99 73
Christopher Haster 2:11cda6bead99 74 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 75 */
Christopher Haster 0:b1b901ae3696 76 void call(A0 a0, A1 a1, A2 a2, A3 a3) {
Christopher Haster 0:b1b901ae3696 77 _bind.attach(_callback, a0, a1, a2, a3);
Christopher Haster 0:b1b901ae3696 78 _event.callback = Binder<void(A0, A1, A2, A3), A0, A1, A2, A3>::thunk;
Christopher Haster 0:b1b901ae3696 79 _event.data = &_bind;
Christopher Haster 2:11cda6bead99 80 _queue->event_register(&_event, _event.delay);
Christopher Haster 0:b1b901ae3696 81 }
Christopher Haster 0:b1b901ae3696 82
Christopher Haster 2:11cda6bead99 83 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 84 */
Christopher Haster 0:b1b901ae3696 85 void operator()(A0 a0, A1 a1, A2 a2, A3 a3) {
Christopher Haster 0:b1b901ae3696 86 return call(a0, a1, a2, a3);
Christopher Haster 0:b1b901ae3696 87 }
Christopher Haster 0:b1b901ae3696 88
Christopher Haster 0:b1b901ae3696 89 /** Test if event has been bound
Christopher Haster 0:b1b901ae3696 90 */
Christopher Haster 0:b1b901ae3696 91 operator bool() const {
Christopher Haster 0:b1b901ae3696 92 return _callback && _queue;
Christopher Haster 0:b1b901ae3696 93 }
Christopher Haster 0:b1b901ae3696 94
Christopher Haster 0:b1b901ae3696 95 /** Static thunk for passing as C-style function
Christopher Haster 0:b1b901ae3696 96 * @param data Event to dispatch passed as void pointer
Christopher Haster 0:b1b901ae3696 97 */
Christopher Haster 0:b1b901ae3696 98 static void thunk(void *data, A0 a0, A1 a1, A2 a2, A3 a3) {
Christopher Haster 0:b1b901ae3696 99 return static_cast<Event<void(A0, A1, A2, A3)>*>(data)
Christopher Haster 0:b1b901ae3696 100 ->call(a0, a1, a2, a3);
Christopher Haster 0:b1b901ae3696 101 }
Christopher Haster 0:b1b901ae3696 102
Christopher Haster 0:b1b901ae3696 103 /** Cancel a pending event
Christopher Haster 0:b1b901ae3696 104 */
Christopher Haster 0:b1b901ae3696 105 void cancel() {
Christopher Haster 0:b1b901ae3696 106 _queue->event_unregister(&_event);
Christopher Haster 0:b1b901ae3696 107 }
Christopher Haster 0:b1b901ae3696 108
Christopher Haster 0:b1b901ae3696 109 private:
Christopher Haster 0:b1b901ae3696 110 EventQueue *_queue;
Christopher Haster 0:b1b901ae3696 111 EventQueue::event _event;
Christopher Haster 0:b1b901ae3696 112 FuncPtr<void(A0, A1, A2, A3)> _callback;
Christopher Haster 0:b1b901ae3696 113 Binder<void(A0, A1, A2, A3), A0, A1, A2, A3> _bind;
Christopher Haster 0:b1b901ae3696 114 };
Christopher Haster 0:b1b901ae3696 115
Christopher Haster 0:b1b901ae3696 116 /** Pendable event class
Christopher Haster 0:b1b901ae3696 117 */
Christopher Haster 0:b1b901ae3696 118 template <typename A0, typename A1, typename A2>
Christopher Haster 0:b1b901ae3696 119 class Event<void(A0, A1, A2)> {
Christopher Haster 0:b1b901ae3696 120 public:
Christopher Haster 0:b1b901ae3696 121 /** Create an unbound event
Christopher Haster 0:b1b901ae3696 122 */
Christopher Haster 2:11cda6bead99 123 Event() {
Christopher Haster 2:11cda6bead99 124 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 125 _event.delay = 0;
Christopher Haster 2:11cda6bead99 126 _event.period = -1;
Christopher Haster 2:11cda6bead99 127 }
Christopher Haster 0:b1b901ae3696 128
Christopher Haster 0:b1b901ae3696 129 /** Create an event bound to a queue
Christopher Haster 0:b1b901ae3696 130 */
Christopher Haster 0:b1b901ae3696 131 Event(EventQueue *queue, FuncPtr<void(A0, A1, A2)> callback) {
Christopher Haster 2:11cda6bead99 132 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 133 _event.delay = 0;
Christopher Haster 2:11cda6bead99 134 _event.period = -1;
Christopher Haster 0:b1b901ae3696 135 attach(queue, callback);
Christopher Haster 0:b1b901ae3696 136 }
Christopher Haster 0:b1b901ae3696 137
Christopher Haster 0:b1b901ae3696 138 /** Safe lifetime management
Christopher Haster 0:b1b901ae3696 139 */
Christopher Haster 0:b1b901ae3696 140 ~Event() {
Christopher Haster 0:b1b901ae3696 141 cancel();
Christopher Haster 0:b1b901ae3696 142 }
Christopher Haster 0:b1b901ae3696 143
Christopher Haster 0:b1b901ae3696 144 /** Attach an event to a queue
Christopher Haster 0:b1b901ae3696 145 */
Christopher Haster 0:b1b901ae3696 146 void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2)> callback) {
Christopher Haster 0:b1b901ae3696 147 _queue = queue;
Christopher Haster 0:b1b901ae3696 148 _callback.attach(callback);
Christopher Haster 0:b1b901ae3696 149 }
Christopher Haster 0:b1b901ae3696 150
Christopher Haster 2:11cda6bead99 151 /** Set delay for when the event is dispatched after it is posted
Christopher Haster 2:11cda6bead99 152 * @param ms Delay in milliseconds
Christopher Haster 2:11cda6bead99 153 */
Christopher Haster 2:11cda6bead99 154 void delay(int ms) {
Christopher Haster 2:11cda6bead99 155 _event.delay = ms;
Christopher Haster 2:11cda6bead99 156 }
Christopher Haster 2:11cda6bead99 157
Christopher Haster 2:11cda6bead99 158 /** Set event to repeat periodically after it is posted
Christopher Haster 2:11cda6bead99 159 * @param ms period in milliseconds
Christopher Haster 2:11cda6bead99 160 */
Christopher Haster 2:11cda6bead99 161 void period(int ms) {
Christopher Haster 2:11cda6bead99 162 _event.period = ms;
Christopher Haster 2:11cda6bead99 163 }
Christopher Haster 2:11cda6bead99 164
Christopher Haster 2:11cda6bead99 165 /** Set tolerance hint on when the event must be called, defaults to 0
Christopher Haster 2:11cda6bead99 166 * @param ms tolerance in milliseconds
Christopher Haster 2:11cda6bead99 167 */
Christopher Haster 2:11cda6bead99 168 void tolerance(int ms) {
Christopher Haster 2:11cda6bead99 169 (void)ms; // currently ignored
Christopher Haster 2:11cda6bead99 170 }
Christopher Haster 2:11cda6bead99 171
Christopher Haster 2:11cda6bead99 172 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 173 */
Christopher Haster 0:b1b901ae3696 174 void call(A0 a0, A1 a1, A2 a2) {
Christopher Haster 0:b1b901ae3696 175 _bind.attach(_callback, a0, a1, a2);
Christopher Haster 0:b1b901ae3696 176 _event.callback = Binder<void(A0, A1, A2), A0, A1, A2>::thunk;
Christopher Haster 0:b1b901ae3696 177 _event.data = &_bind;
Christopher Haster 2:11cda6bead99 178 _queue->event_register(&_event, _event.delay);
Christopher Haster 0:b1b901ae3696 179 }
Christopher Haster 0:b1b901ae3696 180
Christopher Haster 2:11cda6bead99 181 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 182 */
Christopher Haster 0:b1b901ae3696 183 void operator()(A0 a0, A1 a1, A2 a2) {
Christopher Haster 0:b1b901ae3696 184 return call(a0, a1, a2);
Christopher Haster 0:b1b901ae3696 185 }
Christopher Haster 0:b1b901ae3696 186
Christopher Haster 0:b1b901ae3696 187 /** Test if event has been bound
Christopher Haster 0:b1b901ae3696 188 */
Christopher Haster 0:b1b901ae3696 189 operator bool() const {
Christopher Haster 0:b1b901ae3696 190 return _callback && _queue;
Christopher Haster 0:b1b901ae3696 191 }
Christopher Haster 0:b1b901ae3696 192
Christopher Haster 0:b1b901ae3696 193 /** Static thunk for passing as C-style function
Christopher Haster 0:b1b901ae3696 194 * @param data Event to dispatch passed as void pointer
Christopher Haster 0:b1b901ae3696 195 */
Christopher Haster 0:b1b901ae3696 196 static void thunk(void *data, A0 a0, A1 a1, A2 a2) {
Christopher Haster 0:b1b901ae3696 197 return static_cast<Event<void(A0, A1, A2)>*>(data)
Christopher Haster 0:b1b901ae3696 198 ->call(a0, a1, a2);
Christopher Haster 0:b1b901ae3696 199 }
Christopher Haster 0:b1b901ae3696 200
Christopher Haster 0:b1b901ae3696 201 /** Cancel a pending event
Christopher Haster 0:b1b901ae3696 202 */
Christopher Haster 0:b1b901ae3696 203 void cancel() {
Christopher Haster 0:b1b901ae3696 204 _queue->event_unregister(&_event);
Christopher Haster 0:b1b901ae3696 205 }
Christopher Haster 0:b1b901ae3696 206
Christopher Haster 0:b1b901ae3696 207 private:
Christopher Haster 0:b1b901ae3696 208 EventQueue *_queue;
Christopher Haster 0:b1b901ae3696 209 EventQueue::event _event;
Christopher Haster 0:b1b901ae3696 210 FuncPtr<void(A0, A1, A2)> _callback;
Christopher Haster 0:b1b901ae3696 211 Binder<void(A0, A1, A2), A0, A1, A2> _bind;
Christopher Haster 0:b1b901ae3696 212 };
Christopher Haster 0:b1b901ae3696 213
Christopher Haster 0:b1b901ae3696 214 /** Pendable event class
Christopher Haster 0:b1b901ae3696 215 */
Christopher Haster 0:b1b901ae3696 216 template <typename A0, typename A1>
Christopher Haster 0:b1b901ae3696 217 class Event<void(A0, A1)> {
Christopher Haster 0:b1b901ae3696 218 public:
Christopher Haster 0:b1b901ae3696 219 /** Create an unbound event
Christopher Haster 0:b1b901ae3696 220 */
Christopher Haster 2:11cda6bead99 221 Event() {
Christopher Haster 2:11cda6bead99 222 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 223 _event.delay = 0;
Christopher Haster 2:11cda6bead99 224 _event.period = -1;
Christopher Haster 2:11cda6bead99 225 }
Christopher Haster 0:b1b901ae3696 226
Christopher Haster 0:b1b901ae3696 227 /** Create an event bound to a queue
Christopher Haster 0:b1b901ae3696 228 */
Christopher Haster 0:b1b901ae3696 229 Event(EventQueue *queue, FuncPtr<void(A0, A1)> callback) {
Christopher Haster 2:11cda6bead99 230 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 231 _event.delay = 0;
Christopher Haster 2:11cda6bead99 232 _event.period = -1;
Christopher Haster 0:b1b901ae3696 233 attach(queue, callback);
Christopher Haster 0:b1b901ae3696 234 }
Christopher Haster 0:b1b901ae3696 235
Christopher Haster 0:b1b901ae3696 236 /** Safe lifetime management
Christopher Haster 0:b1b901ae3696 237 */
Christopher Haster 0:b1b901ae3696 238 ~Event() {
Christopher Haster 0:b1b901ae3696 239 cancel();
Christopher Haster 0:b1b901ae3696 240 }
Christopher Haster 0:b1b901ae3696 241
Christopher Haster 0:b1b901ae3696 242 /** Attach an event to a queue
Christopher Haster 0:b1b901ae3696 243 */
Christopher Haster 0:b1b901ae3696 244 void attach(EventQueue *queue, FuncPtr<void(A0, A1)> callback) {
Christopher Haster 0:b1b901ae3696 245 _queue = queue;
Christopher Haster 0:b1b901ae3696 246 _callback.attach(callback);
Christopher Haster 0:b1b901ae3696 247 }
Christopher Haster 0:b1b901ae3696 248
Christopher Haster 2:11cda6bead99 249 /** Set delay for when the event is dispatched after it is posted
Christopher Haster 2:11cda6bead99 250 * @param ms Delay in milliseconds
Christopher Haster 2:11cda6bead99 251 */
Christopher Haster 2:11cda6bead99 252 void delay(int ms) {
Christopher Haster 2:11cda6bead99 253 _event.delay = ms;
Christopher Haster 2:11cda6bead99 254 }
Christopher Haster 2:11cda6bead99 255
Christopher Haster 2:11cda6bead99 256 /** Set event to repeat periodically after it is posted
Christopher Haster 2:11cda6bead99 257 * @param ms period in milliseconds
Christopher Haster 2:11cda6bead99 258 */
Christopher Haster 2:11cda6bead99 259 void period(int ms) {
Christopher Haster 2:11cda6bead99 260 _event.period = ms;
Christopher Haster 2:11cda6bead99 261 }
Christopher Haster 2:11cda6bead99 262
Christopher Haster 2:11cda6bead99 263 /** Set tolerance hint on when the event must be called, defaults to 0
Christopher Haster 2:11cda6bead99 264 * @param ms tolerance in milliseconds
Christopher Haster 2:11cda6bead99 265 */
Christopher Haster 2:11cda6bead99 266 void tolerance(int ms) {
Christopher Haster 2:11cda6bead99 267 (void)ms; // currently ignored
Christopher Haster 2:11cda6bead99 268 }
Christopher Haster 2:11cda6bead99 269
Christopher Haster 2:11cda6bead99 270 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 271 */
Christopher Haster 0:b1b901ae3696 272 void call(A0 a0, A1 a1) {
Christopher Haster 0:b1b901ae3696 273 _bind.attach(_callback, a0, a1);
Christopher Haster 0:b1b901ae3696 274 _event.callback = Binder<void(A0, A1), A0, A1>::thunk;
Christopher Haster 0:b1b901ae3696 275 _event.data = &_bind;
Christopher Haster 2:11cda6bead99 276 _queue->event_register(&_event, _event.delay);
Christopher Haster 0:b1b901ae3696 277 }
Christopher Haster 0:b1b901ae3696 278
Christopher Haster 2:11cda6bead99 279 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 280 */
Christopher Haster 0:b1b901ae3696 281 void operator()(A0 a0, A1 a1) {
Christopher Haster 0:b1b901ae3696 282 return call(a0, a1);
Christopher Haster 0:b1b901ae3696 283 }
Christopher Haster 0:b1b901ae3696 284
Christopher Haster 0:b1b901ae3696 285 /** Test if event has been bound
Christopher Haster 0:b1b901ae3696 286 */
Christopher Haster 0:b1b901ae3696 287 operator bool() const {
Christopher Haster 0:b1b901ae3696 288 return _callback && _queue;
Christopher Haster 0:b1b901ae3696 289 }
Christopher Haster 0:b1b901ae3696 290
Christopher Haster 0:b1b901ae3696 291 /** Static thunk for passing as C-style function
Christopher Haster 0:b1b901ae3696 292 * @param data Event to dispatch passed as void pointer
Christopher Haster 0:b1b901ae3696 293 */
Christopher Haster 0:b1b901ae3696 294 static void thunk(void *data, A0 a0, A1 a1) {
Christopher Haster 0:b1b901ae3696 295 return static_cast<Event<void(A0, A1)>*>(data)
Christopher Haster 0:b1b901ae3696 296 ->call(a0, a1);
Christopher Haster 0:b1b901ae3696 297 }
Christopher Haster 0:b1b901ae3696 298
Christopher Haster 0:b1b901ae3696 299 /** Cancel a pending event
Christopher Haster 0:b1b901ae3696 300 */
Christopher Haster 0:b1b901ae3696 301 void cancel() {
Christopher Haster 0:b1b901ae3696 302 _queue->event_unregister(&_event);
Christopher Haster 0:b1b901ae3696 303 }
Christopher Haster 0:b1b901ae3696 304
Christopher Haster 0:b1b901ae3696 305 private:
Christopher Haster 0:b1b901ae3696 306 EventQueue *_queue;
Christopher Haster 0:b1b901ae3696 307 EventQueue::event _event;
Christopher Haster 0:b1b901ae3696 308 FuncPtr<void(A0, A1)> _callback;
Christopher Haster 0:b1b901ae3696 309 Binder<void(A0, A1), A0, A1> _bind;
Christopher Haster 0:b1b901ae3696 310 };
Christopher Haster 0:b1b901ae3696 311
Christopher Haster 0:b1b901ae3696 312 /** Pendable event class
Christopher Haster 0:b1b901ae3696 313 */
Christopher Haster 0:b1b901ae3696 314 template <typename A0>
Christopher Haster 0:b1b901ae3696 315 class Event<void(A0)> {
Christopher Haster 0:b1b901ae3696 316 public:
Christopher Haster 0:b1b901ae3696 317 /** Create an unbound event
Christopher Haster 0:b1b901ae3696 318 */
Christopher Haster 2:11cda6bead99 319 Event() {
Christopher Haster 2:11cda6bead99 320 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 321 _event.delay = 0;
Christopher Haster 2:11cda6bead99 322 _event.period = -1;
Christopher Haster 2:11cda6bead99 323 }
Christopher Haster 0:b1b901ae3696 324
Christopher Haster 0:b1b901ae3696 325 /** Create an event bound to a queue
Christopher Haster 0:b1b901ae3696 326 */
Christopher Haster 0:b1b901ae3696 327 Event(EventQueue *queue, FuncPtr<void(A0)> callback) {
Christopher Haster 2:11cda6bead99 328 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 329 _event.delay = 0;
Christopher Haster 2:11cda6bead99 330 _event.period = -1;
Christopher Haster 0:b1b901ae3696 331 attach(queue, callback);
Christopher Haster 0:b1b901ae3696 332 }
Christopher Haster 0:b1b901ae3696 333
Christopher Haster 0:b1b901ae3696 334 /** Safe lifetime management
Christopher Haster 0:b1b901ae3696 335 */
Christopher Haster 0:b1b901ae3696 336 ~Event() {
Christopher Haster 0:b1b901ae3696 337 cancel();
Christopher Haster 0:b1b901ae3696 338 }
Christopher Haster 0:b1b901ae3696 339
Christopher Haster 0:b1b901ae3696 340 /** Attach an event to a queue
Christopher Haster 0:b1b901ae3696 341 */
Christopher Haster 0:b1b901ae3696 342 void attach(EventQueue *queue, FuncPtr<void(A0)> callback) {
Christopher Haster 0:b1b901ae3696 343 _queue = queue;
Christopher Haster 0:b1b901ae3696 344 _callback.attach(callback);
Christopher Haster 0:b1b901ae3696 345 }
Christopher Haster 0:b1b901ae3696 346
Christopher Haster 2:11cda6bead99 347 /** Set delay for when the event is dispatched after it is posted
Christopher Haster 2:11cda6bead99 348 * @param ms Delay in milliseconds
Christopher Haster 2:11cda6bead99 349 */
Christopher Haster 2:11cda6bead99 350 void delay(int ms) {
Christopher Haster 2:11cda6bead99 351 _event.delay = ms;
Christopher Haster 2:11cda6bead99 352 }
Christopher Haster 2:11cda6bead99 353
Christopher Haster 2:11cda6bead99 354 /** Set event to repeat periodically after it is posted
Christopher Haster 2:11cda6bead99 355 * @param ms period in milliseconds
Christopher Haster 2:11cda6bead99 356 */
Christopher Haster 2:11cda6bead99 357 void period(int ms) {
Christopher Haster 2:11cda6bead99 358 _event.period = ms;
Christopher Haster 2:11cda6bead99 359 }
Christopher Haster 2:11cda6bead99 360
Christopher Haster 2:11cda6bead99 361 /** Set tolerance hint on when the event must be called, defaults to 0
Christopher Haster 2:11cda6bead99 362 * @param ms tolerance in milliseconds
Christopher Haster 2:11cda6bead99 363 */
Christopher Haster 2:11cda6bead99 364 void tolerance(int ms) {
Christopher Haster 2:11cda6bead99 365 (void)ms; // currently ignored
Christopher Haster 2:11cda6bead99 366 }
Christopher Haster 2:11cda6bead99 367
Christopher Haster 2:11cda6bead99 368 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 369 */
Christopher Haster 0:b1b901ae3696 370 void call(A0 a0) {
Christopher Haster 0:b1b901ae3696 371 _bind.attach(_callback, a0);
Christopher Haster 0:b1b901ae3696 372 _event.callback = Binder<void(A0), A0>::thunk;
Christopher Haster 0:b1b901ae3696 373 _event.data = &_bind;
Christopher Haster 2:11cda6bead99 374 _queue->event_register(&_event, _event.delay);
Christopher Haster 0:b1b901ae3696 375 }
Christopher Haster 0:b1b901ae3696 376
Christopher Haster 2:11cda6bead99 377 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 378 */
Christopher Haster 0:b1b901ae3696 379 void operator()(A0 a0) {
Christopher Haster 0:b1b901ae3696 380 return call(a0);
Christopher Haster 0:b1b901ae3696 381 }
Christopher Haster 0:b1b901ae3696 382
Christopher Haster 0:b1b901ae3696 383 /** Test if event has been bound
Christopher Haster 0:b1b901ae3696 384 */
Christopher Haster 0:b1b901ae3696 385 operator bool() const {
Christopher Haster 0:b1b901ae3696 386 return _callback && _queue;
Christopher Haster 0:b1b901ae3696 387 }
Christopher Haster 0:b1b901ae3696 388
Christopher Haster 0:b1b901ae3696 389 /** Static thunk for passing as C-style function
Christopher Haster 0:b1b901ae3696 390 * @param data Event to dispatch passed as void pointer
Christopher Haster 0:b1b901ae3696 391 */
Christopher Haster 0:b1b901ae3696 392 static void thunk(void *data, A0 a0) {
Christopher Haster 0:b1b901ae3696 393 return static_cast<Event<void(A0)>*>(data)
Christopher Haster 0:b1b901ae3696 394 ->call(a0);
Christopher Haster 0:b1b901ae3696 395 }
Christopher Haster 0:b1b901ae3696 396
Christopher Haster 0:b1b901ae3696 397 /** Cancel a pending event
Christopher Haster 0:b1b901ae3696 398 */
Christopher Haster 0:b1b901ae3696 399 void cancel() {
Christopher Haster 0:b1b901ae3696 400 _queue->event_unregister(&_event);
Christopher Haster 0:b1b901ae3696 401 }
Christopher Haster 0:b1b901ae3696 402
Christopher Haster 0:b1b901ae3696 403 private:
Christopher Haster 0:b1b901ae3696 404 EventQueue *_queue;
Christopher Haster 0:b1b901ae3696 405 EventQueue::event _event;
Christopher Haster 0:b1b901ae3696 406 FuncPtr<void(A0)> _callback;
Christopher Haster 0:b1b901ae3696 407 Binder<void(A0), A0> _bind;
Christopher Haster 0:b1b901ae3696 408 };
Christopher Haster 0:b1b901ae3696 409
Christopher Haster 0:b1b901ae3696 410 /** Pendable event class
Christopher Haster 0:b1b901ae3696 411 */
Christopher Haster 0:b1b901ae3696 412 template <>
Christopher Haster 0:b1b901ae3696 413 class Event<void()> {
Christopher Haster 0:b1b901ae3696 414 public:
Christopher Haster 0:b1b901ae3696 415 /** Create an unbound event
Christopher Haster 0:b1b901ae3696 416 */
Christopher Haster 2:11cda6bead99 417 Event() {
Christopher Haster 2:11cda6bead99 418 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 419 _event.delay = 0;
Christopher Haster 2:11cda6bead99 420 _event.period = -1;
Christopher Haster 2:11cda6bead99 421 }
Christopher Haster 0:b1b901ae3696 422
Christopher Haster 0:b1b901ae3696 423 /** Create an event bound to a queue
Christopher Haster 0:b1b901ae3696 424 */
Christopher Haster 0:b1b901ae3696 425 Event(EventQueue *queue, FuncPtr<void()> callback) {
Christopher Haster 2:11cda6bead99 426 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 427 _event.delay = 0;
Christopher Haster 2:11cda6bead99 428 _event.period = -1;
Christopher Haster 0:b1b901ae3696 429 attach(queue, callback);
Christopher Haster 0:b1b901ae3696 430 }
Christopher Haster 0:b1b901ae3696 431
Christopher Haster 0:b1b901ae3696 432 /** Safe lifetime management
Christopher Haster 0:b1b901ae3696 433 */
Christopher Haster 0:b1b901ae3696 434 ~Event() {
Christopher Haster 0:b1b901ae3696 435 cancel();
Christopher Haster 0:b1b901ae3696 436 }
Christopher Haster 0:b1b901ae3696 437
Christopher Haster 0:b1b901ae3696 438 /** Attach an event to a queue
Christopher Haster 0:b1b901ae3696 439 */
Christopher Haster 0:b1b901ae3696 440 void attach(EventQueue *queue, FuncPtr<void()> callback) {
Christopher Haster 0:b1b901ae3696 441 _queue = queue;
Christopher Haster 0:b1b901ae3696 442 _callback.attach(callback);
Christopher Haster 0:b1b901ae3696 443 }
Christopher Haster 0:b1b901ae3696 444
Christopher Haster 2:11cda6bead99 445 /** Set delay for when the event is dispatched after it is posted
Christopher Haster 2:11cda6bead99 446 * @param ms Delay in milliseconds
Christopher Haster 2:11cda6bead99 447 */
Christopher Haster 2:11cda6bead99 448 void delay(int ms) {
Christopher Haster 2:11cda6bead99 449 _event.delay = ms;
Christopher Haster 2:11cda6bead99 450 }
Christopher Haster 2:11cda6bead99 451
Christopher Haster 2:11cda6bead99 452 /** Set event to repeat periodically after it is posted
Christopher Haster 2:11cda6bead99 453 * @param ms period in milliseconds
Christopher Haster 2:11cda6bead99 454 */
Christopher Haster 2:11cda6bead99 455 void period(int ms) {
Christopher Haster 2:11cda6bead99 456 _event.period = ms;
Christopher Haster 2:11cda6bead99 457 }
Christopher Haster 2:11cda6bead99 458
Christopher Haster 2:11cda6bead99 459 /** Set tolerance hint on when the event must be called, defaults to 0
Christopher Haster 2:11cda6bead99 460 * @param ms tolerance in milliseconds
Christopher Haster 2:11cda6bead99 461 */
Christopher Haster 2:11cda6bead99 462 void tolerance(int ms) {
Christopher Haster 2:11cda6bead99 463 (void)ms; // currently ignored
Christopher Haster 2:11cda6bead99 464 }
Christopher Haster 2:11cda6bead99 465
Christopher Haster 2:11cda6bead99 466 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 467 */
Christopher Haster 0:b1b901ae3696 468 void call() {
Christopher Haster 0:b1b901ae3696 469 _event.callback = FuncPtr<void()>::thunk;
Christopher Haster 0:b1b901ae3696 470 _event.data = &_callback;
Christopher Haster 2:11cda6bead99 471 _queue->event_register(&_event, _event.delay);
Christopher Haster 0:b1b901ae3696 472 }
Christopher Haster 0:b1b901ae3696 473
Christopher Haster 2:11cda6bead99 474 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 475 */
Christopher Haster 0:b1b901ae3696 476 void operator()() {
Christopher Haster 0:b1b901ae3696 477 return call();
Christopher Haster 0:b1b901ae3696 478 }
Christopher Haster 0:b1b901ae3696 479
Christopher Haster 0:b1b901ae3696 480 /** Test if event has been bound
Christopher Haster 0:b1b901ae3696 481 */
Christopher Haster 0:b1b901ae3696 482 operator bool() const {
Christopher Haster 0:b1b901ae3696 483 return _callback && _queue;
Christopher Haster 0:b1b901ae3696 484 }
Christopher Haster 0:b1b901ae3696 485
Christopher Haster 0:b1b901ae3696 486 /** Static thunk for passing as C-style function
Christopher Haster 0:b1b901ae3696 487 * @param data Event to dispatch passed as void pointer
Christopher Haster 0:b1b901ae3696 488 */
Christopher Haster 0:b1b901ae3696 489 static void thunk(void *data) {
Christopher Haster 0:b1b901ae3696 490 return static_cast<Event<void()>*>(data)
Christopher Haster 0:b1b901ae3696 491 ->call();
Christopher Haster 0:b1b901ae3696 492 }
Christopher Haster 0:b1b901ae3696 493
Christopher Haster 0:b1b901ae3696 494 /** Cancel a pending event
Christopher Haster 0:b1b901ae3696 495 */
Christopher Haster 0:b1b901ae3696 496 void cancel() {
Christopher Haster 0:b1b901ae3696 497 _queue->event_unregister(&_event);
Christopher Haster 0:b1b901ae3696 498 }
Christopher Haster 0:b1b901ae3696 499
Christopher Haster 0:b1b901ae3696 500 private:
Christopher Haster 0:b1b901ae3696 501 EventQueue *_queue;
Christopher Haster 0:b1b901ae3696 502 EventQueue::event _event;
Christopher Haster 0:b1b901ae3696 503 FuncPtr<void()> _callback;
Christopher Haster 0:b1b901ae3696 504 };
Christopher Haster 0:b1b901ae3696 505
Christopher Haster 0:b1b901ae3696 506
Christopher Haster 0:b1b901ae3696 507 #endif