Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EventQueue.h Source File

EventQueue.h

00001 /*
00002  * Copyright (c) 2016-2019 ARM Limited
00003  * SPDX-License-Identifier: Apache-2.0
00004  *
00005  * Licensed under the Apache License, Version 2.0 (the "License");
00006  * you may not use this file except in compliance with the License.
00007  * You may obtain a copy of the License at
00008  *
00009  *     http://www.apache.org/licenses/LICENSE-2.0
00010  *
00011  * Unless required by applicable law or agreed to in writing, software
00012  * distributed under the License is distributed on an "AS IS" BASIS,
00013  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00014  * See the License for the specific language governing permissions and
00015  * limitations under the License.
00016  */
00017 
00018 #ifndef EVENT_QUEUE_H
00019 #define EVENT_QUEUE_H
00020 
00021 #include "events/equeue.h"
00022 #include "platform/Callback.h"
00023 #include "platform/NonCopyable.h"
00024 #include <cstddef>
00025 #include <new>
00026 
00027 namespace events {
00028 /**
00029  * \addtogroup events-public-api
00030  * @{
00031  */
00032 
00033 /** EVENTS_EVENT_SIZE
00034  *  Minimum size of an event
00035  *  This size fits a Callback<void()> at minimum
00036  */
00037 #define EVENTS_EVENT_SIZE \
00038     (EQUEUE_EVENT_SIZE - 2*sizeof(void*) + sizeof(mbed::Callback<void()>))
00039 
00040 /** EVENTS_QUEUE_SIZE
00041  *  Default size of buffer for events
00042  */
00043 #define EVENTS_QUEUE_SIZE (32*EVENTS_EVENT_SIZE)
00044 
00045 // Predeclared classes
00046 template <typename F>
00047 class Event;
00048 template <typename F, typename A>
00049 class UserAllocatedEvent;
00050 
00051 /**
00052  * \defgroup events_EventQueue EventQueue class
00053  * @{
00054  */
00055 
00056 /** EventQueue
00057  *
00058  *  Flexible event queue for dispatching events
00059  */
00060 class EventQueue : private mbed::NonCopyable<EventQueue> {
00061 public:
00062     /** Create an EventQueue
00063      *
00064      *  Create an event queue. The event queue either allocates a buffer of
00065      *  the specified size with malloc or uses the user provided buffer or
00066      *  uses 1B dummy buffer if 0 size passed.
00067      *
00068      *  0 size queue is a special purpose queue to dispatch static events
00069      *  only (see UserAllocatedEvent). Such a queue gives the guarantee
00070      *  that no dynamic memory allocation will take place while queue
00071      *  creation and events posting & dispatching.
00072      *
00073      *  @param size     Size of buffer to use for events in bytes
00074      *                  (default to EVENTS_QUEUE_SIZE)
00075      *                  If 0 provided then 1B dummy buffer is used
00076      *  @param buffer   Pointer to buffer to use for events
00077      *                  (default to NULL)
00078      */
00079     EventQueue(unsigned size = EVENTS_QUEUE_SIZE, unsigned char *buffer = NULL);
00080 
00081     /** Destroy an EventQueue
00082      */
00083     ~EventQueue();
00084 
00085     /** Dispatch events
00086      *
00087      *  Executes events until the specified milliseconds have passed.
00088      *  If ms is negative, the dispatch function will dispatch events
00089      *  indefinitely or until break_dispatch is called on this queue.
00090      *
00091      *  When called with a finite timeout, the dispatch function is guaranteed
00092      *  to terminate. When called with a timeout of 0, the dispatch function
00093      *  does not wait and is IRQ safe.
00094      *
00095      *  @param ms       Time to wait for events in milliseconds, a negative
00096      *                  value will dispatch events indefinitely
00097      *                  (default to -1)
00098      */
00099     void dispatch(int ms = -1);
00100 
00101     /** Dispatch events without a timeout
00102      *
00103      *  This is equivalent to EventQueue::dispatch with no arguments, but
00104      *  avoids overload ambiguities when passed as a callback.
00105      *
00106      *  @see EventQueue::dispatch
00107      */
00108     void dispatch_forever()
00109     {
00110         dispatch();
00111     }
00112 
00113     /** Break out of a running event loop
00114      *
00115      *  Forces the specified event queue's dispatch loop to terminate. Pending
00116      *  events may finish executing, but no new events will be executed.
00117      */
00118     void break_dispatch();
00119 
00120     /** Millisecond counter
00121      *
00122      *  Returns the underlying tick of the event queue represented as the
00123      *  number of milliseconds that have passed since an arbitrary point in
00124      *  time. Intentionally overflows to 0 after 2^32-1.
00125      *
00126      *  @return         The underlying tick of the event queue in milliseconds
00127      */
00128     unsigned tick();
00129 
00130     /** Cancel an in-flight event
00131      *
00132      *  Attempts to cancel an event referenced by the unique id returned from
00133      *  one of the call functions. It is safe to call cancel after an event
00134      *  has already been dispatched.
00135      *
00136      *  id must be valid i.e. event must have not finished executing.
00137      *
00138      *  The cancel function is IRQ safe.
00139      *
00140      *  If called while the event queue's dispatch loop is active in another thread,
00141      *  the cancel function does not guarantee that the event will not execute after it
00142      *  returns, as the event may have already begun executing. A call made from
00143      *  the same thread as the dispatch loop will always succeed with a valid id.
00144      *
00145      *  @param id       Unique id of the event
00146      *  @return         true  if event was successfully cancelled
00147      *                  false if event was not cancelled (invalid id or executing already begun)
00148      */
00149     bool cancel(int id);
00150 
00151     /** Cancel an in-flight user allocated event
00152      *
00153      *  Attempts to cancel an UserAllocatedEvent referenced by its address
00154      *  It is safe to call cancel after an event has already been dispatched.
00155      *
00156      *  Event must be valid i.e. event must have not finished executing
00157      *  and must have been bound to this queue.
00158      *
00159      *  The cancel function is IRQ safe.
00160      *
00161      *  If called while the event queue's dispatch loop is active in another thread,
00162      *  the cancel function does not guarantee that the event will not execute after it
00163      *  returns, as the event may have already begun executing. A call made from
00164      *  the same thread as the dispatch loop will always succeed with a valid id.
00165      *
00166      *  @param event    Address of the event
00167      *  @return         true  if event was successfully cancelled
00168      *                  false if event was not cancelled (invalid queue or executing already begun)
00169      */
00170     template<typename F, typename A>
00171     bool cancel(UserAllocatedEvent<F, A> *event)
00172     {
00173         if (event->_equeue != &_equeue) {
00174             return false;
00175         }
00176         return equeue_cancel_user_allocated(&_equeue, event);
00177     }
00178 
00179     /** Query how much time is left for delayed event
00180      *
00181      *  If the event is delayed, this function can be used to query how much time
00182      *  is left until the event is due to be dispatched.
00183      *
00184      *  id must be valid i.e. event must have not finished executing.
00185      *
00186      *  This function is IRQ safe.
00187      *
00188      *  @param id       Unique id of the event
00189      *
00190      *  @return         Remaining time in milliseconds or
00191      *                   0 if event is already due to be dispatched or
00192      *                     is currently executing.
00193      *                  Undefined if id is invalid.
00194      *
00195      */
00196     int time_left(int id);
00197 
00198     /** Query how much time is left for delayed UserAllocatedEvent
00199      *
00200      *  If the event is delayed, this function can be used to query how much time
00201      *  is left until the event is due to be dispatched.
00202      *
00203      *  Event must be valid i.e. event must have not finished executing
00204      *  and must have been bound to this queue.
00205      *
00206      *  This function is IRQ safe.
00207      *
00208      *  @param event    Address of the event
00209      *
00210      *  @return         Remaining time in milliseconds or
00211      *                  0 if event is already due to be dispatched or
00212      *                  is currently executing.
00213      *                  Undefined if id is invalid.
00214      *
00215      */
00216     template<typename F, typename A>
00217     int time_left(UserAllocatedEvent<F, A> *event)
00218     {
00219         if (event && event->_equeue != &_equeue) {
00220             return -1;
00221         }
00222         return equeue_timeleft_user_allocated(&_equeue, &event->_e);
00223     }
00224 
00225     /** Background an event queue onto a single-shot timer-interrupt
00226      *
00227      *  When updated, the event queue will call the provided update function
00228      *  with a timeout indicating when the queue should be dispatched. A
00229      *  negative timeout will be passed to the update function when the
00230      *  timer-interrupt is no longer needed.
00231      *
00232      *  Passing a null function disables the existing update function.
00233      *
00234      *  The background function allows an event queue to take advantage of
00235      *  hardware timers or other event loops, allowing an event queue to be
00236      *  ran in the background without consuming the foreground thread.
00237      *
00238      *  @param update   Function called to indicate when the queue should be
00239      *                  dispatched
00240      */
00241     void background(mbed::Callback<void(int)> update);
00242 
00243     /** Chain an event queue onto another event queue
00244      *
00245      *  After chaining a queue to a target, calling dispatch on the target
00246      *  queue will also dispatch events from this queue. The queues use
00247      *  their own buffers and events must be handled independently.
00248      *
00249      *  A null queue as the target will unchain the existing queue.
00250      *
00251      *  The chain function allows multiple event queues to be composed,
00252      *  sharing the context of a dispatch loop while still being managed
00253      *  independently
00254      *
00255      *  @param target   Queue that will dispatch this queue's events as a
00256      *                  part of its dispatch loop
00257      *
00258      *  @return Zero on success and negative error code value if chaining fails
00259      *
00260      */
00261     int chain(EventQueue *target);
00262 
00263 
00264 
00265 #if defined(DOXYGEN_ONLY)
00266     /** Calls an event on the queue
00267      *
00268      *  The specified callback will be executed in the context of the event
00269      *  queue's dispatch loop.
00270      *
00271      *  The call function is IRQ safe and can act as a mechanism for moving
00272      *  events out of IRQ contexts.
00273      *
00274      *  @param f        Function to execute in the context of the dispatch loop
00275      *  @param args     Arguments to pass to the callback
00276      *  @return         A unique id that represents the posted event and can
00277      *                  be passed to cancel, or an id of 0 if there is not
00278      *                  enough memory to allocate the event.
00279      *                  Returned id will remain valid until event has finished
00280      *                  executing.
00281      *
00282      * @code
00283      *     #include "mbed.h"
00284      *
00285      *     int main() {
00286      *         // creates a queue with the default size
00287      *         EventQueue queue;
00288      *
00289      *         // events are simple callbacks
00290      *         queue.call(printf, "called immediately\n");
00291      *
00292      *         // the dispatch method executes events
00293      *         queue.dispatch();
00294      *     }
00295      * @endcode
00296      */
00297     template <typename F, typename ...Args>
00298     int call(F f, Args ...args);
00299 
00300     /** Calls an event on the queue
00301      *
00302      *  The specified callback is executed in the context of the event
00303      *  queue's dispatch loop.
00304      *
00305      *  The call function is IRQ safe and can act as a mechanism for moving
00306      *  events out of IRQ contexts.
00307      *
00308      *  @param obj        Object to call with the member function
00309      *  @param method     Member function to execute in the context of the dispatch loop
00310      *  @param args       Arguments to pass to the callback
00311      *  @return           A unique ID that represents the posted event and can
00312      *                    be passed to cancel, or an ID of 0 if there is not
00313      *                    enough memory to allocate the event.
00314      *                    Returned ID remains valid until event has finished
00315      *                    executing.
00316      *
00317      * @code
00318      *     #include "mbed.h"
00319      *
00320      *     class EventHandler {
00321      *         int _id;
00322      *     public:
00323      *         EventHandler(int id) : _id(id) { }
00324      *
00325      *         void handler(int c) {
00326      *             printf("ID: %d Param: %d\r\n", _id, c);
00327      *         }
00328      *     };
00329      *
00330      *     int main() {
00331      *         // creates a queue with the default size
00332      *         EventQueue queue;
00333      *
00334      *         // Create EventHandler object with state
00335      *         EventHandler handler_cb(1);
00336      *
00337      *         // events are simple callbacks, call object method
00338      *         // with provided parameter
00339      *         queue.call(&handler_cb, &EventHandler::handler, 2);
00340      *
00341      *         // the dispath method executes events
00342      *         queue.dispatch();
00343      *     }
00344      * @endcode
00345      */
00346     // AStyle ignore, not handling correctly below
00347     // *INDENT-OFF*
00348     template <typename T, typename R, typename ...Args>
00349     int call(T *obj, R (T::*method)(Args ...args), Args ...args);
00350     // *INDENT-ON*
00351 
00352     /** Calls an event on the queue after a specified delay
00353      *
00354      *  The specified callback is executed in the context of the event
00355      *  queue's dispatch loop.
00356      *
00357      *  The call_in function is IRQ safe and can act as a mechanism for moving
00358      *  events out of IRQ contexts.
00359      *
00360      *  @param ms       Time to delay in milliseconds
00361      *  @param args     Arguments to pass to the callback
00362      *  @return         A unique ID that represents the posted event and can
00363      *                  be passed to cancel, or an ID of 0 if there is not
00364      *                  enough memory to allocate the event.
00365      *
00366      * @code
00367      *     #include "mbed.h"
00368      *
00369      *     int main() {
00370      *         // creates a queue with the default size
00371      *         EventQueue queue;
00372      *
00373      *         // events are simple callbacks
00374      *         queue.call_in(2000, printf, "called in 2 seconds\n");
00375      *
00376      *         // the dispatch methods executes events
00377      *         queue.dispatch();
00378      *     }
00379      * @endcode
00380      */
00381     template <typename F, typename ...Args>
00382     int call_in(int ms, Args ...args);
00383 
00384     /** Calls an event on the queue after a specified delay
00385      *
00386      *  The specified callback is executed in the context of the event
00387      *  queue's dispatch loop.
00388      *
00389      *  The call_in function is IRQ safe and can act as a mechanism for moving
00390      *  events out of IRQ contexts.
00391      *
00392      *  @param ms       Time to delay in milliseconds
00393      *  @param obj      Object to call with the member function
00394      *  @param method   Member function to execute in the context of the dispatch loop
00395      *  @param args     Arguments to pass to the callback
00396      *  @return         A unique ID that represents the posted event and can
00397      *                  be passed to cancel, or an ID of 0 if there is not
00398      *                  enough memory to allocate the event.
00399      *
00400      * @code
00401      *     #include "mbed.h"
00402      *
00403      *     class EventHandler {
00404      *         int _id;
00405      *     public:
00406      *         EventHandler(int id) : _id(id) { }
00407      *
00408      *         void handler(int c) {
00409      *             printf("ID: %d Param: %d\r\n", _id, c);
00410      *         }
00411      *     };
00412      *
00413      *     int main() {
00414      *         // creates a queue with the default size
00415      *         EventQueue queue;
00416      *
00417      *         // Create EventHandler object with state
00418      *         EventHandler handler_cb(3);
00419      *
00420      *         // events are simple callbacks, call object method in 2 seconds
00421      *         // with provided parameter
00422      *         queue.call_in(2000, &handler_cb, &EventHandler::handler, 4);
00423      *
00424      *         // the dispatch method executes events
00425      *         queue.dispatch();
00426      *     }
00427      * @endcode
00428      */
00429     // AStyle ignore, not handling correctly below
00430     // *INDENT-OFF*
00431     template <typename T, typename R, typename ...Args>
00432     int call_in(int ms, T *obj, R (T::*method)(Args ...args), Args ...args);
00433     // *INDENT-ON*
00434 
00435     /** Calls an event on the queue periodically
00436      *
00437      *  @note The first call_every event occurs after the specified delay.
00438      *  To create a periodic event that fires immediately, @see Event.
00439      *
00440      *  The specified callback is executed in the context of the event
00441      *  queue's dispatch loop.
00442      *
00443      *  The call_every function is IRQ safe and can act as a mechanism for
00444      *  moving events out of IRQ contexts.
00445      *
00446      *  @param ms       Period of the event in milliseconds
00447      *  @param f        Function to execute in the context of the dispatch loop
00448      *  @param args     Arguments to pass to the callback
00449      *  @return         A unique ID that represents the posted event and can
00450      *                  be passed to cancel, or an ID of 0 if there is not
00451      *                  enough memory to allocate the event.
00452      *
00453      * @code
00454      *     #include "mbed.h"
00455      *
00456      *     class EventHandler {
00457      *         int _id;
00458      *     public:
00459      *         EventHandler(int id) : _id(id) { }
00460      *
00461      *         void handler(int c) {
00462      *             printf("ID: %d Param: %d\r\n", _id, c);
00463      *         }
00464      *     };
00465      *
00466      *     int main() {
00467      *         // creates a queue with the default size
00468      *         EventQueue queue;
00469      *
00470      *         // events are simple callbacks, call every 2 seconds
00471      *         queue.call_every(2000, printf, "Calling every 2 seconds\n");
00472      *
00473      *         // the dispatch method executes events
00474      *         queue.dispatch();
00475      *     }
00476      * @endcode
00477      */
00478     template <typename F, typename ...Args>
00479     int call_every(int ms, F f, Args ...args);
00480 
00481     /** Calls an event on the queue periodically
00482      *
00483      *  @note The first call_every event occurs after the specified delay.
00484      *  To create a periodic event that fires immediately, @see Event.
00485      *
00486      *  The specified callback is executed in the context of the event
00487      *  queue's dispatch loop.
00488      *
00489      *  The call_every function is IRQ safe and can act as a mechanism for
00490      *  moving events out of IRQ contexts.
00491      *
00492      *  @param ms       Period of the event in milliseconds
00493      *  @param obj      Object to call with the member function
00494      *  @param method   Member function to execute in the context of the dispatch loop
00495      *  @param args     Arguments to pass to the callback
00496      *
00497      * @code
00498      *     #include "mbed.h"
00499      *
00500      *     class EventHandler {
00501      *         int _id;
00502      *     public:
00503      *         EventHandler(int id) : _id(id) { }
00504      *
00505      *         void handler(int c) {
00506      *             printf("ID: %d Param: %d\r\n", _id, c);
00507      *         }
00508      *     };
00509      *
00510      *     int main() {
00511      *         // creates a queue with the default size
00512      *         EventQueue queue;
00513      *
00514      *         // Create EventHandler object with state
00515      *         EventHandler handler_cb(5);
00516      *
00517      *         // events are simple callbacks, call object method every 2 seconds
00518      *         // with provided parameter
00519      *         queue.call_every(2000, &handler_cb, &EventHandler::handler, 6);
00520      *
00521      *         // the dispatch method executes events
00522      *         queue.dispatch();
00523      *     }
00524      * @endcode
00525      */
00526     // AStyle ignore, not handling correctly below
00527     // *INDENT-OFF*
00528     template <typename T, typename R, typename ...Args>
00529     int call_every(int ms, T *obj, R (T::*method)(Args ...args), Args ...args);
00530     // *INDENT-ON*
00531 
00532     /** Creates an event bound to the event queue
00533      *
00534      *  Constructs an event bound to the specified event queue. The specified
00535      *  callback acts as the target for the event and is executed in the
00536      *  context of the event queue's dispatch loop once posted.
00537      *
00538      *  @param  func            Function to execute when the event is dispatched
00539      *  @param  context_args    Arguments to pass to the callback
00540      *  @return                 Event that dispatches on the specific queue
00541      *
00542      * @code
00543      *     #include "mbed.h"
00544      *
00545      *     void handler(int c) {
00546      *         printf("Param: %d\r\n", c);
00547      *     }
00548      *
00549      *     int main()
00550      *     {
00551      *         EventQueue queue;
00552      *
00553      *         // Create event with parameter
00554      *         Event<void()>    e  = queue.event(handler, 1);
00555      *         e();
00556      *
00557      *         // Create event and post parameter later
00558      *         Event<void(int)> e2 = queue.event(handler);
00559      *
00560      *         // Post the event with paramter 8
00561      *         e.post(8);
00562      *
00563      *         // The dispatch method executes events
00564      *         queue.dispatch();
00565      *
00566      *         e2.post(2);
00567      *
00568      *         queue.dispatch();
00569      *     }
00570      * @endcode
00571      */
00572     // AStyle ignore, not handling correctly below
00573     // *INDENT-OFF*
00574     template <typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args>
00575     Event<void(Args...)> event(R (*func)(BoundArgs..., Args...), ContextArgs ...context_args);
00576     // *INDENT-ON*
00577 
00578     /** Creates an event bound to the event queue
00579      *
00580      *  Constructs an event bound to the specified event queue. The specified
00581      *  callback acts as the target for the event and is executed in the
00582      *  context of the event queue's dispatch loop once posted.
00583      *
00584      *  @param obj             Object to call with the member function
00585      *  @param method          Member function to execute in the context of the dispatch loop
00586      *  @param context_args    Arguments to pass to the callback
00587      *  @return                Event that dispatches on the specific queue
00588      *
00589      * @code
00590      *     #include "mbed.h"
00591      *
00592      *     class EventHandler {
00593      *         int _id;
00594      *
00595      *     public:
00596      *         EventHandler(int id) : _id(id) { }
00597      *
00598      *         void handler(int c) {
00599      *             printf("ID: %d Param: %d\r\n", _id, c);
00600      *         }
00601      *     };
00602      *
00603      *     int main()
00604      *     {
00605      *         EventQueue queue;
00606      *
00607      *         EventHandler handler_cb(10);
00608      *
00609      *         // Create event on the eventqueue with a method callback
00610      *         Event<void(int)> e = queue.event(&handler_cb, &EventHandler::handler);
00611      *
00612      *         // Post the event with paramter 8
00613      *         e.post(11);
00614      *
00615      *         // The dispatch method executes events
00616      *         queue.dispatch();
00617      *     }
00618      * @endcode
00619      */
00620     // AStyle ignore, not handling correctly below
00621     // *INDENT-OFF*
00622     template <typename T, typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args>
00623     Event<void(Args...)> event(T *obj, R (T::*method)(BoundArgs..., Args...), ContextArgs ...context_args);
00624     // *INDENT-ON*
00625 
00626     /** Creates an event bound to the event queue
00627      *
00628      *  Constructs an event bound to the specified event queue. The specified
00629      *  callback acts as the target for the event and is executed in the
00630      *  context of the event queue's dispatch loop once posted.
00631      *
00632      *  @param  cb             Callback object
00633      *  @param  context_args   Arguments to pass to the callback
00634      *  @return                Event that dispatches on the specific queue
00635      *
00636      *  @code
00637      *     #include "mbed.h"
00638      *
00639      *     void handler(int c) {
00640      *         printf("Param: %d\r\n", c);
00641      *     }
00642      *
00643      *     int main()
00644      *     {
00645      *         EventQueue queue;
00646      *         // Create callback object acting as a function
00647      *         // pointer to handler
00648      *         Callback<void(int)> cb(handler);
00649      *
00650      *         // Pass the callback object to the eventqueue
00651      *         Event<void(int)> e = queue.event(cb);
00652      *
00653      *         // Post the event with parameter 8
00654      *         e.post(9);
00655      *
00656      *         // The dispatch method executes events
00657      *         q.dispatch();
00658      *     }
00659      *  @endcode
00660      */
00661     template <typename R, typename ...BoundArgs, typename ...ContextArgs, typename ...Args>
00662     Event<void(Args...)> event(mbed::Callback<R(BoundArgs..., Args...)> cb, ContextArgs ...context_args);
00663 
00664     /** Creates an user allocated event bound to the event queue
00665      *
00666      *  Constructs an user allocated event bound to the specified event queue.
00667      *  The specified callback acts as the target for the event and is executed
00668      *  in the context of the event queue's dispatch loop once posted.
00669      *
00670      * @code
00671      *  #include "mbed.h"
00672      *
00673      *  void handler(int data) { ... }
00674      *
00675      *  class Device {
00676      *     public:
00677      *     void handler(int data) { ... }
00678      *  };
00679      *
00680      *  Device dev;
00681      *
00682      *  // queue with not internal storage for dynamic events
00683      *  // accepts only user allocated events
00684      *  static EventQueue queue(0);
00685      *  // Create events
00686      *  static auto e1 = make_user_allocated_event(&dev, Device::handler, 2);
00687      *  static auto e2 = queue.make_user_allocated_event(handler, 3);
00688      *
00689      *  int main()
00690      *  {
00691      *    e1.call_on(&queue);
00692      *    e2.call();
00693      *
00694      *    queue.dispatch(1);
00695      *  }
00696      * @endcode
00697      *
00698      *  @param f        Function to execute when the event is dispatched
00699      *  @return         Event that will dispatch on the specific queue
00700      */
00701     template <typename F, typename... ArgTs>
00702     UserAllocatedEvent<F, void(ArgTs...)> make_user_allocated_event(F f, ArgTs... args);
00703 
00704     /** Creates an user allocated event bound to the event queue
00705      *  @see EventQueue::make_user_allocated_event
00706      */
00707     template <typename T, typename R, typename... ArgTs>
00708     UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(T *obj, R(T::*method)(ArgTs... args), ArgTs... args);
00709 
00710 
00711 #else
00712 
00713     /** Calls an event on the queue
00714      *
00715      *  The specified callback is executed in the context of the event
00716      *  queue's dispatch loop.
00717      *
00718      *  The call function is IRQ safe and can act as a mechanism for moving
00719      *  events out of IRQ contexts.
00720      *
00721      *  @param f        Function to execute in the context of the dispatch loop
00722      *  @return         A unique ID that represents the posted event and can
00723      *                  be passed to cancel, or an ID of 0 if there is not
00724      *                  enough memory to allocate the event.
00725      *                  Returned ID remains valid until event has finished
00726      *                  executing.
00727      *
00728      * @code
00729      *     #include "mbed.h"
00730      *
00731      *     int main()
00732      *     {
00733      *         EventQueue queue;
00734      *
00735      *         Callback<void(int)> cb(handler);
00736      *
00737      *         // Create event on the eventqueue with a separate callback object
00738      *         Event<void(int)> e = queue.event(cb);
00739      *         e.post(1);
00740      *         queue.dispatch();
00741      *     }
00742      * @endcode
00743      */
00744     template <typename F>
00745     int call(F f)
00746     {
00747         void *p = equeue_alloc(&_equeue, sizeof(F));
00748         if (!p) {
00749             return 0;
00750         }
00751 
00752         F *e = new (p) F(f);
00753         equeue_event_dtor(e, &EventQueue::function_dtor<F>);
00754         return equeue_post(&_equeue, &EventQueue::function_call<F>, e);
00755     }
00756 
00757 
00758     /** Calls an event on the queue
00759      *  @see                    EventQueue::call
00760      *  @param f                Function to execute in the context of the dispatch loop
00761      *  @param args             Arguments to pass to the callback
00762      */
00763     template <typename F, typename... ArgTs>
00764     int call(F f, ArgTs... args)
00765     {
00766         return call(context<F, ArgTs...>(f, args...));
00767     }
00768 
00769     /** Calls an event on the queue
00770      *  @see EventQueue::call
00771      */
00772     template <typename T, typename R, typename... ArgTs>
00773     int call(T *obj, R(T::*method)(ArgTs...), ArgTs... args)
00774     {
00775         return call(mbed::callback(obj, method), args...);
00776     }
00777 
00778     /** Calls an event on the queue
00779      *  @see EventQueue::call
00780      */
00781     template <typename T, typename R, typename... ArgTs>
00782     int call(const T *obj, R(T::*method)(ArgTs...) const, ArgTs... args)
00783     {
00784         return call(mbed::callback(obj, method), args...);
00785     }
00786 
00787     /** Calls an event on the queue
00788      *  @see EventQueue::call
00789      */
00790     template <typename T, typename R, typename... ArgTs>
00791     int call(volatile T *obj, R(T::*method)(ArgTs...) volatile, ArgTs... args)
00792     {
00793         return call(mbed::callback(obj, method), args...);
00794     }
00795 
00796     /** Calls an event on the queue
00797      *  @see EventQueue::call
00798      */
00799     template <typename T, typename R, typename... ArgTs>
00800     int call(const volatile T *obj, R(T::*method)(ArgTs...) const volatile, ArgTs... args)
00801     {
00802         return call(mbed::callback(obj, method), args...);
00803     }
00804 
00805     /** Calls an event on the queue after a specified delay
00806      *
00807      *  The specified callback will be executed in the context of the event
00808      *  queue's dispatch loop.
00809      *
00810      *  The call_in function is IRQ safe and can act as a mechanism for moving
00811      *  events out of IRQ contexts.
00812      *
00813      *  @param ms       Time to delay in milliseconds
00814      *  @param f        Function to execute in the context of the dispatch loop
00815      *  @return         A unique id that represents the posted event and can
00816      *                  be passed to cancel, or an id of 0 if there is not
00817      *                  enough memory to allocate the event.
00818      */
00819     template <typename F>
00820     int call_in(int ms, F f)
00821     {
00822         void *p = equeue_alloc(&_equeue, sizeof(F));
00823         if (!p) {
00824             return 0;
00825         }
00826 
00827         F *e = new (p) F(f);
00828         equeue_event_delay(e, ms);
00829         equeue_event_dtor(e, &EventQueue::function_dtor<F>);
00830         return equeue_post(&_equeue, &EventQueue::function_call<F>, e);
00831     }
00832 
00833     /** Calls an event on the queue after a specified delay
00834      *  @see                        EventQueue::call_in
00835      *  @param ms                   Time to delay in milliseconds
00836      *  @param f                    Function to execute in the context of the dispatch loop
00837      *  @param args                 Arguments to pass to the callback
00838      */
00839     template <typename F, typename... ArgTs>
00840     int call_in(int ms, F f, ArgTs... args)
00841     {
00842         return call_in(ms, context<F, ArgTs...>(f, args...));
00843     }
00844 
00845     /** Calls an event on the queue after a specified delay
00846      *  @see EventQueue::call_in
00847      */
00848     template <typename T, typename R, typename... ArgTs>
00849     int call_in(int ms, T *obj, R(T::*method)(ArgTs...), ArgTs... args)
00850     {
00851         return call_in(ms, mbed::callback(obj, method), args...);
00852     }
00853 
00854     /** Calls an event on the queue after a specified delay
00855      *  @see EventQueue::call_in
00856      */
00857     template <typename T, typename R, typename... ArgTs>
00858     int call_in(int ms, const T *obj, R(T::*method)(ArgTs...) const, ArgTs... args)
00859     {
00860         return call_in(ms, mbed::callback(obj, method), args...);
00861     }
00862 
00863     /** Calls an event on the queue after a specified delay
00864      *  @see EventQueue::call_in
00865      */
00866     template <typename T, typename R, typename... ArgTs>
00867     int call_in(int ms, volatile T *obj, R(T::*method)(ArgTs...) volatile, ArgTs... args)
00868     {
00869         return call_in(ms, mbed::callback(obj, method), args...);
00870     }
00871 
00872     /** Calls an event on the queue after a specified delay
00873      *  @see EventQueue::call_in
00874      */
00875     template <typename T, typename R, typename... ArgTs>
00876     int call_in(int ms, const volatile T *obj, R(T::*method)(ArgTs...) const volatile, ArgTs... args)
00877     {
00878         return call_in(ms, mbed::callback(obj, method), args...);
00879     }
00880 
00881     /** Calls an event on the queue periodically
00882      *
00883      *  @note The first call_every event occurs after the specified delay.
00884      *  To create a periodic event that fires immediately, @see Event.
00885      *
00886      *  The specified callback will be executed in the context of the event
00887      *  queue's dispatch loop.
00888      *
00889      *  The call_every function is IRQ safe and can act as a mechanism for
00890      *  moving events out of IRQ contexts.
00891      *
00892      *  @param f        Function to execute in the context of the dispatch loop
00893      *  @param ms       Period of the event in milliseconds
00894      *  @return         A unique id that represents the posted event and can
00895      *                  be passed to cancel, or an id of 0 if there is not
00896      *                  enough memory to allocate the event.
00897      */
00898     template <typename F>
00899     int call_every(int ms, F f)
00900     {
00901         void *p = equeue_alloc(&_equeue, sizeof(F));
00902         if (!p) {
00903             return 0;
00904         }
00905 
00906         F *e = new (p) F(f);
00907         equeue_event_delay(e, ms);
00908         equeue_event_period(e, ms);
00909         equeue_event_dtor(e, &EventQueue::function_dtor<F>);
00910         return equeue_post(&_equeue, &EventQueue::function_call<F>, e);
00911     }
00912 
00913     /** Calls an event on the queue periodically
00914      *  @see                    EventQueue::call_every
00915      *  @param f                Function to execute in the context of the dispatch loop
00916      *  @param args             Arguments to pass to the callback
00917      *  @param ms               Period of the event in milliseconds
00918      */
00919     template <typename F, typename... ArgTs>
00920     int call_every(int ms, F f, ArgTs... args)
00921     {
00922         return call_every(ms, context<F, ArgTs...>(f, args...));
00923     }
00924 
00925     /** Calls an event on the queue periodically
00926      *  @see EventQueue::call_every
00927      */
00928     template <typename T, typename R, typename... ArgTs>
00929     int call_every(int ms, T *obj, R(T::*method)(ArgTs...), ArgTs... args)
00930     {
00931         return call_every(ms, mbed::callback(obj, method), args...);
00932     }
00933 
00934     /** Calls an event on the queue periodically
00935      *  @see EventQueue::call_every
00936      */
00937     template <typename T, typename R, typename... ArgTs>
00938     int call_every(int ms, const T *obj, R(T::*method)(ArgTs...) const, ArgTs... args)
00939     {
00940         return call_every(ms, mbed::callback(obj, method), args...);
00941     }
00942 
00943     /** Calls an event on the queue periodically
00944      *  @see EventQueue::call_every
00945      */
00946     template <typename T, typename R, typename... ArgTs>
00947     int call_every(int ms, volatile T *obj, R(T::*method)(ArgTs...) volatile, ArgTs... args)
00948     {
00949         return call_every(ms, mbed::callback(obj, method), args...);
00950     }
00951 
00952     /** Calls an event on the queue periodically
00953      *  @see EventQueue::call_every
00954      */
00955     template <typename T, typename R, typename... ArgTs>
00956     int call_every(int ms, const volatile T *obj, R(T::*method)(ArgTs...) const volatile, ArgTs... args)
00957     {
00958         return call_every(ms, mbed::callback(obj, method), args...);
00959     }
00960 
00961     /** Creates an event bound to the event queue
00962      *
00963      *  Constructs an event bound to the specified event queue. The specified
00964      *  callback acts as the target for the event and is executed in the
00965      *  context of the event queue's dispatch loop once posted.
00966      *
00967      *  @param func        Function to execute when the event is dispatched
00968      *  @return            Event that will dispatch on the specific queue
00969      */
00970     template <typename R, typename... ArgTs>
00971     Event<void(ArgTs...)> event(R(*func)(ArgTs...));
00972 
00973     /** Creates an event bound to the event queue
00974      *  @see EventQueue::event
00975      */
00976     template <typename T, typename R, typename... ArgTs>
00977     Event<void(ArgTs...)> event(T *obj, R(T::*method)(ArgTs...));
00978 
00979     /** Creates an event bound to the event queue
00980      *  @see EventQueue::event
00981      */
00982     template <typename T, typename R, typename... ArgTs>
00983     Event<void(ArgTs...)> event(const T *obj, R(T::*method)(ArgTs...) const);
00984 
00985     /** Creates an event bound to the event queue
00986      *  @see EventQueue::event
00987      */
00988     template <typename T, typename R, typename... ArgTs>
00989     Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(ArgTs...) volatile);
00990 
00991     /** Creates an event bound to the event queue
00992      *  @see EventQueue::event
00993      */
00994     template <typename T, typename R, typename... ArgTs>
00995     Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(ArgTs...) const volatile);
00996 
00997     /** Creates an event bound to the event queue
00998      *  @see EventQueue::event
00999      */
01000     template <typename R, typename... ArgTs>
01001     Event<void(ArgTs...)> event(mbed::Callback<R(ArgTs...)> cb);
01002 
01003     /** Creates an event bound to the event queue
01004      *  @see EventQueue::event
01005      */
01006     template <typename R, typename B0, typename C0, typename... ArgTs>
01007     Event<void(ArgTs...)> event(R(*func)(B0, ArgTs...), C0 c0);
01008 
01009     /** Creates an event bound to the event queue
01010      *  @see EventQueue::event
01011      */
01012     template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
01013     Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, ArgTs...), C0 c0);
01014 
01015     /** Creates an event bound to the event queue
01016      *  @see EventQueue::event
01017      */
01018     template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
01019     Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, ArgTs...) const, C0 c0);
01020 
01021     /** Creates an event bound to the event queue
01022      *  @see EventQueue::event
01023      */
01024     template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
01025     Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, ArgTs...) volatile, C0 c0);
01026 
01027     /** Creates an event bound to the event queue
01028      *  @see EventQueue::event
01029      */
01030     template <typename T, typename R, typename B0, typename C0, typename... ArgTs>
01031     Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, ArgTs...) const volatile, C0 c0);
01032 
01033     /** Creates an event bound to the event queue
01034      *  @see EventQueue::event
01035      */
01036     template <typename R, typename B0, typename C0, typename... ArgTs>
01037     Event<void(ArgTs...)> event(mbed::Callback<R(B0, ArgTs...)> cb, C0 c0);
01038 
01039     /** Creates an event bound to the event queue
01040      *  @see EventQueue::event
01041      */
01042     template <typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
01043     Event<void(ArgTs...)> event(R(*func)(B0, B1, ArgTs...), C0 c0, C1 c1);
01044 
01045     /** Creates an event bound to the event queue
01046      *  @see EventQueue::event
01047      */
01048     template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
01049     Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, B1, ArgTs...), C0 c0, C1 c1);
01050 
01051     /** Creates an event bound to the event queue
01052      *  @see EventQueue::event
01053      */
01054     template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
01055     Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, B1, ArgTs...) const, C0 c0, C1 c1);
01056 
01057     /** Creates an event bound to the event queue
01058      *  @see EventQueue::event
01059      */
01060     template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
01061     Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, B1, ArgTs...) volatile, C0 c0, C1 c1);
01062 
01063     /** Creates an event bound to the event queue
01064      *  @see EventQueue::event
01065      */
01066     template <typename T, typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
01067     Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, B1, ArgTs...) const volatile, C0 c0, C1 c1);
01068 
01069     /** Creates an event bound to the event queue
01070      *  @see EventQueue::event
01071      */
01072     template <typename R, typename B0, typename B1, typename C0, typename C1, typename... ArgTs>
01073     Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, ArgTs...)> cb, C0 c0, C1 c1);
01074 
01075     /** Creates an event bound to the event queue
01076      *  @see EventQueue::event
01077      */
01078     template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
01079     Event<void(ArgTs...)> event(R(*func)(B0, B1, B2, ArgTs...), C0 c0, C1 c1, C2 c2);
01080 
01081     /** Creates an event bound to the event queue
01082      *  @see EventQueue::event
01083      */
01084     template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
01085     Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, B1, B2, ArgTs...), C0 c0, C1 c1, C2 c2);
01086 
01087     /** Creates an event bound to the event queue
01088      *  @see EventQueue::event
01089      */
01090     template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
01091     Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, B1, B2, ArgTs...) const, C0 c0, C1 c1, C2 c2);
01092 
01093     /** Creates an event bound to the event queue
01094      *  @see EventQueue::event
01095      */
01096     template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
01097     Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, B1, B2, ArgTs...) volatile, C0 c0, C1 c1, C2 c2);
01098 
01099     /** Creates an event bound to the event queue
01100      *  @see EventQueue::event
01101      */
01102     template <typename T, typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
01103     Event<void(ArgTs...)> event(const volatile T *obj, R(T::*method)(B0, B1, B2, ArgTs...) const volatile, C0 c0, C1 c1, C2 c2);
01104 
01105     /** Creates an event bound to the event queue
01106      *  @see EventQueue::event
01107      */
01108     template <typename R, typename B0, typename B1, typename B2, typename C0, typename C1, typename C2, typename... ArgTs>
01109     Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, B2, ArgTs...)> cb, C0 c0, C1 c1, C2 c2);
01110 
01111     /** Creates an event bound to the event queue
01112      *  @see EventQueue::event
01113      */
01114     template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
01115     Event<void(ArgTs...)> event(R(*func)(B0, B1, B2, B3, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3);
01116 
01117     /** Creates an event bound to the event queue
01118      *  @see EventQueue::event
01119      */
01120     template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
01121     Event<void(ArgTs...)> event(T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3);
01122 
01123     /** Creates an event bound to the event queue
01124      *  @see EventQueue::event
01125      */
01126     template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
01127     Event<void(ArgTs...)> event(const T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) const, C0 c0, C1 c1, C2 c2, C3 c3);
01128 
01129     /** Creates an event bound to the event queue
01130      *  @see EventQueue::event
01131      */
01132     template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
01133     Event<void(ArgTs...)> event(volatile T *obj, R(T::*method)(B0, B1, B2, B3, ArgTs...) volatile, C0 c0, C1 c1, C2 c2, C3 c3);
01134 
01135     /** Creates an event bound to the event queue
01136      *  @see EventQueue::event
01137      */
01138     template <typename T, typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
01139     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);
01140 
01141     /** Creates an event bound to the event queue
01142      *  @see EventQueue::event
01143      */
01144     template <typename R, typename B0, typename B1, typename B2, typename B3, typename C0, typename C1, typename C2, typename C3, typename... ArgTs>
01145     Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, B2, B3, ArgTs...)> cb, C0 c0, C1 c1, C2 c2, C3 c3);
01146 
01147     /** Creates an event bound to the event queue
01148      *  @see EventQueue::event
01149      */
01150     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>
01151     Event<void(ArgTs...)> event(R(*func)(B0, B1, B2, B3, B4, ArgTs...), C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
01152 
01153     /** Creates an event bound to the event queue
01154      *  @see EventQueue::event
01155      */
01156     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>
01157     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);
01158 
01159     /** Creates an event bound to the event queue
01160      *  @see EventQueue::event
01161      */
01162     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>
01163     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);
01164 
01165     /** Creates an event bound to the event queue
01166      *  @see EventQueue::event
01167      */
01168     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>
01169     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);
01170 
01171     /** Creates an event bound to the event queue
01172      *  @see EventQueue::event
01173      */
01174     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>
01175     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);
01176 
01177     /** Creates an event bound to the event queue
01178      *  @see EventQueue::event
01179      */
01180     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>
01181     Event<void(ArgTs...)> event(mbed::Callback<R(B0, B1, B2, B3, B4, ArgTs...)> cb, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4);
01182 
01183     /** Creates an user allocated event bound to the event queue
01184      *
01185      *  Constructs an user allocated event bound to the specified event queue.
01186      *  The specified callback acts as the target for the event and is executed
01187      *  in the context of the event queue's dispatch loop once posted.
01188      *
01189      *  @param f           Function to execute when the event is dispatched
01190      *  @return            Event that will dispatch on the specific queue
01191      */
01192     template <typename F, typename... ArgTs>
01193     UserAllocatedEvent<F, void(ArgTs...)> make_user_allocated_event(F f, ArgTs... args);
01194 
01195     /** Creates an user allocated event bound to the event queue
01196      *  @see EventQueue::make_user_allocated_event
01197      */
01198     template <typename T, typename R, typename... ArgTs>
01199     UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(T *obj, R(T::*method)(ArgTs... args), ArgTs... args);
01200 
01201     /** Creates an user allocated event bound to the event queue
01202      *  @see EventQueue::make_user_allocated_event
01203      */
01204     template <typename T, typename R, typename... ArgTs>
01205     UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(const T *obj, R(T::*method)(ArgTs... args) const, ArgTs... args);
01206 
01207     /** Creates an user allocated event bound to the event queue
01208      *  @see EventQueue::make_user_allocated_event
01209      */
01210     template <typename T, typename R, typename... ArgTs>
01211     UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(volatile T *obj, R(T::*method)(ArgTs... args) volatile, ArgTs... args);
01212 
01213     /** Creates an user allocated event bound to the event queue
01214      *  @see EventQueue::make_user_allocated_event
01215      */
01216     template <typename T, typename R, typename... ArgTs>
01217     UserAllocatedEvent<mbed::Callback<void(ArgTs...)>, void(ArgTs...)> make_user_allocated_event(const volatile T *obj, R(T::*method)(ArgTs... args) const volatile, ArgTs... args);
01218 #endif
01219 
01220 protected:
01221 #if !defined(DOXYGEN_ONLY)
01222     template <typename F>
01223     friend class Event;
01224     template <typename F, typename A>
01225     friend class UserAllocatedEvent;
01226     struct equeue _equeue;
01227     mbed::Callback<void(int)> _update;
01228 
01229     // Function attributes
01230     template <typename F>
01231     static void function_call(void *p)
01232     {
01233         (*(F *)p)();
01234     }
01235 
01236     template <typename F>
01237     static void function_dtor(void *p)
01238     {
01239         ((F *)p)->~F();
01240     }
01241 
01242     // Context structures
01243     template <typename F, typename... ContextArgTs>
01244     struct context;
01245 
01246     template <typename F>
01247     struct context<F> {
01248         F f;
01249 
01250         constexpr context(F f)
01251             : f(f) {}
01252 
01253         template <typename... ArgTs>
01254         void operator()(ArgTs... args)
01255         {
01256             f(args...);
01257         }
01258     };
01259 
01260     template <typename F, typename C0>
01261     struct context<F, C0> {
01262         F f;
01263         C0 c0;
01264 
01265         constexpr context(F f, C0 c0)
01266             : f(f), c0(c0) {}
01267 
01268         template <typename... ArgTs>
01269         void operator()(ArgTs... args)
01270         {
01271             f(c0, args...);
01272         }
01273     };
01274 
01275     template <typename F, typename C0, typename C1>
01276     struct context<F, C0, C1> {
01277         F f;
01278         C0 c0;
01279         C1 c1;
01280 
01281         constexpr context(F f, C0 c0, C1 c1)
01282             : f(f), c0(c0), c1(c1) {}
01283 
01284         template <typename... ArgTs>
01285         void operator()(ArgTs... args)
01286         {
01287             f(c0, c1, args...);
01288         }
01289     };
01290 
01291     template <typename F, typename C0, typename C1, typename C2>
01292     struct context<F, C0, C1, C2> {
01293         F f;
01294         C0 c0;
01295         C1 c1;
01296         C2 c2;
01297 
01298         constexpr context(F f, C0 c0, C1 c1, C2 c2)
01299             : f(f), c0(c0), c1(c1), c2(c2) {}
01300 
01301         template <typename... ArgTs>
01302         void operator()(ArgTs... args)
01303         {
01304             f(c0, c1, c2, args...);
01305         }
01306     };
01307 
01308     template <typename F, typename C0, typename C1, typename C2, typename C3>
01309     struct context<F, C0, C1, C2, C3> {
01310         F f;
01311         C0 c0;
01312         C1 c1;
01313         C2 c2;
01314         C3 c3;
01315 
01316         constexpr context(F f, C0 c0, C1 c1, C2 c2, C3 c3)
01317             : f(f), c0(c0), c1(c1), c2(c2), c3(c3) {}
01318 
01319         template <typename... ArgTs>
01320         void operator()(ArgTs... args)
01321         {
01322             f(c0, c1, c2, c3, args...);
01323         }
01324     };
01325 
01326     template <typename F, typename C0, typename C1, typename C2, typename C3, typename C4>
01327     struct context<F, C0, C1, C2, C3, C4> {
01328         F f;
01329         C0 c0;
01330         C1 c1;
01331         C2 c2;
01332         C3 c3;
01333         C4 c4;
01334 
01335         constexpr context(F f, C0 c0, C1 c1, C2 c2, C3 c3, C4 c4)
01336             : f(f), c0(c0), c1(c1), c2(c2), c3(c3), c4(c4) {}
01337 
01338         template <typename... ArgTs>
01339         void operator()(ArgTs... args)
01340         {
01341             f(c0, c1, c2, c3, c4, args...);
01342         }
01343     };
01344 #endif //!defined(DOXYGEN_ONLY)
01345 };
01346 
01347 /** @}*/
01348 /** @}*/
01349 
01350 }
01351 
01352 #endif