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