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:18:55 2016 -0500
Revision:
12:1feb78280125
Parent:
4:30883e8633b4
Child:
13:b84e049b2d9c
Add trigger method for explicit event triggering

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