Mistake on this page?
Report an issue in GitHub or email us
EventQueue.h
1 /*
2  * Copyright (c) 2016-2019 ARM Limited
3  * SPDX-License-Identifier: Apache-2.0
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #ifndef EVENT_QUEUE_H
19 #define EVENT_QUEUE_H
20 
21 #include "events/equeue.h"
22 #include "platform/Callback.h"
23 #include "platform/NonCopyable.h"
24 #include <cstddef>
25 #include <new>
26 
27 namespace events {
28 /**
29  * \addtogroup events-public-api
30  * @{
31  */
32 
33 /** EVENTS_EVENT_SIZE
34  * Minimum size of an event
35  * This size fits a Callback<void()> at minimum
36  */
37 #define EVENTS_EVENT_SIZE \
38  (EQUEUE_EVENT_SIZE - 2*sizeof(void*) + sizeof(mbed::Callback<void()>))
39 
40 /** EVENTS_QUEUE_SIZE
41  * Default size of buffer for events
42  */
43 #define EVENTS_QUEUE_SIZE (32*EVENTS_EVENT_SIZE)
44 
45 // Predeclared classes
46 template <typename F>
47 class Event;
48 template <typename F, typename A>
50 
51 /**
52  * \defgroup events_EventQueue EventQueue class
53  * @{
54  */
55 
56 /** EventQueue
57  *
58  * Flexible event queue for dispatching events
59  */
60 class EventQueue : private mbed::NonCopyable<EventQueue> {
61 public:
62  /** Create an EventQueue
63  *
64  * Create an event queue. The event queue either allocates a buffer of
65  * the specified size with malloc or uses the user provided buffer or
66  * uses 1B dummy buffer if 0 size passed.
67  *
68  * 0 size queue is a special purpose queue to dispatch static events
69  * only (see UserAllocatedEvent). Such a queue gives the guarantee
70  * that no dynamic memory allocation will take place while queue
71  * creation and events posting & dispatching.
72  *
73  * @param size Size of buffer to use for events in bytes
74  * (default to EVENTS_QUEUE_SIZE)
75  * If 0 provided then 1B dummy buffer is used
76  * @param buffer Pointer to buffer to use for events
77  * (default to NULL)
78  */
79  EventQueue(unsigned size = EVENTS_QUEUE_SIZE, unsigned char *buffer = NULL);
80 
81  /** Destroy an EventQueue
82  */
83  ~EventQueue();
84 
85  /** Dispatch events
86  *
87  * Executes events until the specified milliseconds have passed.
88  * If ms is negative, the dispatch function will dispatch events
89  * indefinitely or until break_dispatch is called on this queue.
90  *
91  * When called with a finite timeout, the dispatch function is guaranteed
92  * to terminate. When called with a timeout of 0, the dispatch function
93  * does not wait and is IRQ safe.
94  *
95  * @param ms Time to wait for events in milliseconds, a negative
96  * value will dispatch events indefinitely
97  * (default to -1)
98  */
99  void dispatch(int ms = -1);
100 
101  /** Dispatch events without a timeout
102  *
103  * This is equivalent to EventQueue::dispatch with no arguments, but
104  * avoids overload ambiguities when passed as a callback.
105  *
106  * @see EventQueue::dispatch
107  */
109  {
110  dispatch();
111  }
112 
113  /** Break out of a running event loop
114  *
115  * Forces the specified event queue's dispatch loop to terminate. Pending
116  * events may finish executing, but no new events will be executed.
117  */
118  void break_dispatch();
119 
120  /** Millisecond counter
121  *
122  * Returns the underlying tick of the event queue represented as the
123  * number of milliseconds that have passed since an arbitrary point in
124  * time. Intentionally overflows to 0 after 2^32-1.
125  *
126  * @return The underlying tick of the event queue in milliseconds
127  */
128  unsigned tick();
129 
130  /** Cancel an in-flight event
131  *
132  * Attempts to cancel an event referenced by the unique id returned from
133  * one of the call functions. It is safe to call cancel after an event
134  * has already been dispatched.
135  *
136  * id must be valid i.e. event must have not finished executing.
137  *
138  * The cancel function is IRQ safe.
139  *
140  * If called while the event queue's dispatch loop is active in another thread,
141  * the cancel function does not guarantee that the event will not execute after it
142  * returns, as the event may have already begun executing. A call made from
143  * the same thread as the dispatch loop will always succeed with a valid id.
144  *
145  * @param id Unique id of the event
146  * @return true if event was successfully cancelled
147  * false if event was not cancelled (invalid id or executing already begun)
148  */
149  bool cancel(int id);
150 
151  /** Cancel an in-flight user allocated event
152  *
153  * Attempts to cancel an UserAllocatedEvent referenced by its address
154  * It is safe to call cancel after an event has already been dispatched.
155  *
156  * Event must be valid i.e. event must have not finished executing
157  * and must have been bound to this queue.
158  *
159  * The cancel function is IRQ safe.
160  *
161  * If called while the event queue's dispatch loop is active in another thread,
162  * the cancel function does not guarantee that the event will not execute after it
163  * returns, as the event may have already begun executing. A call made from
164  * the same thread as the dispatch loop will always succeed with a valid id.
165  *
166  * @param event Address of the event
167  * @return true if event was successfully cancelled
168  * false if event was not cancelled (invalid queue or executing already begun)
169  */
170  template<typename F, typename A>
172  {
173  if (event->_equeue != &_equeue) {
174  return false;
175  }
176  return equeue_cancel_user_allocated(&_equeue, event);
177  }
178 
179  /** Query how much time is left for delayed event
180  *
181  * If the event is delayed, this function can be used to query how much time
182  * is left until the event is due to be dispatched.
183  *
184  * id must be valid i.e. event must have not finished executing.
185  *
186  * This function is IRQ safe.
187  *
188  * @param id Unique id of the event
189  *
190  * @return Remaining time in milliseconds or
191  * 0 if event is already due to be dispatched or
192  * is currently executing.
193  * Undefined if id is invalid.
194  *
195  */
196  int time_left(int id);
197 
198  /** Query how much time is left for delayed UserAllocatedEvent
199  *
200  * If the event is delayed, this function can be used to query how much time
201  * is left until the event is due to be dispatched.
202  *
203  * Event must be valid i.e. event must have not finished executing
204  * and must have been bound to this queue.
205  *
206  * This function is IRQ safe.
207  *
208  * @param event Address of the event
209  *
210  * @return Remaining time in milliseconds or
211  * 0 if event is already due to be dispatched or
212  * is currently executing.
213  * Undefined if id is invalid.
214  *
215  */
216  template<typename F, typename A>
218  {
219  if (event && event->_equeue != &_equeue) {
220  return -1;
221  }
222  return equeue_timeleft_user_allocated(&_equeue, &event->_e);
223  }
224 
225  /** Background an event queue onto a single-shot timer-interrupt
226  *
227  * When updated, the event queue will call the provided update function
228  * with a timeout indicating when the queue should be dispatched. A
229  * negative timeout will be passed to the update function when the
230  * timer-interrupt is no longer needed.
231  *
232  * Passing a null function disables the existing update function.
233  *
234  * The background function allows an event queue to take advantage of
235  * hardware timers or other event loops, allowing an event queue to be
236  * ran in the background without consuming the foreground thread.
237  *
238  * @param update Function called to indicate when the queue should be
239  * dispatched
240  */
241  void background(mbed::Callback<void(int)> update);
242 
243  /** Chain an event queue onto another event queue
244  *
245  * After chaining a queue to a target, calling dispatch on the target
246  * queue will also dispatch events from this queue. The queues use
247  * their own buffers and events must be handled independently.
248  *
249  * A null queue as the target will unchain the existing queue.
250  *
251  * The chain function allows multiple event queues to be composed,
252  * sharing the context of a dispatch loop while still being managed
253  * independently
254  *
255  * @param target Queue that will dispatch this queue's events as a
256  * part of its dispatch loop
257  *
258  * @return Zero on success and negative error code value if chaining fails
259  *
260  */
261  int chain(EventQueue *target);
262 
263 
264 
265 #if defined(DOXYGEN_ONLY)
266  /** Calls an event on the queue
267  *
268  * The specified callback will be executed in the context of the event
269  * queue's dispatch loop.
270  *
271  * The call function is IRQ safe and can act as a mechanism for moving
272  * events out of IRQ contexts.
273  *
274  * @param f Function to execute in the context of the dispatch loop
275  * @param args Arguments to pass to the callback
276  * @return A unique id that represents the posted event and can
277  * be passed to cancel, or an id of 0 if there is not
278  * enough memory to allocate the event.
279  * Returned id will remain valid until event has finished
280  * executing.
281  *
282  * @code
283  * #include "mbed.h"
284  *
285  * int main() {
286  * // creates a queue with the default size
287  * EventQueue queue;
288  *
289  * // events are simple callbacks
290  * queue.call(printf, "called immediately\n");
291  *
292  * // the dispatch method executes events
293  * queue.dispatch();
294  * }
295  * @endcode
296  */
297  template <typename F, typename ...Args>
298  int call(F f, Args ...args);
299 
300  /** Calls an event on the queue
301  *
302  * The specified callback is executed in the context of the event
303  * queue's dispatch loop.
304  *
305  * The call function is IRQ safe and can act as a mechanism for moving
306  * events out of IRQ contexts.
307  *
308  * @param obj Object to call with the member function
309  * @param method Member function to execute in the context of the dispatch loop
310  * @param args Arguments to pass to the callback
311  * @return A unique ID that represents the posted event and can
312  * be passed to cancel, or an ID of 0 if there is not
313  * enough memory to allocate the event.
314  * Returned ID remains valid until event has finished
315  * executing.
316  *
317  * @code
318  * #include "mbed.h"
319  *
320  * class EventHandler {
321  * int _id;
322  * public:
323  * EventHandler(int id) : _id(id) { }
324  *
325  * void handler(int c) {
326  * printf("ID: %d Param: %d\r\n", _id, c);
327  * }
328  * };
329  *
330  * int main() {
331  * // creates a queue with the default size
332  * EventQueue queue;
333  *
334  * // Create EventHandler object with state
335  * EventHandler handler_cb(1);
336  *
337  * // events are simple callbacks, call object method
338  * // with provided parameter
339  * queue.call(&handler_cb, &EventHandler::handler, 2);
340  *
341  * // the dispath method executes events
342  * queue.dispatch();
343  * }
344  * @endcode
345  */
346  // AStyle ignore, not handling correctly below
347  // *INDENT-OFF*
348  template <typename T, typename R, typename ...Args>
349  int call(T *obj, R (T::*method)(Args ...args), Args ...args);
350  // *INDENT-ON*
351 
352  /** Calls an event on the queue after a specified delay
353  *
354  * The specified callback is executed in the context of the event
355  * queue's dispatch loop.
356  *
357  * The call_in function is IRQ safe and can act as a mechanism for moving
358  * events out of IRQ contexts.
359  *
360  * @param ms Time to delay in milliseconds
361  * @param args Arguments to pass to the callback
362  * @return A unique ID that represents the posted event and can
363  * be passed to cancel, or an ID of 0 if there is not
364  * enough memory to allocate the event.
365  *
366  * @code
367  * #include "mbed.h"
368  *
369  * int main() {
370  * // creates a queue with the default size
371  * EventQueue queue;
372  *
373  * // events are simple callbacks
374  * queue.call_in(2000, printf, "called in 2 seconds\n");
375  *
376  * // the dispatch methods executes events
377  * queue.dispatch();
378  * }
379  * @endcode
380  */
381  template <typename F, typename ...Args>
382  int call_in(int ms, Args ...args);
383 
384  /** Calls an event on the queue after a specified delay
385  *
386  * The specified callback is executed in the context of the event
387  * queue's dispatch loop.
388  *
389  * The call_in function is IRQ safe and can act as a mechanism for moving
390  * events out of IRQ contexts.
391  *
392  * @param ms Time to delay in milliseconds
393  * @param obj Object to call with the member function
394  * @param method Member function to execute in the context of the dispatch loop
395  * @param args Arguments to pass to the callback
396  * @return A unique ID that represents the posted event and can
397  * be passed to cancel, or an ID of 0 if there is not
398  * enough memory to allocate the event.
399  *
400  * @code
401  * #include "mbed.h"
402  *
403  * class EventHandler {
404  * int _id;
405  * public:
406  * EventHandler(int id) : _id(id) { }
407  *
408  * void handler(int c) {
409  * printf("ID: %d Param: %d\r\n", _id, c);
410  * }
411  * };
412  *
413  * int main() {
414  * // creates a queue with the default size
415  * EventQueue queue;
416  *
417  * // Create EventHandler object with state
418  * EventHandler handler_cb(3);
419  *
420  * // events are simple callbacks, call object method in 2 seconds
421  * // with provided parameter
422  * queue.call_in(2000, &handler_cb, &EventHandler::handler, 4);
423  *
424  * // the dispatch method executes events
425  * queue.dispatch();
426  * }
427  * @endcode
428  */
429  // AStyle ignore, not handling correctly below
430  // *INDENT-OFF*
431  template <typename T, typename R, typename ...Args>
432  int call_in(int ms, T *obj, R (T::*method)(Args ...args), Args ...args);
433  // *INDENT-ON*
434 
435  /** Calls an event on the queue periodically
436  *
437  * @note The first call_every event occurs after the specified delay.
438  * To create a periodic event that fires immediately, @see Event.
439  *
440  * The specified callback is executed in the context of the event
441  * queue's dispatch loop.
442  *
443  * The call_every function is IRQ safe and can act as a mechanism for
444  * moving events out of IRQ contexts.
445  *
446  * @param ms Period of the event in milliseconds
447  * @param f Function to execute in the context of the dispatch loop
448  * @param args Arguments to pass to the callback
449  * @return A unique ID that represents the posted event and can
450  * be passed to cancel, or an ID of 0 if there is not
451  * enough memory to allocate the event.
452  *
453  * @code
454  * #include "mbed.h"
455  *
456  * class EventHandler {
457  * int _id;
458  * public:
459  * EventHandler(int id) : _id(id) { }
460  *
461  * void handler(int c) {
462  * printf("ID: %d Param: %d\r\n", _id, c);
463  * }
464  * };
465  *
466  * int main() {
467  * // creates a queue with the default size
468  * EventQueue queue;
469  *
470  * // events are simple callbacks, call every 2 seconds
471  * queue.call_every(2000, printf, "Calling every 2 seconds\n");
472  *
473  * // the dispatch method executes events
474  * queue.dispatch();
475  * }
476  * @endcode
477  */
478  template <typename F, typename ...Args>
479  int call_every(int ms, F f, Args ...args);
480 
481  /** Calls an event on the queue periodically
482  *
483  * @note The first call_every event occurs after the specified delay.
484  * To create a periodic event that fires immediately, @see Event.
485  *
486  * The specified callback is executed in the context of the event
487  * queue's dispatch loop.
488  *
489  * The call_every function is IRQ safe and can act as a mechanism for
490  * moving events out of IRQ contexts.
491  *
492  * @param ms Period of the event in milliseconds
493  * @param obj Object to call with the member function
494  * @param method Member function to execute in the context of the dispatch loop
495  * @param args Arguments to pass to the callback
496  *
497  * @code
498  * #include "mbed.h"
499  *
500  * class EventHandler {
501  * int _id;
502  * public:
503  * EventHandler(int id) : _id(id) { }
504  *
505  * void handler(int c) {
506  * printf("ID: %d Param: %d\r\n", _id, c);
507  * }
508  * };
509  *
510  * int main() {
511  * // creates a queue with the default size
512  * EventQueue queue;
513  *
514  * // Create EventHandler object with state
515  * EventHandler handler_cb(5);
516  *
517  * // events are simple callbacks, call object method every 2 seconds
518  * // with provided parameter
519  * queue.call_every(2000, &handler_cb, &EventHandler::handler, 6);
520  *
521  * // the dispatch method executes events
522  * queue.dispatch();
523  * }
524  * @endcode
525  */
526  // AStyle ignore, not handling correctly below
527  // *INDENT-OFF*
528  template <typename T, typename R, typename ...Args>
529  int call_every(int ms, T *obj, R (T::*method)(Args ...args), Args ...args);
530  // *INDENT-ON*
531 
532  /** Creates an event bound to the event queue
533  *
534  * Constructs an event bound to the specified event queue. The specified
535  * callback acts as the target for the event and is executed in the
536  * context of the event queue's dispatch loop once posted.
537  *
538  * @param func Function to execute when the event is dispatched
539  * @param context_args Arguments to pass to the callback
540  * @return Event that dispatches on the specific queue
541  *
542  * @code
543  * #include "mbed.h"
544  *
545  * void handler(int c) {
546  * printf("Param: %d\r\n", c);
547  * }
548  *
549  * int main()
550  * {
551  * EventQueue queue;
552  *
553  * // Create event with parameter
554  * Event<void()> e = queue.event(handler, 1);
555  * e();
556  *
557  * // Create event and post parameter later
558  * Event<void(int)> e2 = queue.event(handler);
559  *
560  * // Post the event with paramter 8
561  * e.post(8);
562  *
563  * // The dispatch method executes events
564  * queue.dispatch();
565  *
566  * e2.post(2);
567  *
568  * queue.dispatch();
569  * }
570  * @endcode
571  */
572  // AStyle ignore, not handling correctly below
573  // *INDENT-OFF*
574  template <typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args>
575  Event<void(Args...)> event(R (*func)(BoundArgs..., Args...), ContextArgs ...context_args);
576  // *INDENT-ON*
577 
578  /** Creates an event bound to the event queue
579  *
580  * Constructs an event bound to the specified event queue. The specified
581  * callback acts as the target for the event and is executed in the
582  * context of the event queue's dispatch loop once posted.
583  *
584  * @param obj Object to call with the member function
585  * @param method Member function to execute in the context of the dispatch loop
586  * @param context_args Arguments to pass to the callback
587  * @return Event that dispatches on the specific queue
588  *
589  * @code
590  * #include "mbed.h"
591  *
592  * class EventHandler {
593  * int _id;
594  *
595  * public:
596  * EventHandler(int id) : _id(id) { }
597  *
598  * void handler(int c) {
599  * printf("ID: %d Param: %d\r\n", _id, c);
600  * }
601  * };
602  *
603  * int main()
604  * {
605  * EventQueue queue;
606  *
607  * EventHandler handler_cb(10);
608  *
609  * // Create event on the eventqueue with a method callback
610  * Event<void(int)> e = queue.event(&handler_cb, &EventHandler::handler);
611  *
612  * // Post the event with paramter 8
613  * e.post(11);
614  *
615  * // The dispatch method executes events
616  * queue.dispatch();
617  * }
618  * @endcode
619  */
620  // AStyle ignore, not handling correctly below
621  // *INDENT-OFF*
622  template <typename T, typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args>
623  Event<void(Args...)> event(T *obj, R (T::*method)(BoundArgs..., Args...), ContextArgs ...context_args);
624  // *INDENT-ON*
625 
626  /** Creates an event bound to the event queue
627  *
628  * Constructs an event bound to the specified event queue. The specified
629  * callback acts as the target for the event and is executed in the
630  * context of the event queue's dispatch loop once posted.
631  *
632  * @param cb Callback object
633  * @param context_args Arguments to pass to the callback
634  * @return Event that dispatches on the specific queue
635  *
636  * @code
637  * #include "mbed.h"
638  *
639  * void handler(int c) {
640  * printf("Param: %d\r\n", c);
641  * }
642  *
643  * int main()
644  * {
645  * EventQueue queue;
646  * // Create callback object acting as a function
647  * // pointer to handler
648  * Callback<void(int)> cb(handler);
649  *
650  * // Pass the callback object to the eventqueue
651  * Event<void(int)> e = queue.event(cb);
652  *
653  * // Post the event with parameter 8
654  * e.post(9);
655  *
656  * // The dispatch method executes events
657  * q.dispatch();
658  * }
659  * @endcode
660  */
661  template <typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args>
662  Event<void(Args...)> event(mbed::Callback<R(BoundArgs..., Args...)> cb, ContextArgs ...context_args);
663 
664  /** Creates an user allocated event bound to the event queue
665  *
666  * Constructs an user allocated event bound to the specified event queue.
667  * The specified callback acts as the target for the event and is executed
668  * in the context of the event queue's dispatch loop once posted.
669  *
670  * @code
671  * #include "mbed.h"
672  *
673  * void handler(int data) { ... }
674  *
675  * class Device {
676  * public:
677  * void handler(int data) { ... }
678  * };
679  *
680  * Device dev;
681  *
682  * // queue with not internal storage for dynamic events
683  * // accepts only user allocated events
684  * static EventQueue queue(0);
685  * // Create events
686  * static auto e1 = make_user_allocated_event(&dev, Device::handler, 2);
687  * static auto e2 = queue.make_user_allocated_event(handler, 3);
688  *
689  * int main()
690  * {
691  * e1.call_on(&queue);
692  * e2.call();
693  *
694  * queue.dispatch(1);
695  * }
696  * @endcode
697  *
698  * @param f Function to execute when the event is dispatched
699  * @return Event that will dispatch on the specific queue
700  */
701  template <typename F, typename... ArgTs>
702  UserAllocatedEvent<F, void(ArgTs...)> make_user_allocated_event(F f, ArgTs... args);
703 
704  /** Creates an user allocated event bound to the event queue
705  * @see EventQueue::make_user_allocated_event
706  */
707  template <typename T, typename R, typename... ArgTs>
708  UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(T *obj, R(T::*method)(ArgTs... args), ArgTs... args);
709 
710 
711 #else
712 
713  /** Calls an event on the queue
714  *
715  * The specified callback is executed in the context of the event
716  * queue's dispatch loop.
717  *
718  * The call function is IRQ safe and can act as a mechanism for moving
719  * events out of IRQ contexts.
720  *
721  * @param f Function to execute in the context of the dispatch loop
722  * @return A unique ID that represents the posted event and can
723  * be passed to cancel, or an ID of 0 if there is not
724  * enough memory to allocate the event.
725  * Returned ID remains valid until event has finished
726  * executing.
727  *
728  * @code
729  * #include "mbed.h"
730  *
731  * int main()
732  * {
733  * EventQueue queue;
734  *
735  * Callback<void(int)> cb(handler);
736  *
737  * // Create event on the eventqueue with a separate callback object
738  * Event<void(int)> e = queue.event(cb);
739  * e.post(1);
740  * queue.dispatch();
741  * }
742  * @endcode
743  */
744  template <typename F>
745  int call(F f)
746  {
747  void *p = equeue_alloc(&_equeue, sizeof(F));
748  if (!p) {
749  return 0;
750  }
751 
752  F *e = new (p) F(f);
753  equeue_event_dtor(e, &EventQueue::function_dtor<F>);
754  return equeue_post(&_equeue, &EventQueue::function_call<F>, e);
755  }
756 
757 
758  /** Calls an event on the queue
759  * @see EventQueue::call
760  * @param f Function to execute in the context of the dispatch loop
761  * @param args Arguments to pass to the callback
762  */
763  template <typename F, typename... ArgTs>
764  int call(F f, ArgTs... args)
765  {
766  return call(context<F, ArgTs...>(f, args...));
767  }
768 
769  /** Calls an event on the queue
770  * @see EventQueue::call
771  */
772  template <typename T, typename R, typename... ArgTs>
773  int call(T *obj, R(T::*method)(ArgTs...), ArgTs... args)
774  {
775  return call(mbed::callback(obj, method), args...);
776  }
777 
778  /** Calls an event on the queue
779  * @see EventQueue::call
780  */
781  template <typename T, typename R, typename... ArgTs>
782  int call(const T *obj, R(T::*method)(ArgTs...) const, ArgTs... args)
783  {
784  return call(mbed::callback(obj, method), args...);
785  }
786 
787  /** Calls an event on the queue
788  * @see EventQueue::call
789  */
790  template <typename T, typename R, typename... ArgTs>
791  int call(volatile T *obj, R(T::*method)(ArgTs...) volatile, ArgTs... args)
792  {
793  return call(mbed::callback(obj, method), args...);
794  }
795 
796  /** Calls an event on the queue
797  * @see EventQueue::call
798  */
799  template <typename T, typename R, typename... ArgTs>
800  int call(const volatile T *obj, R(T::*method)(ArgTs...) const volatile, ArgTs... args)
801  {
802  return call(mbed::callback(obj, method), args...);
803  }
804 
805  /** Calls an event on the queue after a specified delay
806  *
807  * The specified callback will be executed in the context of the event
808  * queue's dispatch loop.
809  *
810  * The call_in function is IRQ safe and can act as a mechanism for moving
811  * events out of IRQ contexts.
812  *
813  * @param ms Time to delay in milliseconds
814  * @param f Function to execute in the context of the dispatch loop
815  * @return A unique id that represents the posted event and can
816  * be passed to cancel, or an id of 0 if there is not
817  * enough memory to allocate the event.
818  */
819  template <typename F>
820  int call_in(int ms, F f)
821  {
822  void *p = equeue_alloc(&_equeue, sizeof(F));
823  if (!p) {
824  return 0;
825  }
826 
827  F *e = new (p) F(f);
828  equeue_event_delay(e, ms);
829  equeue_event_dtor(e, &EventQueue::function_dtor<F>);
830  return equeue_post(&_equeue, &EventQueue::function_call<F>, e);
831  }
832 
833  /** Calls an event on the queue after a specified delay
834  * @see EventQueue::call_in
835  * @param ms Time to delay in milliseconds
836  * @param f Function to execute in the context of the dispatch loop
837  * @param args Arguments to pass to the callback
838  */
839  template <typename F, typename... ArgTs>
840  int call_in(int ms, F f, ArgTs... args)
841  {
842  return call_in(ms, context<F, ArgTs...>(f, args...));
843  }
844 
845  /** Calls an event on the queue after a specified delay
846  * @see EventQueue::call_in
847  */
848  template <typename T, typename R, typename... ArgTs>
849  int call_in(int ms, T *obj, R(T::*method)(ArgTs...), ArgTs... args)
850  {
851  return call_in(ms, mbed::callback(obj, method), args...);
852  }
853 
854  /** Calls an event on the queue after a specified delay
855  * @see EventQueue::call_in
856  */
857  template <typename T, typename R, typename... ArgTs>
858  int call_in(int ms, const T *obj, R(T::*method)(ArgTs...) const, ArgTs... args)
859  {
860  return call_in(ms, mbed::callback(obj, method), args...);
861  }
862 
863  /** Calls an event on the queue after a specified delay
864  * @see EventQueue::call_in
865  */
866  template <typename T, typename R, typename... ArgTs>
867  int call_in(int ms, volatile T *obj, R(T::*method)(ArgTs...) volatile, ArgTs... args)
868  {
869  return call_in(ms, mbed::callback(obj, method), args...);
870  }
871 
872  /** Calls an event on the queue after a specified delay
873  * @see EventQueue::call_in
874  */
875  template <typename T, typename R, typename... ArgTs>
876  int call_in(int ms, const volatile T *obj, R(T::*method)(ArgTs...) const volatile, ArgTs... args)
877  {
878  return call_in(ms, mbed::callback(obj, method), args...);
879  }
880 
881  /** Calls an event on the queue periodically
882  *
883  * @note The first call_every event occurs after the specified delay.
884  * To create a periodic event that fires immediately, @see Event.
885  *
886  * The specified callback will be executed in the context of the event
887  * queue's dispatch loop.
888  *
889  * The call_every function is IRQ safe and can act as a mechanism for
890  * moving events out of IRQ contexts.
891  *
892  * @param f Function to execute in the context of the dispatch loop
893  * @param ms Period of the event in milliseconds
894  * @return A unique id that represents the posted event and can
895  * be passed to cancel, or an id of 0 if there is not
896  * enough memory to allocate the event.
897  */
898  template <typename F>
899  int call_every(int ms, F f)
900  {
901  void *p = equeue_alloc(&_equeue, sizeof(F));
902  if (!p) {
903  return 0;
904  }
905 
906  F *e = new (p) F(f);
907  equeue_event_delay(e, ms);
908  equeue_event_period(e, ms);
909  equeue_event_dtor(e, &EventQueue::function_dtor<F>);
910  return equeue_post(&_equeue, &EventQueue::function_call<F>, e);
911  }
912 
913  /** Calls an event on the queue periodically
914  * @see EventQueue::call_every
915  * @param f Function to execute in the context of the dispatch loop
916  * @param args Arguments to pass to the callback
917  * @param ms Period of the event in milliseconds
918  */
919  template <typename F, typename... ArgTs>
920  int call_every(int ms, F f, ArgTs... args)
921  {
922  return call_every(ms, context<F, ArgTs...>(f, args...));
923  }
924 
925  /** Calls an event on the queue periodically
926  * @see EventQueue::call_every
927  */
928  template <typename T, typename R, typename... ArgTs>
929  int call_every(int ms, T *obj, R(T::*method)(ArgTs...), ArgTs... args)
930  {
931  return call_every(ms, mbed::callback(obj, method), args...);
932  }
933 
934  /** Calls an event on the queue periodically
935  * @see EventQueue::call_every
936  */
937  template <typename T, typename R, typename... ArgTs>
938  int call_every(int ms, const T *obj, R(T::*method)(ArgTs...) const, ArgTs... args)
939  {
940  return call_every(ms, mbed::callback(obj, method), args...);
941  }
942 
943  /** Calls an event on the queue periodically
944  * @see EventQueue::call_every
945  */
946  template <typename T, typename R, typename... ArgTs>
947  int call_every(int ms, volatile T *obj, R(T::*method)(ArgTs...) volatile, ArgTs... args)
948  {
949  return call_every(ms, mbed::callback(obj, method), args...);
950  }
951 
952  /** Calls an event on the queue periodically
953  * @see EventQueue::call_every
954  */
955  template <typename T, typename R, typename... ArgTs>
956  int call_every(int ms, const volatile T *obj, R(T::*method)(ArgTs...) const volatile, ArgTs... args)
957  {
958  return call_every(ms, mbed::callback(obj, method), args...);
959  }
960 
961  /** Creates an event bound to the event queue
962  *
963  * Constructs an event bound to the specified event queue. The specified
964  * callback acts as the target for the event and is executed in the
965  * context of the event queue's dispatch loop once posted.
966  *
967  * @param func Function to execute when the event is dispatched
968  * @return Event that will dispatch on the specific queue
969  */
970  template <typename R, typename... ArgTs>
971  Event<void(ArgTs...)> event(R(*func)(ArgTs...));
972 
973  /** Creates an event bound to the event queue
974  * @see EventQueue::event
975  */
976  template <typename T, typename R, typename... ArgTs>
977  Event<void(ArgTs...)> event(T *obj, R(T::*method)(ArgTs...));
978 
979  /** Creates an event bound to the event queue
980  * @see EventQueue::event
981  */
982  template <typename T, typename R, typename... ArgTs>
983  Event<void(ArgTs...)> event(const T *obj, R(T::*method)(ArgTs...) const);
984 
985  /** Creates an event bound to the event queue
986  * @see EventQueue::event
987  */
988  template <typename T, typename R, typename... ArgTs>
989  Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(ArgTs...) volatile);
990 
991  /** Creates an event bound to the event queue
992  * @see EventQueue::event
993  */
994  template <typename T, typename R, typename... ArgTs>
995  Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(ArgTs...) const volatile);
996 
997  /** Creates an event bound to the event queue
998  * @see EventQueue::event
999  */
1000  template <typename R, typename... ArgTs>
1001  Event<void(ArgTs...)> event(mbed::Callback<R(ArgTs...)> cb);
1002 
1003  /** Creates an event bound to the event queue
1004  * @see EventQueue::event
1005  */
1006  template <typename R, typename B0, typename C0, typename... ArgTs>
1007  Event<void(ArgTs...)> event(R(*func)(B0, ArgTs...), C0 c0);
1008 
1009  /** Creates an event bound to the event queue
1010  * @see EventQueue::event
1011  */
1012  template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
1013  Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, ArgTs...), C0 c0);
1014 
1015  /** Creates an event bound to the event queue
1016  * @see EventQueue::event
1017  */
1018  template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
1019  Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, ArgTs...) const, C0 c0);
1020 
1021  /** Creates an event bound to the event queue
1022  * @see EventQueue::event
1023  */
1024  template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
1025  Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, ArgTs...) volatile, C0 c0);
1026 
1027  /** Creates an event bound to the event queue
1028  * @see EventQueue::event
1029  */
1030  template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
1031  Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, ArgTs...) const volatile, C0 c0);
1032 
1033  /** Creates an event bound to the event queue
1034  * @see EventQueue::event
1035  */
1036  template <typename R, typename B0, typename C0, typename... ArgTs>
1037  Event<void(ArgTs...)> event(mbed::Callback<R(B0, ArgTs...)> cb, C0 c0);
1038 
1039  /** Creates an event bound to the event queue
1040  * @see EventQueue::event
1041  */
1042  template <typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
1043  Event<void(ArgTs...)> event(R(*func)(B0, B1, ArgTs...), C0 c0, C1 c1);
1044 
1045  /** Creates an event bound to the event queue
1046  * @see EventQueue::event
1047  */
1048  template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
1049  Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, B1, ArgTs...), C0 c0, C1 c1);
1050 
1051  /** Creates an event bound to the event queue
1052  * @see EventQueue::event
1053  */
1054  template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
1055  Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, B1, ArgTs...) const, C0 c0, C1 c1);
1056 
1057  /** Creates an event bound to the event queue
1058  * @see EventQueue::event
1059  */
1060  template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
1061  Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, B1, ArgTs...) volatile, C0 c0, C1 c1);
1062 
1063  /** Creates an event bound to the event queue
1064  * @see EventQueue::event
1065  */
1066  template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
1067  Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, B1, ArgTs...) const volatile, C0 c0, C1 c1);
1068 
1069  /** Creates an event bound to the event queue
1070  * @see EventQueue::event
1071  */
1072  template <typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
1073  Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, ArgTs...)> cb, C0 c0, C1 c1);
1074 
1075  /** Creates an event bound to the event queue
1076  * @see EventQueue::event
1077  */
1078  template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
1079  Event<void(ArgTs...)> event(R(*func)(B0, B1, B2, ArgTs...), C0 c0, C1 c1, C2 c2);
1080 
1081  /** Creates an event bound to the event queue
1082  * @see EventQueue::event
1083  */
1084  template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
1085  Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, B1, B2, ArgTs...), C0 c0, C1 c1, C2 c2);
1086 
1087  /** Creates an event bound to the event queue
1088  * @see EventQueue::event
1089  */
1090  template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
1091  Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, B1, B2, ArgTs...) const, C0 c0, C1 c1, C2 c2);
1092 
1093  /** Creates an event bound to the event queue
1094  * @see EventQueue::event
1095  */
1096  template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
1097  Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, B1, B2, ArgTs...) volatile, C0 c0, C1 c1, C2 c2);
1098 
1099  /** Creates an event bound to the event queue
1100  * @see EventQueue::event
1101  */
1102  template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
1103  Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, B1, B2, ArgTs...) const volatile, C0 c0, C1 c1, C2 c2);
1104 
1105  /** Creates an event bound to the event queue
1106  * @see EventQueue::event
1107  */
1108  template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
1109  Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, B2, ArgTs...)> cb, C0 c0, C1 c1, C2 c2);
1110 
1111  /** Creates an event bound to the event queue
1112  * @see EventQueue::event
1113  */
1114  template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
1115  Event<void(ArgTs...)> event(R(*func)(B0, B1, B2, B3, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3);
1116 
1117  /** Creates an event bound to the event queue
1118  * @see EventQueue::event
1119  */
1120  template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
1121  Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3);
1122 
1123  /** Creates an event bound to the event queue
1124  * @see EventQueue::event
1125  */
1126  template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
1127  Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) const, C0 c0, C1 c1, C2 c2, C3 c3);
1128 
1129  /** Creates an event bound to the event queue
1130  * @see EventQueue::event
1131  */
1132  template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
1133  Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) volatile, C0 c0, C1 c1, C2 c2, C3 c3);
1134 
1135  /** Creates an event bound to the event queue
1136  * @see EventQueue::event
1137  */
1138  template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
1139  Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) const volatile, C0 c0, C1 c1, C2 c2, C3 c3);
1140 
1141  /** Creates an event bound to the event queue
1142  * @see EventQueue::event
1143  */
1144  template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
1145  Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, B2, B3, ArgTs...)> cb, C0 c0, C1 c1, C2 c2, C3 c3);
1146 
1147  /** Creates an event bound to the event queue
1148  * @see EventQueue::event
1149  */
1150  template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
1151  Event<void(ArgTs...)> event(R(*func)(B0, B1, B2, B3, B4, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
1152 
1153  /** Creates an event bound to the event queue
1154  * @see EventQueue::event
1155  */
1156  template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
1157  Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
1158 
1159  /** Creates an event bound to the event queue
1160  * @see EventQueue::event
1161  */
1162  template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
1163  Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) const, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
1164 
1165  /** Creates an event bound to the event queue
1166  * @see EventQueue::event
1167  */
1168  template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
1169  Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
1170 
1171  /** Creates an event bound to the event queue
1172  * @see EventQueue::event
1173  */
1174  template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
1175  Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, B1, B2, B3, B4, ArgTs...) const volatile, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
1176 
1177  /** Creates an event bound to the event queue
1178  * @see EventQueue::event
1179  */
1180  template <typename R, typename B0, typename B1, typename B2, typename B3, typename B4, typename C0, typename C1, typename C2, typename C3, typename C4, typename... ArgTs>
1181  Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, B2, B3, B4, ArgTs...)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
1182 
1183  /** Creates an user allocated event bound to the event queue
1184  *
1185  * Constructs an user allocated event bound to the specified event queue.
1186  * The specified callback acts as the target for the event and is executed
1187  * in the context of the event queue's dispatch loop once posted.
1188  *
1189  * @param f Function to execute when the event is dispatched
1190  * @return Event that will dispatch on the specific queue
1191  */
1192  template <typename F, typename... ArgTs>
1193  UserAllocatedEvent<F, void(ArgTs...)> make_user_allocated_event(F f, ArgTs... args);
1194 
1195  /** Creates an user allocated event bound to the event queue
1196  * @see EventQueue::make_user_allocated_event
1197  */
1198  template <typename T, typename R, typename... ArgTs>
1199  UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(T *obj, R(T::*method)(ArgTs... args), ArgTs... args);
1200 
1201  /** Creates an user allocated event bound to the event queue
1202  * @see EventQueue::make_user_allocated_event
1203  */
1204  template <typename T, typename R, typename... ArgTs>
1205  UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(const T *obj, R(T::*method)(ArgTs... args) const, ArgTs... args);
1206 
1207  /** Creates an user allocated event bound to the event queue
1208  * @see EventQueue::make_user_allocated_event
1209  */
1210  template <typename T, typename R, typename... ArgTs>
1211  UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(volatile T *obj, R(T::*method)(ArgTs... args) volatile, ArgTs... args);
1212 
1213  /** Creates an user allocated event bound to the event queue
1214  * @see EventQueue::make_user_allocated_event
1215  */
1216  template <typename T, typename R, typename... ArgTs>
1217  UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(const volatile T *obj, R(T::*method)(ArgTs... args) const volatile, ArgTs... args);
1218 #endif
1219 
1220 protected:
1221 #if !defined(DOXYGEN_ONLY)
1222  template <typename F>
1223  friend class Event;
1224  template <typename F, typename A>
1225  friend class UserAllocatedEvent;
1226  struct equeue _equeue;
1227  mbed::Callback<void(int)> _update;
1228 
1229  // Function attributes
1230  template <typename F>
1231  static void function_call(void *p)
1232  {
1233  (*(F *)p)();
1234  }
1235 
1236  template <typename F>
1237  static void function_dtor(void *p)
1238  {
1239  ((F *)p)->~F();
1240  }
1241 
1242  // Context structures
1243  template <typename F, typename... ContextArgTs>
1244  struct context;
1245 
1246  template <typename F>
1247  struct context<F> {
1248  F f;
1249 
1250  constexpr context(F f)
1251  : f(f) {}
1252 
1253  template <typename... ArgTs>
1254  void operator()(ArgTs... args)
1255  {
1256  f(args...);
1257  }
1258  };
1259 
1260  template <typename F, typename C0>
1261  struct context<F, C0> {
1262  F f;
1263  C0 c0;
1264 
1265  constexpr context(F f, C0 c0)
1266  : f(f), c0(c0) {}
1267 
1268  template <typename... ArgTs>
1269  void operator()(ArgTs... args)
1270  {
1271  f(c0, args...);
1272  }
1273  };
1274 
1275  template <typename F, typename C0, typename C1>
1276  struct context<F, C0, C1> {
1277  F f;
1278  C0 c0;
1279  C1 c1;
1280 
1281  constexpr context(F f, C0 c0, C1 c1)
1282  : f(f), c0(c0), c1(c1) {}
1283 
1284  template <typename... ArgTs>
1285  void operator()(ArgTs... args)
1286  {
1287  f(c0, c1, args...);
1288  }
1289  };
1290 
1291  template <typename F, typename C0, typename C1, typename C2>
1292  struct context<F, C0, C1, C2> {
1293  F f;
1294  C0 c0;
1295  C1 c1;
1296  C2 c2;
1297 
1298  constexpr context(F f, C0 c0, C1 c1, C2 c2)
1299  : f(f), c0(c0), c1(c1), c2(c2) {}
1300 
1301  template <typename... ArgTs>
1302  void operator()(ArgTs... args)
1303  {
1304  f(c0, c1, c2, args...);
1305  }
1306  };
1307 
1308  template <typename F, typename C0, typename C1, typename C2, typename C3>
1309  struct context<F, C0, C1, C2, C3> {
1310  F f;
1311  C0 c0;
1312  C1 c1;
1313  C2 c2;
1314  C3 c3;
1315 
1316  constexpr context(F f, C0 c0, C1 c1, C2 c2, C3 c3)
1317  : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {}
1318 
1319  template <typename... ArgTs>
1320  void operator()(ArgTs... args)
1321  {
1322  f(c0, c1, c2, c3, args...);
1323  }
1324  };
1325 
1326  template <typename F, typename C0, typename C1, typename C2, typename C3, typename C4>
1327  struct context<F, C0, C1, C2, C3, C4> {
1328  F f;
1329  C0 c0;
1330  C1 c1;
1331  C2 c2;
1332  C3 c3;
1333  C4 c4;
1334 
1335  constexpr context(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4)
1336  : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {}
1337 
1338  template <typename... ArgTs>
1339  void operator()(ArgTs... args)
1340  {
1341  f(c0, c1, c2, c3, c4, args...);
1342  }
1343  };
1344 #endif //!defined(DOXYGEN_ONLY)
1345 };
1346 
1347 /** @}*/
1348 /** @}*/
1349 
1350 }
1351 
1352 #endif
void dispatch_forever()
Dispatch events without a timeout.
Definition: EventQueue.h:108
int time_left(int id)
Query how much time is left for delayed event.
void break_dispatch()
Break out of a running event loop.
EventQueue.
Definition: EventQueue.h:60
Event.
Definition: Event.h:34
int chain(EventQueue *target)
Chain an event queue onto another event queue.
bool cancel(UserAllocatedEvent< F, A > *event)
Cancel an in-flight user allocated event.
Definition: EventQueue.h:171
Prevents generation of copy constructor and copy assignment operator in derived classes.
Definition: NonCopyable.h:169
UserAllocatedEvent< F, void(ArgTs...)> make_user_allocated_event(F f, ArgTs...args)
Creates an user allocated event bound to the event queue.
unsigned tick()
Millisecond counter.
Definition: equeue.h:60
bool cancel(int id)
Cancel an in-flight event.
Callback< R(ArgTs...)> callback(R(*func)(ArgTs...)=0)
Create a callback class with type inferred from the arguments.
Definition: Callback.h:709
void background(mbed::Callback< void(int)> update)
Background an event queue onto a single-shot timer-interrupt.
int call(F f, Args...args)
Calls an event on the queue.
Event< void(Args...)> event(R(*func)(BoundArgs..., Args...), ContextArgs...context_args)
Creates an event bound to the event queue.
~EventQueue()
Destroy an EventQueue.
EventQueue(unsigned size=(32 *(EQUEUE_EVENT_SIZE-2 *sizeof(void *)+sizeof(mbed::Callback< void()>))), unsigned char *buffer=NULL)
Create an EventQueue.
int time_left(UserAllocatedEvent< F, A > *event)
Query how much time is left for delayed UserAllocatedEvent.
Definition: EventQueue.h:217
Callback class based on template specialization.
Definition: Callback.h:39
int call_every(int ms, F f, Args...args)
Calls an event on the queue periodically.
int call_in(int ms, Args...args)
Calls an event on the queue after a specified delay.
#define EVENTS_QUEUE_SIZE
EVENTS_QUEUE_SIZE Default size of buffer for events.
Definition: EventQueue.h:43
void dispatch(int ms=-1)
Dispatch events.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.