my version with changed conversion between duration units

Fork of BLE_API by Bluetooth Low Energy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FunctionPointerWithContext.h Source File

FunctionPointerWithContext.h

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H
00018 #define MBED_FUNCTIONPOINTER_WITH_CONTEXT_H
00019 
00020 #include <string.h>
00021 
00022 
00023 /** A class for storing and calling a pointer to a static or member void function
00024  *  which takes a context.
00025  */
00026 template <typename ContextType>
00027 class FunctionPointerWithContext {
00028 public:
00029     typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t;
00030     typedef void (*pvoidfcontext_t)(ContextType context);
00031 
00032     /** Create a FunctionPointerWithContext, attaching a static function
00033      *
00034      *  @param function The void static function to attach (default is none)
00035      */
00036     FunctionPointerWithContext(void (*function)(ContextType context) = NULL) :
00037         _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) {
00038         attach(function);
00039     }
00040 
00041     /** Create a FunctionPointerWithContext, attaching a member function
00042      *
00043      *  @param object The object pointer to invoke the member function on (i.e. the this pointer)
00044      *  @param function The address of the void member function to attach
00045      */
00046     template<typename T>
00047     FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) :
00048         _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) {
00049         attach(object, member);
00050     }
00051 
00052     /** Attach a static function
00053      *
00054      *  @param function The void static function to attach (default is none)
00055      */
00056     void attach(void (*function)(ContextType context) = NULL) {
00057         _function = function;
00058     }
00059 
00060     /** Attach a member function
00061      *
00062      *  @param object The object pointer to invoke the member function on (i.e. the this pointer)
00063      *  @param function The address of the void member function to attach
00064      */
00065     template<typename T>
00066     void attach(T *object, void (T::*member)(ContextType context)) {
00067         _object = static_cast<void *>(object);
00068         memcpy(_member, (char *)&member, sizeof(member));
00069         _membercaller = &FunctionPointerWithContext::membercaller<T>;
00070     }
00071 
00072     /** Call the attached static or member function; and if there are chained
00073      *  FunctionPointers their callbacks are invoked as well.
00074      *  @Note: all chained callbacks stack up; so hopefully there won't be too
00075      *  many FunctionPointers in a chain. */
00076     void call(ContextType context) {
00077         if (_function) {
00078             _function(context);
00079         } else if (_object && _membercaller) {
00080             _membercaller(_object, _member, context);
00081         }
00082 
00083         /* Propagate the call to next in the chain. */
00084         if (_next) {
00085             _next->call(context);
00086         }
00087     }
00088 
00089     /**
00090      * Setup an external FunctionPointer as a next in the chain of related
00091      * callbacks. Invoking call() on the head FunctionPointer will invoke all
00092      * chained callbacks.
00093      *
00094      * Refer to 'CallChain' as an alternative.
00095      */
00096     void chainAsNext(pFunctionPointerWithContext_t  next) {
00097         _next = next;
00098     }
00099 
00100     pFunctionPointerWithContext_t getNext(void) const {
00101         return _next;
00102     }
00103 
00104     pvoidfcontext_t get_function() const {
00105         return (pvoidfcontext_t)_function;
00106     }
00107 
00108 private:
00109     template<typename T>
00110     static void membercaller(void *object, char *member, ContextType context) {
00111         T *o = static_cast<T *>(object);
00112         void (T::*m)(ContextType);
00113         memcpy((char *)&m, member, sizeof(m));
00114         (o->*m)(context);
00115     }
00116 
00117     void (*_function)(ContextType context);             /**< static function pointer - NULL if none attached */
00118     void *_object;                                      /**< object this pointer - NULL if none attached */
00119     char _member[16];                                   /**< raw member function pointer storage - converted back by
00120                                                          *   registered _membercaller */
00121     void (*_membercaller)(void *, char *, ContextType); /**< registered membercaller function to convert back and call
00122                                                          *   _member on _object passing the context. */
00123     pFunctionPointerWithContext_t _next;                /**< Optional link to make a chain out of functionPointers; this
00124                                                          *   allows chaining function pointers without requiring
00125                                                          *   external memory to manage the chain. Also refer to
00126                                                          *   'CallChain' as an alternative. */
00127 };
00128 
00129 #endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H