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:
Fri Apr 22 22:32:35 2016 -0500
Revision:
13:b84e049b2d9c
Parent:
12:1feb78280125
Child:
14:5abf2ccf2dbf
Add support for attaching queue/callback separately

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 4:30883e8633b4 20 template <typename A0, typename A1, typename A2, typename A3, typename A4>
Christopher Haster 4:30883e8633b4 21 class Event<void(A0, A1, A2, A3, A4)> {
Christopher Haster 4:30883e8633b4 22 public:
Christopher Haster 4:30883e8633b4 23 /** Create an event bound to a queue
Christopher Haster 4:30883e8633b4 24 */
Christopher Haster 13:b84e049b2d9c 25 Event(EventQueue *queue=0, FuncPtr<void(A0, A1, A2, A3, A4)> callback=0) {
Christopher Haster 4:30883e8633b4 26 memset(&_event, 0, sizeof _event);
Christopher Haster 4:30883e8633b4 27 _event.delay = 0;
Christopher Haster 4:30883e8633b4 28 _event.period = -1;
Christopher Haster 4:30883e8633b4 29 attach(queue, callback);
Christopher Haster 4:30883e8633b4 30 }
Christopher Haster 4:30883e8633b4 31
Christopher Haster 4:30883e8633b4 32 /** Create an event bound to a queue
Christopher Haster 4:30883e8633b4 33 */
Christopher Haster 4:30883e8633b4 34 template <typename T, typename M>
Christopher Haster 4:30883e8633b4 35 Event(EventQueue *queue, T *obj, M method) {
Christopher Haster 4:30883e8633b4 36 memset(&_event, 0, sizeof _event);
Christopher Haster 4:30883e8633b4 37 _event.delay = 0;
Christopher Haster 4:30883e8633b4 38 _event.period = -1;
Christopher Haster 4:30883e8633b4 39 attach(queue, obj, method);
Christopher Haster 4:30883e8633b4 40 }
Christopher Haster 4:30883e8633b4 41
Christopher Haster 4:30883e8633b4 42 /** Safe lifetime management
Christopher Haster 4:30883e8633b4 43 */
Christopher Haster 4:30883e8633b4 44 ~Event() {
Christopher Haster 4:30883e8633b4 45 cancel();
Christopher Haster 4:30883e8633b4 46 }
Christopher Haster 4:30883e8633b4 47
Christopher Haster 4:30883e8633b4 48 /** Attach an event to a queue
Christopher Haster 4:30883e8633b4 49 */
Christopher Haster 13:b84e049b2d9c 50 void attach(EventQueue *queue) {
Christopher Haster 4:30883e8633b4 51 _queue = queue;
Christopher Haster 13:b84e049b2d9c 52 }
Christopher Haster 13:b84e049b2d9c 53
Christopher Haster 13:b84e049b2d9c 54 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 55 */
Christopher Haster 13:b84e049b2d9c 56 void attach(FuncPtr<void(A0, A1, A2, A3, A4)> callback) {
Christopher Haster 4:30883e8633b4 57 _callback.attach(callback);
Christopher Haster 4:30883e8633b4 58 }
Christopher Haster 4:30883e8633b4 59
Christopher Haster 13:b84e049b2d9c 60 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 61 */
Christopher Haster 13:b84e049b2d9c 62 template <typename T, typename M>
Christopher Haster 13:b84e049b2d9c 63 void attach(T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 64 attach(FuncPtr<void(A0, A1, A2, A3, A4)>(obj, method));
Christopher Haster 13:b84e049b2d9c 65 }
Christopher Haster 13:b84e049b2d9c 66
Christopher Haster 13:b84e049b2d9c 67 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 68 */
Christopher Haster 13:b84e049b2d9c 69 void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3, A4)> callback) {
Christopher Haster 13:b84e049b2d9c 70 attach(queue);
Christopher Haster 13:b84e049b2d9c 71 attach(callback);
Christopher Haster 13:b84e049b2d9c 72 }
Christopher Haster 13:b84e049b2d9c 73
Christopher Haster 4:30883e8633b4 74 /** Attach an event to a queue
Christopher Haster 4:30883e8633b4 75 */
Christopher Haster 4:30883e8633b4 76 template <typename T, typename M>
Christopher Haster 4:30883e8633b4 77 void attach(EventQueue *queue, T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 78 attach(queue);
Christopher Haster 13:b84e049b2d9c 79 attach(obj, method);
Christopher Haster 4:30883e8633b4 80 }
Christopher Haster 4:30883e8633b4 81
Christopher Haster 4:30883e8633b4 82 /** Set delay for when the event is dispatched after it is posted
Christopher Haster 4:30883e8633b4 83 * @param ms Delay in milliseconds
Christopher Haster 4:30883e8633b4 84 */
Christopher Haster 4:30883e8633b4 85 void delay(int ms) {
Christopher Haster 4:30883e8633b4 86 _event.delay = ms;
Christopher Haster 4:30883e8633b4 87 }
Christopher Haster 4:30883e8633b4 88
Christopher Haster 4:30883e8633b4 89 /** Set event to repeat periodically after it is posted
Christopher Haster 12:1feb78280125 90 * @param ms Period in milliseconds
Christopher Haster 4:30883e8633b4 91 */
Christopher Haster 4:30883e8633b4 92 void period(int ms) {
Christopher Haster 4:30883e8633b4 93 _event.period = ms;
Christopher Haster 4:30883e8633b4 94 }
Christopher Haster 4:30883e8633b4 95
Christopher Haster 4:30883e8633b4 96 /** Set tolerance hint on when the event must be called, defaults to 0
Christopher Haster 12:1feb78280125 97 * @param ms Tolerance in milliseconds
Christopher Haster 4:30883e8633b4 98 */
Christopher Haster 4:30883e8633b4 99 void tolerance(int ms) {
Christopher Haster 4:30883e8633b4 100 (void)ms; // currently ignored
Christopher Haster 4:30883e8633b4 101 }
Christopher Haster 4:30883e8633b4 102
Christopher Haster 4:30883e8633b4 103 /** Post the event onto the bound queue
Christopher Haster 12:1feb78280125 104 * @return True if the event was posted successfully
Christopher Haster 4:30883e8633b4 105 */
Christopher Haster 12:1feb78280125 106 bool trigger(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 12:1feb78280125 107 if (_event.registered) {
Christopher Haster 12:1feb78280125 108 return false;
Christopher Haster 12:1feb78280125 109 }
Christopher Haster 12:1feb78280125 110
Christopher Haster 4:30883e8633b4 111 _bind.attach(_callback, a0, a1, a2, a3, a4);
Christopher Haster 4:30883e8633b4 112 _event.callback = Binder<void(A0, A1, A2, A3, A4), A0, A1, A2, A3, A4>::thunk;
Christopher Haster 4:30883e8633b4 113 _event.data = &_bind;
Christopher Haster 4:30883e8633b4 114 _queue->event_register(&_event, _event.delay);
Christopher Haster 12:1feb78280125 115 return true;
Christopher Haster 12:1feb78280125 116 }
Christopher Haster 12:1feb78280125 117
Christopher Haster 12:1feb78280125 118 /** Post the event onto the bound queue
Christopher Haster 12:1feb78280125 119 */
Christopher Haster 12:1feb78280125 120 void call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 12:1feb78280125 121 trigger(a0, a1, a2, a3, a4);
Christopher Haster 4:30883e8633b4 122 }
Christopher Haster 4:30883e8633b4 123
Christopher Haster 4:30883e8633b4 124 /** Post the event onto the bound queue
Christopher Haster 4:30883e8633b4 125 */
Christopher Haster 4:30883e8633b4 126 void operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 4:30883e8633b4 127 return call(a0, a1, a2, a3, a4);
Christopher Haster 4:30883e8633b4 128 }
Christopher Haster 4:30883e8633b4 129
Christopher Haster 4:30883e8633b4 130 /** Test if event has been bound
Christopher Haster 4:30883e8633b4 131 */
Christopher Haster 4:30883e8633b4 132 operator bool() const {
Christopher Haster 4:30883e8633b4 133 return _callback && _queue;
Christopher Haster 4:30883e8633b4 134 }
Christopher Haster 4:30883e8633b4 135
Christopher Haster 4:30883e8633b4 136 /** Static thunk for passing as C-style function
Christopher Haster 4:30883e8633b4 137 * @param data Event to dispatch passed as void pointer
Christopher Haster 4:30883e8633b4 138 */
Christopher Haster 4:30883e8633b4 139 static void thunk(void *data, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
Christopher Haster 4:30883e8633b4 140 return static_cast<Event<void(A0, A1, A2, A3, A4)>*>(data)
Christopher Haster 4:30883e8633b4 141 ->call(a0, a1, a2, a3, a4);
Christopher Haster 4:30883e8633b4 142 }
Christopher Haster 4:30883e8633b4 143
Christopher Haster 4:30883e8633b4 144 /** Cancel a pending event
Christopher Haster 4:30883e8633b4 145 */
Christopher Haster 4:30883e8633b4 146 void cancel() {
Christopher Haster 4:30883e8633b4 147 _queue->event_unregister(&_event);
Christopher Haster 4:30883e8633b4 148 }
Christopher Haster 4:30883e8633b4 149
Christopher Haster 4:30883e8633b4 150 private:
Christopher Haster 4:30883e8633b4 151 EventQueue *_queue;
Christopher Haster 4:30883e8633b4 152 EventQueue::event _event;
Christopher Haster 4:30883e8633b4 153 FuncPtr<void(A0, A1, A2, A3, A4)> _callback;
Christopher Haster 4:30883e8633b4 154 Binder<void(A0, A1, A2, A3, A4), A0, A1, A2, A3, A4> _bind;
Christopher Haster 4:30883e8633b4 155 };
Christopher Haster 4:30883e8633b4 156
Christopher Haster 4:30883e8633b4 157 /** Pendable event class
Christopher Haster 4:30883e8633b4 158 */
Christopher Haster 0:b1b901ae3696 159 template <typename A0, typename A1, typename A2, typename A3>
Christopher Haster 0:b1b901ae3696 160 class Event<void(A0, A1, A2, A3)> {
Christopher Haster 0:b1b901ae3696 161 public:
Christopher Haster 0:b1b901ae3696 162 /** Create an event bound to a queue
Christopher Haster 0:b1b901ae3696 163 */
Christopher Haster 13:b84e049b2d9c 164 Event(EventQueue *queue=0, FuncPtr<void(A0, A1, A2, A3)> callback=0) {
Christopher Haster 2:11cda6bead99 165 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 166 _event.delay = 0;
Christopher Haster 2:11cda6bead99 167 _event.period = -1;
Christopher Haster 0:b1b901ae3696 168 attach(queue, callback);
Christopher Haster 0:b1b901ae3696 169 }
Christopher Haster 0:b1b901ae3696 170
Christopher Haster 3:6dccdc36651f 171 /** Create an event bound to a queue
Christopher Haster 3:6dccdc36651f 172 */
Christopher Haster 3:6dccdc36651f 173 template <typename T, typename M>
Christopher Haster 3:6dccdc36651f 174 Event(EventQueue *queue, T *obj, M method) {
Christopher Haster 3:6dccdc36651f 175 memset(&_event, 0, sizeof _event);
Christopher Haster 3:6dccdc36651f 176 _event.delay = 0;
Christopher Haster 3:6dccdc36651f 177 _event.period = -1;
Christopher Haster 3:6dccdc36651f 178 attach(queue, obj, method);
Christopher Haster 3:6dccdc36651f 179 }
Christopher Haster 3:6dccdc36651f 180
Christopher Haster 0:b1b901ae3696 181 /** Safe lifetime management
Christopher Haster 0:b1b901ae3696 182 */
Christopher Haster 0:b1b901ae3696 183 ~Event() {
Christopher Haster 0:b1b901ae3696 184 cancel();
Christopher Haster 0:b1b901ae3696 185 }
Christopher Haster 0:b1b901ae3696 186
Christopher Haster 0:b1b901ae3696 187 /** Attach an event to a queue
Christopher Haster 0:b1b901ae3696 188 */
Christopher Haster 13:b84e049b2d9c 189 void attach(EventQueue *queue) {
Christopher Haster 0:b1b901ae3696 190 _queue = queue;
Christopher Haster 13:b84e049b2d9c 191 }
Christopher Haster 13:b84e049b2d9c 192
Christopher Haster 13:b84e049b2d9c 193 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 194 */
Christopher Haster 13:b84e049b2d9c 195 void attach(FuncPtr<void(A0, A1, A2, A3)> callback) {
Christopher Haster 0:b1b901ae3696 196 _callback.attach(callback);
Christopher Haster 0:b1b901ae3696 197 }
Christopher Haster 0:b1b901ae3696 198
Christopher Haster 13:b84e049b2d9c 199 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 200 */
Christopher Haster 13:b84e049b2d9c 201 template <typename T, typename M>
Christopher Haster 13:b84e049b2d9c 202 void attach(T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 203 attach(FuncPtr<void(A0, A1, A2, A3)>(obj, method));
Christopher Haster 13:b84e049b2d9c 204 }
Christopher Haster 13:b84e049b2d9c 205
Christopher Haster 13:b84e049b2d9c 206 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 207 */
Christopher Haster 13:b84e049b2d9c 208 void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2, A3)> callback) {
Christopher Haster 13:b84e049b2d9c 209 attach(queue);
Christopher Haster 13:b84e049b2d9c 210 attach(callback);
Christopher Haster 13:b84e049b2d9c 211 }
Christopher Haster 13:b84e049b2d9c 212
Christopher Haster 3:6dccdc36651f 213 /** Attach an event to a queue
Christopher Haster 3:6dccdc36651f 214 */
Christopher Haster 3:6dccdc36651f 215 template <typename T, typename M>
Christopher Haster 3:6dccdc36651f 216 void attach(EventQueue *queue, T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 217 attach(queue);
Christopher Haster 13:b84e049b2d9c 218 attach(obj, method);
Christopher Haster 3:6dccdc36651f 219 }
Christopher Haster 3:6dccdc36651f 220
Christopher Haster 2:11cda6bead99 221 /** Set delay for when the event is dispatched after it is posted
Christopher Haster 2:11cda6bead99 222 * @param ms Delay in milliseconds
Christopher Haster 2:11cda6bead99 223 */
Christopher Haster 2:11cda6bead99 224 void delay(int ms) {
Christopher Haster 2:11cda6bead99 225 _event.delay = ms;
Christopher Haster 2:11cda6bead99 226 }
Christopher Haster 2:11cda6bead99 227
Christopher Haster 2:11cda6bead99 228 /** Set event to repeat periodically after it is posted
Christopher Haster 12:1feb78280125 229 * @param ms Period in milliseconds
Christopher Haster 2:11cda6bead99 230 */
Christopher Haster 2:11cda6bead99 231 void period(int ms) {
Christopher Haster 2:11cda6bead99 232 _event.period = ms;
Christopher Haster 2:11cda6bead99 233 }
Christopher Haster 2:11cda6bead99 234
Christopher Haster 2:11cda6bead99 235 /** Set tolerance hint on when the event must be called, defaults to 0
Christopher Haster 12:1feb78280125 236 * @param ms Tolerance in milliseconds
Christopher Haster 2:11cda6bead99 237 */
Christopher Haster 2:11cda6bead99 238 void tolerance(int ms) {
Christopher Haster 2:11cda6bead99 239 (void)ms; // currently ignored
Christopher Haster 2:11cda6bead99 240 }
Christopher Haster 2:11cda6bead99 241
Christopher Haster 2:11cda6bead99 242 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 243 */
Christopher Haster 12:1feb78280125 244 bool trigger(A0 a0, A1 a1, A2 a2, A3 a3) {
Christopher Haster 12:1feb78280125 245 if (_event.registered) {
Christopher Haster 12:1feb78280125 246 return false;
Christopher Haster 12:1feb78280125 247 }
Christopher Haster 12:1feb78280125 248
Christopher Haster 0:b1b901ae3696 249 _bind.attach(_callback, a0, a1, a2, a3);
Christopher Haster 0:b1b901ae3696 250 _event.callback = Binder<void(A0, A1, A2, A3), A0, A1, A2, A3>::thunk;
Christopher Haster 0:b1b901ae3696 251 _event.data = &_bind;
Christopher Haster 2:11cda6bead99 252 _queue->event_register(&_event, _event.delay);
Christopher Haster 12:1feb78280125 253 return true;
Christopher Haster 12:1feb78280125 254 }
Christopher Haster 12:1feb78280125 255
Christopher Haster 12:1feb78280125 256 /** Post the event onto the bound queue
Christopher Haster 12:1feb78280125 257 */
Christopher Haster 12:1feb78280125 258 void call(A0 a0, A1 a1, A2 a2, A3 a3) {
Christopher Haster 12:1feb78280125 259 trigger(a0, a1, a2, a3);
Christopher Haster 0:b1b901ae3696 260 }
Christopher Haster 0:b1b901ae3696 261
Christopher Haster 2:11cda6bead99 262 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 263 */
Christopher Haster 0:b1b901ae3696 264 void operator()(A0 a0, A1 a1, A2 a2, A3 a3) {
Christopher Haster 0:b1b901ae3696 265 return call(a0, a1, a2, a3);
Christopher Haster 0:b1b901ae3696 266 }
Christopher Haster 0:b1b901ae3696 267
Christopher Haster 0:b1b901ae3696 268 /** Test if event has been bound
Christopher Haster 0:b1b901ae3696 269 */
Christopher Haster 0:b1b901ae3696 270 operator bool() const {
Christopher Haster 0:b1b901ae3696 271 return _callback && _queue;
Christopher Haster 0:b1b901ae3696 272 }
Christopher Haster 0:b1b901ae3696 273
Christopher Haster 0:b1b901ae3696 274 /** Static thunk for passing as C-style function
Christopher Haster 0:b1b901ae3696 275 * @param data Event to dispatch passed as void pointer
Christopher Haster 0:b1b901ae3696 276 */
Christopher Haster 0:b1b901ae3696 277 static void thunk(void *data, A0 a0, A1 a1, A2 a2, A3 a3) {
Christopher Haster 0:b1b901ae3696 278 return static_cast<Event<void(A0, A1, A2, A3)>*>(data)
Christopher Haster 0:b1b901ae3696 279 ->call(a0, a1, a2, a3);
Christopher Haster 0:b1b901ae3696 280 }
Christopher Haster 0:b1b901ae3696 281
Christopher Haster 0:b1b901ae3696 282 /** Cancel a pending event
Christopher Haster 0:b1b901ae3696 283 */
Christopher Haster 0:b1b901ae3696 284 void cancel() {
Christopher Haster 0:b1b901ae3696 285 _queue->event_unregister(&_event);
Christopher Haster 0:b1b901ae3696 286 }
Christopher Haster 0:b1b901ae3696 287
Christopher Haster 0:b1b901ae3696 288 private:
Christopher Haster 0:b1b901ae3696 289 EventQueue *_queue;
Christopher Haster 0:b1b901ae3696 290 EventQueue::event _event;
Christopher Haster 0:b1b901ae3696 291 FuncPtr<void(A0, A1, A2, A3)> _callback;
Christopher Haster 0:b1b901ae3696 292 Binder<void(A0, A1, A2, A3), A0, A1, A2, A3> _bind;
Christopher Haster 0:b1b901ae3696 293 };
Christopher Haster 0:b1b901ae3696 294
Christopher Haster 0:b1b901ae3696 295 /** Pendable event class
Christopher Haster 0:b1b901ae3696 296 */
Christopher Haster 0:b1b901ae3696 297 template <typename A0, typename A1, typename A2>
Christopher Haster 0:b1b901ae3696 298 class Event<void(A0, A1, A2)> {
Christopher Haster 0:b1b901ae3696 299 public:
Christopher Haster 0:b1b901ae3696 300 /** Create an event bound to a queue
Christopher Haster 0:b1b901ae3696 301 */
Christopher Haster 13:b84e049b2d9c 302 Event(EventQueue *queue=0, FuncPtr<void(A0, A1, A2)> callback=0) {
Christopher Haster 2:11cda6bead99 303 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 304 _event.delay = 0;
Christopher Haster 2:11cda6bead99 305 _event.period = -1;
Christopher Haster 0:b1b901ae3696 306 attach(queue, callback);
Christopher Haster 0:b1b901ae3696 307 }
Christopher Haster 0:b1b901ae3696 308
Christopher Haster 3:6dccdc36651f 309 /** Create an event bound to a queue
Christopher Haster 3:6dccdc36651f 310 */
Christopher Haster 3:6dccdc36651f 311 template <typename T, typename M>
Christopher Haster 3:6dccdc36651f 312 Event(EventQueue *queue, T *obj, M method) {
Christopher Haster 3:6dccdc36651f 313 memset(&_event, 0, sizeof _event);
Christopher Haster 3:6dccdc36651f 314 _event.delay = 0;
Christopher Haster 3:6dccdc36651f 315 _event.period = -1;
Christopher Haster 3:6dccdc36651f 316 attach(queue, obj, method);
Christopher Haster 3:6dccdc36651f 317 }
Christopher Haster 3:6dccdc36651f 318
Christopher Haster 0:b1b901ae3696 319 /** Safe lifetime management
Christopher Haster 0:b1b901ae3696 320 */
Christopher Haster 0:b1b901ae3696 321 ~Event() {
Christopher Haster 0:b1b901ae3696 322 cancel();
Christopher Haster 0:b1b901ae3696 323 }
Christopher Haster 0:b1b901ae3696 324
Christopher Haster 0:b1b901ae3696 325 /** Attach an event to a queue
Christopher Haster 0:b1b901ae3696 326 */
Christopher Haster 13:b84e049b2d9c 327 void attach(EventQueue *queue) {
Christopher Haster 0:b1b901ae3696 328 _queue = queue;
Christopher Haster 13:b84e049b2d9c 329 }
Christopher Haster 13:b84e049b2d9c 330
Christopher Haster 13:b84e049b2d9c 331 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 332 */
Christopher Haster 13:b84e049b2d9c 333 void attach(FuncPtr<void(A0, A1, A2)> callback) {
Christopher Haster 0:b1b901ae3696 334 _callback.attach(callback);
Christopher Haster 0:b1b901ae3696 335 }
Christopher Haster 0:b1b901ae3696 336
Christopher Haster 13:b84e049b2d9c 337 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 338 */
Christopher Haster 13:b84e049b2d9c 339 template <typename T, typename M>
Christopher Haster 13:b84e049b2d9c 340 void attach(T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 341 attach(FuncPtr<void(A0, A1, A2)>(obj, method));
Christopher Haster 13:b84e049b2d9c 342 }
Christopher Haster 13:b84e049b2d9c 343
Christopher Haster 13:b84e049b2d9c 344 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 345 */
Christopher Haster 13:b84e049b2d9c 346 void attach(EventQueue *queue, FuncPtr<void(A0, A1, A2)> callback) {
Christopher Haster 13:b84e049b2d9c 347 attach(queue);
Christopher Haster 13:b84e049b2d9c 348 attach(callback);
Christopher Haster 13:b84e049b2d9c 349 }
Christopher Haster 13:b84e049b2d9c 350
Christopher Haster 3:6dccdc36651f 351 /** Attach an event to a queue
Christopher Haster 3:6dccdc36651f 352 */
Christopher Haster 3:6dccdc36651f 353 template <typename T, typename M>
Christopher Haster 3:6dccdc36651f 354 void attach(EventQueue *queue, T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 355 attach(queue);
Christopher Haster 13:b84e049b2d9c 356 attach(obj, method);
Christopher Haster 3:6dccdc36651f 357 }
Christopher Haster 3:6dccdc36651f 358
Christopher Haster 2:11cda6bead99 359 /** Set delay for when the event is dispatched after it is posted
Christopher Haster 2:11cda6bead99 360 * @param ms Delay in milliseconds
Christopher Haster 2:11cda6bead99 361 */
Christopher Haster 2:11cda6bead99 362 void delay(int ms) {
Christopher Haster 2:11cda6bead99 363 _event.delay = ms;
Christopher Haster 2:11cda6bead99 364 }
Christopher Haster 2:11cda6bead99 365
Christopher Haster 2:11cda6bead99 366 /** Set event to repeat periodically after it is posted
Christopher Haster 12:1feb78280125 367 * @param ms Period in milliseconds
Christopher Haster 2:11cda6bead99 368 */
Christopher Haster 2:11cda6bead99 369 void period(int ms) {
Christopher Haster 2:11cda6bead99 370 _event.period = ms;
Christopher Haster 2:11cda6bead99 371 }
Christopher Haster 2:11cda6bead99 372
Christopher Haster 2:11cda6bead99 373 /** Set tolerance hint on when the event must be called, defaults to 0
Christopher Haster 12:1feb78280125 374 * @param ms Tolerance in milliseconds
Christopher Haster 2:11cda6bead99 375 */
Christopher Haster 2:11cda6bead99 376 void tolerance(int ms) {
Christopher Haster 2:11cda6bead99 377 (void)ms; // currently ignored
Christopher Haster 2:11cda6bead99 378 }
Christopher Haster 2:11cda6bead99 379
Christopher Haster 2:11cda6bead99 380 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 381 */
Christopher Haster 12:1feb78280125 382 bool trigger(A0 a0, A1 a1, A2 a2) {
Christopher Haster 12:1feb78280125 383 if (_event.registered) {
Christopher Haster 12:1feb78280125 384 return false;
Christopher Haster 12:1feb78280125 385 }
Christopher Haster 12:1feb78280125 386
Christopher Haster 0:b1b901ae3696 387 _bind.attach(_callback, a0, a1, a2);
Christopher Haster 0:b1b901ae3696 388 _event.callback = Binder<void(A0, A1, A2), A0, A1, A2>::thunk;
Christopher Haster 0:b1b901ae3696 389 _event.data = &_bind;
Christopher Haster 2:11cda6bead99 390 _queue->event_register(&_event, _event.delay);
Christopher Haster 12:1feb78280125 391 return true;
Christopher Haster 12:1feb78280125 392 }
Christopher Haster 12:1feb78280125 393
Christopher Haster 12:1feb78280125 394 /** Post the event onto the bound queue
Christopher Haster 12:1feb78280125 395 */
Christopher Haster 12:1feb78280125 396 void call(A0 a0, A1 a1, A2 a2) {
Christopher Haster 12:1feb78280125 397 trigger(a0, a1, a2);
Christopher Haster 0:b1b901ae3696 398 }
Christopher Haster 0:b1b901ae3696 399
Christopher Haster 2:11cda6bead99 400 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 401 */
Christopher Haster 0:b1b901ae3696 402 void operator()(A0 a0, A1 a1, A2 a2) {
Christopher Haster 0:b1b901ae3696 403 return call(a0, a1, a2);
Christopher Haster 0:b1b901ae3696 404 }
Christopher Haster 0:b1b901ae3696 405
Christopher Haster 0:b1b901ae3696 406 /** Test if event has been bound
Christopher Haster 0:b1b901ae3696 407 */
Christopher Haster 0:b1b901ae3696 408 operator bool() const {
Christopher Haster 0:b1b901ae3696 409 return _callback && _queue;
Christopher Haster 0:b1b901ae3696 410 }
Christopher Haster 0:b1b901ae3696 411
Christopher Haster 0:b1b901ae3696 412 /** Static thunk for passing as C-style function
Christopher Haster 0:b1b901ae3696 413 * @param data Event to dispatch passed as void pointer
Christopher Haster 0:b1b901ae3696 414 */
Christopher Haster 0:b1b901ae3696 415 static void thunk(void *data, A0 a0, A1 a1, A2 a2) {
Christopher Haster 0:b1b901ae3696 416 return static_cast<Event<void(A0, A1, A2)>*>(data)
Christopher Haster 0:b1b901ae3696 417 ->call(a0, a1, a2);
Christopher Haster 0:b1b901ae3696 418 }
Christopher Haster 0:b1b901ae3696 419
Christopher Haster 0:b1b901ae3696 420 /** Cancel a pending event
Christopher Haster 0:b1b901ae3696 421 */
Christopher Haster 0:b1b901ae3696 422 void cancel() {
Christopher Haster 0:b1b901ae3696 423 _queue->event_unregister(&_event);
Christopher Haster 0:b1b901ae3696 424 }
Christopher Haster 0:b1b901ae3696 425
Christopher Haster 0:b1b901ae3696 426 private:
Christopher Haster 0:b1b901ae3696 427 EventQueue *_queue;
Christopher Haster 0:b1b901ae3696 428 EventQueue::event _event;
Christopher Haster 0:b1b901ae3696 429 FuncPtr<void(A0, A1, A2)> _callback;
Christopher Haster 0:b1b901ae3696 430 Binder<void(A0, A1, A2), A0, A1, A2> _bind;
Christopher Haster 0:b1b901ae3696 431 };
Christopher Haster 0:b1b901ae3696 432
Christopher Haster 0:b1b901ae3696 433 /** Pendable event class
Christopher Haster 0:b1b901ae3696 434 */
Christopher Haster 0:b1b901ae3696 435 template <typename A0, typename A1>
Christopher Haster 0:b1b901ae3696 436 class Event<void(A0, A1)> {
Christopher Haster 0:b1b901ae3696 437 public:
Christopher Haster 0:b1b901ae3696 438 /** Create an event bound to a queue
Christopher Haster 0:b1b901ae3696 439 */
Christopher Haster 13:b84e049b2d9c 440 Event(EventQueue *queue=0, FuncPtr<void(A0, A1)> callback=0) {
Christopher Haster 2:11cda6bead99 441 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 442 _event.delay = 0;
Christopher Haster 2:11cda6bead99 443 _event.period = -1;
Christopher Haster 0:b1b901ae3696 444 attach(queue, callback);
Christopher Haster 0:b1b901ae3696 445 }
Christopher Haster 0:b1b901ae3696 446
Christopher Haster 3:6dccdc36651f 447 /** Create an event bound to a queue
Christopher Haster 3:6dccdc36651f 448 */
Christopher Haster 3:6dccdc36651f 449 template <typename T, typename M>
Christopher Haster 3:6dccdc36651f 450 Event(EventQueue *queue, T *obj, M method) {
Christopher Haster 3:6dccdc36651f 451 memset(&_event, 0, sizeof _event);
Christopher Haster 3:6dccdc36651f 452 _event.delay = 0;
Christopher Haster 3:6dccdc36651f 453 _event.period = -1;
Christopher Haster 3:6dccdc36651f 454 attach(queue, obj, method);
Christopher Haster 3:6dccdc36651f 455 }
Christopher Haster 3:6dccdc36651f 456
Christopher Haster 0:b1b901ae3696 457 /** Safe lifetime management
Christopher Haster 0:b1b901ae3696 458 */
Christopher Haster 0:b1b901ae3696 459 ~Event() {
Christopher Haster 0:b1b901ae3696 460 cancel();
Christopher Haster 0:b1b901ae3696 461 }
Christopher Haster 0:b1b901ae3696 462
Christopher Haster 0:b1b901ae3696 463 /** Attach an event to a queue
Christopher Haster 0:b1b901ae3696 464 */
Christopher Haster 13:b84e049b2d9c 465 void attach(EventQueue *queue) {
Christopher Haster 0:b1b901ae3696 466 _queue = queue;
Christopher Haster 13:b84e049b2d9c 467 }
Christopher Haster 13:b84e049b2d9c 468
Christopher Haster 13:b84e049b2d9c 469 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 470 */
Christopher Haster 13:b84e049b2d9c 471 void attach(FuncPtr<void(A0, A1)> callback) {
Christopher Haster 0:b1b901ae3696 472 _callback.attach(callback);
Christopher Haster 0:b1b901ae3696 473 }
Christopher Haster 0:b1b901ae3696 474
Christopher Haster 13:b84e049b2d9c 475 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 476 */
Christopher Haster 13:b84e049b2d9c 477 template <typename T, typename M>
Christopher Haster 13:b84e049b2d9c 478 void attach(T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 479 attach(FuncPtr<void(A0, A1)>(obj, method));
Christopher Haster 13:b84e049b2d9c 480 }
Christopher Haster 13:b84e049b2d9c 481
Christopher Haster 13:b84e049b2d9c 482 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 483 */
Christopher Haster 13:b84e049b2d9c 484 void attach(EventQueue *queue, FuncPtr<void(A0, A1)> callback) {
Christopher Haster 13:b84e049b2d9c 485 attach(queue);
Christopher Haster 13:b84e049b2d9c 486 attach(callback);
Christopher Haster 13:b84e049b2d9c 487 }
Christopher Haster 13:b84e049b2d9c 488
Christopher Haster 3:6dccdc36651f 489 /** Attach an event to a queue
Christopher Haster 3:6dccdc36651f 490 */
Christopher Haster 3:6dccdc36651f 491 template <typename T, typename M>
Christopher Haster 3:6dccdc36651f 492 void attach(EventQueue *queue, T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 493 attach(queue);
Christopher Haster 13:b84e049b2d9c 494 attach(obj, method);
Christopher Haster 3:6dccdc36651f 495 }
Christopher Haster 3:6dccdc36651f 496
Christopher Haster 2:11cda6bead99 497 /** Set delay for when the event is dispatched after it is posted
Christopher Haster 2:11cda6bead99 498 * @param ms Delay in milliseconds
Christopher Haster 2:11cda6bead99 499 */
Christopher Haster 2:11cda6bead99 500 void delay(int ms) {
Christopher Haster 2:11cda6bead99 501 _event.delay = ms;
Christopher Haster 2:11cda6bead99 502 }
Christopher Haster 2:11cda6bead99 503
Christopher Haster 2:11cda6bead99 504 /** Set event to repeat periodically after it is posted
Christopher Haster 12:1feb78280125 505 * @param ms Period in milliseconds
Christopher Haster 2:11cda6bead99 506 */
Christopher Haster 2:11cda6bead99 507 void period(int ms) {
Christopher Haster 2:11cda6bead99 508 _event.period = ms;
Christopher Haster 2:11cda6bead99 509 }
Christopher Haster 2:11cda6bead99 510
Christopher Haster 2:11cda6bead99 511 /** Set tolerance hint on when the event must be called, defaults to 0
Christopher Haster 12:1feb78280125 512 * @param ms Tolerance in milliseconds
Christopher Haster 2:11cda6bead99 513 */
Christopher Haster 2:11cda6bead99 514 void tolerance(int ms) {
Christopher Haster 2:11cda6bead99 515 (void)ms; // currently ignored
Christopher Haster 2:11cda6bead99 516 }
Christopher Haster 2:11cda6bead99 517
Christopher Haster 2:11cda6bead99 518 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 519 */
Christopher Haster 12:1feb78280125 520 bool trigger(A0 a0, A1 a1) {
Christopher Haster 12:1feb78280125 521 if (_event.registered) {
Christopher Haster 12:1feb78280125 522 return false;
Christopher Haster 12:1feb78280125 523 }
Christopher Haster 12:1feb78280125 524
Christopher Haster 0:b1b901ae3696 525 _bind.attach(_callback, a0, a1);
Christopher Haster 0:b1b901ae3696 526 _event.callback = Binder<void(A0, A1), A0, A1>::thunk;
Christopher Haster 0:b1b901ae3696 527 _event.data = &_bind;
Christopher Haster 2:11cda6bead99 528 _queue->event_register(&_event, _event.delay);
Christopher Haster 12:1feb78280125 529 return true;
Christopher Haster 12:1feb78280125 530 }
Christopher Haster 12:1feb78280125 531
Christopher Haster 12:1feb78280125 532 /** Post the event onto the bound queue
Christopher Haster 12:1feb78280125 533 */
Christopher Haster 12:1feb78280125 534 void call(A0 a0, A1 a1) {
Christopher Haster 12:1feb78280125 535 trigger(a0, a1);
Christopher Haster 0:b1b901ae3696 536 }
Christopher Haster 0:b1b901ae3696 537
Christopher Haster 2:11cda6bead99 538 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 539 */
Christopher Haster 0:b1b901ae3696 540 void operator()(A0 a0, A1 a1) {
Christopher Haster 0:b1b901ae3696 541 return call(a0, a1);
Christopher Haster 0:b1b901ae3696 542 }
Christopher Haster 0:b1b901ae3696 543
Christopher Haster 0:b1b901ae3696 544 /** Test if event has been bound
Christopher Haster 0:b1b901ae3696 545 */
Christopher Haster 0:b1b901ae3696 546 operator bool() const {
Christopher Haster 0:b1b901ae3696 547 return _callback && _queue;
Christopher Haster 0:b1b901ae3696 548 }
Christopher Haster 0:b1b901ae3696 549
Christopher Haster 0:b1b901ae3696 550 /** Static thunk for passing as C-style function
Christopher Haster 0:b1b901ae3696 551 * @param data Event to dispatch passed as void pointer
Christopher Haster 0:b1b901ae3696 552 */
Christopher Haster 0:b1b901ae3696 553 static void thunk(void *data, A0 a0, A1 a1) {
Christopher Haster 0:b1b901ae3696 554 return static_cast<Event<void(A0, A1)>*>(data)
Christopher Haster 0:b1b901ae3696 555 ->call(a0, a1);
Christopher Haster 0:b1b901ae3696 556 }
Christopher Haster 0:b1b901ae3696 557
Christopher Haster 0:b1b901ae3696 558 /** Cancel a pending event
Christopher Haster 0:b1b901ae3696 559 */
Christopher Haster 0:b1b901ae3696 560 void cancel() {
Christopher Haster 0:b1b901ae3696 561 _queue->event_unregister(&_event);
Christopher Haster 0:b1b901ae3696 562 }
Christopher Haster 0:b1b901ae3696 563
Christopher Haster 0:b1b901ae3696 564 private:
Christopher Haster 0:b1b901ae3696 565 EventQueue *_queue;
Christopher Haster 0:b1b901ae3696 566 EventQueue::event _event;
Christopher Haster 0:b1b901ae3696 567 FuncPtr<void(A0, A1)> _callback;
Christopher Haster 0:b1b901ae3696 568 Binder<void(A0, A1), A0, A1> _bind;
Christopher Haster 0:b1b901ae3696 569 };
Christopher Haster 0:b1b901ae3696 570
Christopher Haster 0:b1b901ae3696 571 /** Pendable event class
Christopher Haster 0:b1b901ae3696 572 */
Christopher Haster 0:b1b901ae3696 573 template <typename A0>
Christopher Haster 0:b1b901ae3696 574 class Event<void(A0)> {
Christopher Haster 0:b1b901ae3696 575 public:
Christopher Haster 0:b1b901ae3696 576 /** Create an event bound to a queue
Christopher Haster 0:b1b901ae3696 577 */
Christopher Haster 13:b84e049b2d9c 578 Event(EventQueue *queue=0, FuncPtr<void(A0)> callback=0) {
Christopher Haster 2:11cda6bead99 579 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 580 _event.delay = 0;
Christopher Haster 2:11cda6bead99 581 _event.period = -1;
Christopher Haster 0:b1b901ae3696 582 attach(queue, callback);
Christopher Haster 0:b1b901ae3696 583 }
Christopher Haster 0:b1b901ae3696 584
Christopher Haster 3:6dccdc36651f 585 /** Create an event bound to a queue
Christopher Haster 3:6dccdc36651f 586 */
Christopher Haster 3:6dccdc36651f 587 template <typename T, typename M>
Christopher Haster 3:6dccdc36651f 588 Event(EventQueue *queue, T *obj, M method) {
Christopher Haster 3:6dccdc36651f 589 memset(&_event, 0, sizeof _event);
Christopher Haster 3:6dccdc36651f 590 _event.delay = 0;
Christopher Haster 3:6dccdc36651f 591 _event.period = -1;
Christopher Haster 3:6dccdc36651f 592 attach(queue, obj, method);
Christopher Haster 3:6dccdc36651f 593 }
Christopher Haster 3:6dccdc36651f 594
Christopher Haster 0:b1b901ae3696 595 /** Safe lifetime management
Christopher Haster 0:b1b901ae3696 596 */
Christopher Haster 0:b1b901ae3696 597 ~Event() {
Christopher Haster 0:b1b901ae3696 598 cancel();
Christopher Haster 0:b1b901ae3696 599 }
Christopher Haster 0:b1b901ae3696 600
Christopher Haster 0:b1b901ae3696 601 /** Attach an event to a queue
Christopher Haster 0:b1b901ae3696 602 */
Christopher Haster 13:b84e049b2d9c 603 void attach(EventQueue *queue) {
Christopher Haster 0:b1b901ae3696 604 _queue = queue;
Christopher Haster 13:b84e049b2d9c 605 }
Christopher Haster 13:b84e049b2d9c 606
Christopher Haster 13:b84e049b2d9c 607 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 608 */
Christopher Haster 13:b84e049b2d9c 609 void attach(FuncPtr<void(A0)> callback) {
Christopher Haster 0:b1b901ae3696 610 _callback.attach(callback);
Christopher Haster 0:b1b901ae3696 611 }
Christopher Haster 0:b1b901ae3696 612
Christopher Haster 13:b84e049b2d9c 613 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 614 */
Christopher Haster 13:b84e049b2d9c 615 template <typename T, typename M>
Christopher Haster 13:b84e049b2d9c 616 void attach(T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 617 attach(FuncPtr<void(A0)>(obj, method));
Christopher Haster 13:b84e049b2d9c 618 }
Christopher Haster 13:b84e049b2d9c 619
Christopher Haster 13:b84e049b2d9c 620 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 621 */
Christopher Haster 13:b84e049b2d9c 622 void attach(EventQueue *queue, FuncPtr<void(A0)> callback) {
Christopher Haster 13:b84e049b2d9c 623 attach(queue);
Christopher Haster 13:b84e049b2d9c 624 attach(callback);
Christopher Haster 13:b84e049b2d9c 625 }
Christopher Haster 13:b84e049b2d9c 626
Christopher Haster 3:6dccdc36651f 627 /** Attach an event to a queue
Christopher Haster 3:6dccdc36651f 628 */
Christopher Haster 3:6dccdc36651f 629 template <typename T, typename M>
Christopher Haster 3:6dccdc36651f 630 void attach(EventQueue *queue, T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 631 attach(queue);
Christopher Haster 13:b84e049b2d9c 632 attach(obj, method);
Christopher Haster 3:6dccdc36651f 633 }
Christopher Haster 3:6dccdc36651f 634
Christopher Haster 2:11cda6bead99 635 /** Set delay for when the event is dispatched after it is posted
Christopher Haster 2:11cda6bead99 636 * @param ms Delay in milliseconds
Christopher Haster 2:11cda6bead99 637 */
Christopher Haster 2:11cda6bead99 638 void delay(int ms) {
Christopher Haster 2:11cda6bead99 639 _event.delay = ms;
Christopher Haster 2:11cda6bead99 640 }
Christopher Haster 2:11cda6bead99 641
Christopher Haster 2:11cda6bead99 642 /** Set event to repeat periodically after it is posted
Christopher Haster 12:1feb78280125 643 * @param ms Period in milliseconds
Christopher Haster 2:11cda6bead99 644 */
Christopher Haster 2:11cda6bead99 645 void period(int ms) {
Christopher Haster 2:11cda6bead99 646 _event.period = ms;
Christopher Haster 2:11cda6bead99 647 }
Christopher Haster 2:11cda6bead99 648
Christopher Haster 2:11cda6bead99 649 /** Set tolerance hint on when the event must be called, defaults to 0
Christopher Haster 12:1feb78280125 650 * @param ms Tolerance in milliseconds
Christopher Haster 2:11cda6bead99 651 */
Christopher Haster 2:11cda6bead99 652 void tolerance(int ms) {
Christopher Haster 2:11cda6bead99 653 (void)ms; // currently ignored
Christopher Haster 2:11cda6bead99 654 }
Christopher Haster 2:11cda6bead99 655
Christopher Haster 2:11cda6bead99 656 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 657 */
Christopher Haster 12:1feb78280125 658 bool trigger(A0 a0) {
Christopher Haster 12:1feb78280125 659 if (_event.registered) {
Christopher Haster 12:1feb78280125 660 return false;
Christopher Haster 12:1feb78280125 661 }
Christopher Haster 12:1feb78280125 662
Christopher Haster 0:b1b901ae3696 663 _bind.attach(_callback, a0);
Christopher Haster 0:b1b901ae3696 664 _event.callback = Binder<void(A0), A0>::thunk;
Christopher Haster 0:b1b901ae3696 665 _event.data = &_bind;
Christopher Haster 2:11cda6bead99 666 _queue->event_register(&_event, _event.delay);
Christopher Haster 12:1feb78280125 667 return true;
Christopher Haster 12:1feb78280125 668 }
Christopher Haster 12:1feb78280125 669
Christopher Haster 12:1feb78280125 670 /** Post the event onto the bound queue
Christopher Haster 12:1feb78280125 671 */
Christopher Haster 12:1feb78280125 672 void call(A0 a0) {
Christopher Haster 12:1feb78280125 673 trigger(a0);
Christopher Haster 0:b1b901ae3696 674 }
Christopher Haster 0:b1b901ae3696 675
Christopher Haster 2:11cda6bead99 676 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 677 */
Christopher Haster 0:b1b901ae3696 678 void operator()(A0 a0) {
Christopher Haster 0:b1b901ae3696 679 return call(a0);
Christopher Haster 0:b1b901ae3696 680 }
Christopher Haster 0:b1b901ae3696 681
Christopher Haster 0:b1b901ae3696 682 /** Test if event has been bound
Christopher Haster 0:b1b901ae3696 683 */
Christopher Haster 0:b1b901ae3696 684 operator bool() const {
Christopher Haster 0:b1b901ae3696 685 return _callback && _queue;
Christopher Haster 0:b1b901ae3696 686 }
Christopher Haster 0:b1b901ae3696 687
Christopher Haster 0:b1b901ae3696 688 /** Static thunk for passing as C-style function
Christopher Haster 0:b1b901ae3696 689 * @param data Event to dispatch passed as void pointer
Christopher Haster 0:b1b901ae3696 690 */
Christopher Haster 0:b1b901ae3696 691 static void thunk(void *data, A0 a0) {
Christopher Haster 0:b1b901ae3696 692 return static_cast<Event<void(A0)>*>(data)
Christopher Haster 0:b1b901ae3696 693 ->call(a0);
Christopher Haster 0:b1b901ae3696 694 }
Christopher Haster 0:b1b901ae3696 695
Christopher Haster 0:b1b901ae3696 696 /** Cancel a pending event
Christopher Haster 0:b1b901ae3696 697 */
Christopher Haster 0:b1b901ae3696 698 void cancel() {
Christopher Haster 0:b1b901ae3696 699 _queue->event_unregister(&_event);
Christopher Haster 0:b1b901ae3696 700 }
Christopher Haster 0:b1b901ae3696 701
Christopher Haster 0:b1b901ae3696 702 private:
Christopher Haster 0:b1b901ae3696 703 EventQueue *_queue;
Christopher Haster 0:b1b901ae3696 704 EventQueue::event _event;
Christopher Haster 0:b1b901ae3696 705 FuncPtr<void(A0)> _callback;
Christopher Haster 0:b1b901ae3696 706 Binder<void(A0), A0> _bind;
Christopher Haster 0:b1b901ae3696 707 };
Christopher Haster 0:b1b901ae3696 708
Christopher Haster 0:b1b901ae3696 709 /** Pendable event class
Christopher Haster 0:b1b901ae3696 710 */
Christopher Haster 0:b1b901ae3696 711 template <>
Christopher Haster 0:b1b901ae3696 712 class Event<void()> {
Christopher Haster 0:b1b901ae3696 713 public:
Christopher Haster 0:b1b901ae3696 714 /** Create an unbound event
Christopher Haster 0:b1b901ae3696 715 */
Christopher Haster 2:11cda6bead99 716 Event() {
Christopher Haster 2:11cda6bead99 717 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 718 _event.delay = 0;
Christopher Haster 2:11cda6bead99 719 _event.period = -1;
Christopher Haster 2:11cda6bead99 720 }
Christopher Haster 0:b1b901ae3696 721
Christopher Haster 0:b1b901ae3696 722 /** Create an event bound to a queue
Christopher Haster 0:b1b901ae3696 723 */
Christopher Haster 13:b84e049b2d9c 724 Event(EventQueue *queue=0, FuncPtr<void()> callback=0) {
Christopher Haster 2:11cda6bead99 725 memset(&_event, 0, sizeof _event);
Christopher Haster 2:11cda6bead99 726 _event.delay = 0;
Christopher Haster 2:11cda6bead99 727 _event.period = -1;
Christopher Haster 0:b1b901ae3696 728 attach(queue, callback);
Christopher Haster 0:b1b901ae3696 729 }
Christopher Haster 0:b1b901ae3696 730
Christopher Haster 3:6dccdc36651f 731 /** Create an event bound to a queue
Christopher Haster 3:6dccdc36651f 732 */
Christopher Haster 3:6dccdc36651f 733 template <typename T, typename M>
Christopher Haster 3:6dccdc36651f 734 Event(EventQueue *queue, T *obj, M method) {
Christopher Haster 3:6dccdc36651f 735 memset(&_event, 0, sizeof _event);
Christopher Haster 3:6dccdc36651f 736 _event.delay = 0;
Christopher Haster 3:6dccdc36651f 737 _event.period = -1;
Christopher Haster 3:6dccdc36651f 738 attach(queue, obj, method);
Christopher Haster 3:6dccdc36651f 739 }
Christopher Haster 3:6dccdc36651f 740
Christopher Haster 0:b1b901ae3696 741 /** Safe lifetime management
Christopher Haster 0:b1b901ae3696 742 */
Christopher Haster 0:b1b901ae3696 743 ~Event() {
Christopher Haster 0:b1b901ae3696 744 cancel();
Christopher Haster 0:b1b901ae3696 745 }
Christopher Haster 0:b1b901ae3696 746
Christopher Haster 0:b1b901ae3696 747 /** Attach an event to a queue
Christopher Haster 0:b1b901ae3696 748 */
Christopher Haster 13:b84e049b2d9c 749 void attach(EventQueue *queue) {
Christopher Haster 0:b1b901ae3696 750 _queue = queue;
Christopher Haster 13:b84e049b2d9c 751 }
Christopher Haster 13:b84e049b2d9c 752
Christopher Haster 13:b84e049b2d9c 753 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 754 */
Christopher Haster 13:b84e049b2d9c 755 void attach(FuncPtr<void()> callback) {
Christopher Haster 0:b1b901ae3696 756 _callback.attach(callback);
Christopher Haster 0:b1b901ae3696 757 }
Christopher Haster 0:b1b901ae3696 758
Christopher Haster 13:b84e049b2d9c 759 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 760 */
Christopher Haster 13:b84e049b2d9c 761 template <typename T, typename M>
Christopher Haster 13:b84e049b2d9c 762 void attach(T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 763 attach(FuncPtr<void()>(obj, method));
Christopher Haster 13:b84e049b2d9c 764 }
Christopher Haster 13:b84e049b2d9c 765
Christopher Haster 13:b84e049b2d9c 766 /** Attach a callback to an event
Christopher Haster 13:b84e049b2d9c 767 */
Christopher Haster 13:b84e049b2d9c 768 void attach(EventQueue *queue, FuncPtr<void()> callback) {
Christopher Haster 13:b84e049b2d9c 769 attach(queue);
Christopher Haster 13:b84e049b2d9c 770 attach(callback);
Christopher Haster 13:b84e049b2d9c 771 }
Christopher Haster 13:b84e049b2d9c 772
Christopher Haster 3:6dccdc36651f 773 /** Attach an event to a queue
Christopher Haster 3:6dccdc36651f 774 */
Christopher Haster 3:6dccdc36651f 775 template <typename T, typename M>
Christopher Haster 3:6dccdc36651f 776 void attach(EventQueue *queue, T *obj, M method) {
Christopher Haster 13:b84e049b2d9c 777 attach(queue);
Christopher Haster 13:b84e049b2d9c 778 attach(obj, method);
Christopher Haster 3:6dccdc36651f 779 }
Christopher Haster 3:6dccdc36651f 780
Christopher Haster 2:11cda6bead99 781 /** Set delay for when the event is dispatched after it is posted
Christopher Haster 2:11cda6bead99 782 * @param ms Delay in milliseconds
Christopher Haster 2:11cda6bead99 783 */
Christopher Haster 2:11cda6bead99 784 void delay(int ms) {
Christopher Haster 2:11cda6bead99 785 _event.delay = ms;
Christopher Haster 2:11cda6bead99 786 }
Christopher Haster 2:11cda6bead99 787
Christopher Haster 2:11cda6bead99 788 /** Set event to repeat periodically after it is posted
Christopher Haster 12:1feb78280125 789 * @param ms Period in milliseconds
Christopher Haster 2:11cda6bead99 790 */
Christopher Haster 2:11cda6bead99 791 void period(int ms) {
Christopher Haster 2:11cda6bead99 792 _event.period = ms;
Christopher Haster 2:11cda6bead99 793 }
Christopher Haster 2:11cda6bead99 794
Christopher Haster 2:11cda6bead99 795 /** Set tolerance hint on when the event must be called, defaults to 0
Christopher Haster 12:1feb78280125 796 * @param ms Tolerance in milliseconds
Christopher Haster 2:11cda6bead99 797 */
Christopher Haster 2:11cda6bead99 798 void tolerance(int ms) {
Christopher Haster 2:11cda6bead99 799 (void)ms; // currently ignored
Christopher Haster 2:11cda6bead99 800 }
Christopher Haster 2:11cda6bead99 801
Christopher Haster 2:11cda6bead99 802 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 803 */
Christopher Haster 12:1feb78280125 804 bool trigger() {
Christopher Haster 12:1feb78280125 805 if (_event.registered) {
Christopher Haster 12:1feb78280125 806 return false;
Christopher Haster 12:1feb78280125 807 }
Christopher Haster 12:1feb78280125 808
Christopher Haster 0:b1b901ae3696 809 _event.callback = FuncPtr<void()>::thunk;
Christopher Haster 0:b1b901ae3696 810 _event.data = &_callback;
Christopher Haster 2:11cda6bead99 811 _queue->event_register(&_event, _event.delay);
Christopher Haster 12:1feb78280125 812 return true;
Christopher Haster 12:1feb78280125 813 }
Christopher Haster 12:1feb78280125 814
Christopher Haster 12:1feb78280125 815 /** Post the event onto the bound queue
Christopher Haster 12:1feb78280125 816 */
Christopher Haster 12:1feb78280125 817 void call() {
Christopher Haster 12:1feb78280125 818 trigger();
Christopher Haster 0:b1b901ae3696 819 }
Christopher Haster 0:b1b901ae3696 820
Christopher Haster 2:11cda6bead99 821 /** Post the event onto the bound queue
Christopher Haster 0:b1b901ae3696 822 */
Christopher Haster 0:b1b901ae3696 823 void operator()() {
Christopher Haster 0:b1b901ae3696 824 return call();
Christopher Haster 0:b1b901ae3696 825 }
Christopher Haster 0:b1b901ae3696 826
Christopher Haster 0:b1b901ae3696 827 /** Test if event has been bound
Christopher Haster 0:b1b901ae3696 828 */
Christopher Haster 0:b1b901ae3696 829 operator bool() const {
Christopher Haster 0:b1b901ae3696 830 return _callback && _queue;
Christopher Haster 0:b1b901ae3696 831 }
Christopher Haster 0:b1b901ae3696 832
Christopher Haster 0:b1b901ae3696 833 /** Static thunk for passing as C-style function
Christopher Haster 0:b1b901ae3696 834 * @param data Event to dispatch passed as void pointer
Christopher Haster 0:b1b901ae3696 835 */
Christopher Haster 0:b1b901ae3696 836 static void thunk(void *data) {
Christopher Haster 0:b1b901ae3696 837 return static_cast<Event<void()>*>(data)
Christopher Haster 0:b1b901ae3696 838 ->call();
Christopher Haster 0:b1b901ae3696 839 }
Christopher Haster 0:b1b901ae3696 840
Christopher Haster 0:b1b901ae3696 841 /** Cancel a pending event
Christopher Haster 0:b1b901ae3696 842 */
Christopher Haster 0:b1b901ae3696 843 void cancel() {
Christopher Haster 0:b1b901ae3696 844 _queue->event_unregister(&_event);
Christopher Haster 0:b1b901ae3696 845 }
Christopher Haster 0:b1b901ae3696 846
Christopher Haster 0:b1b901ae3696 847 private:
Christopher Haster 0:b1b901ae3696 848 EventQueue *_queue;
Christopher Haster 0:b1b901ae3696 849 EventQueue::event _event;
Christopher Haster 0:b1b901ae3696 850 FuncPtr<void()> _callback;
Christopher Haster 0:b1b901ae3696 851 };
Christopher Haster 0:b1b901ae3696 852
Christopher Haster 0:b1b901ae3696 853
Christopher Haster 0:b1b901ae3696 854 #endif