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