Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of BLE_API by
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
Generated on Tue Jul 12 2022 18:47:13 by
