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_WallbotBLE_Challenge 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 namespace mbed { 00023 00024 /** A class for storing and calling a pointer to a static or member void function 00025 * which takes a context. 00026 */ 00027 template <typename ContextType> 00028 class FunctionPointerWithContext { 00029 public: 00030 typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t; 00031 typedef void (*pvoidfcontext_t)(ContextType context); 00032 00033 /** Create a FunctionPointerWithContext, attaching a static function 00034 * 00035 * @param function The void static function to attach (default is none) 00036 */ 00037 FunctionPointerWithContext(void (*function)(ContextType context) = NULL) : 00038 _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) { 00039 attach(function); 00040 } 00041 00042 /** Create a FunctionPointerWithContext, attaching a member function 00043 * 00044 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00045 * @param function The address of the void member function to attach 00046 */ 00047 template<typename T> 00048 FunctionPointerWithContext(T *object, void (T::*member)(ContextType context)) : 00049 _function(NULL), _object(NULL), _member(), _membercaller(NULL), _next(NULL) { 00050 attach(object, member); 00051 } 00052 00053 /** Attach a static function 00054 * 00055 * @param function The void static function to attach (default is none) 00056 */ 00057 void attach(void (*function)(ContextType context) = NULL) { 00058 _function = function; 00059 } 00060 00061 /** Attach a member function 00062 * 00063 * @param object The object pointer to invoke the member function on (i.e. the this pointer) 00064 * @param function The address of the void member function to attach 00065 */ 00066 template<typename T> 00067 void attach(T *object, void (T::*member)(ContextType context)) { 00068 _object = static_cast<void *>(object); 00069 memcpy(_member, (char *)&member, sizeof(member)); 00070 _membercaller = &FunctionPointerWithContext::membercaller<T>; 00071 } 00072 00073 /** Call the attached static or member function; and if there are chained 00074 * FunctionPointers their callbacks are invoked as well. 00075 * @Note: all chained callbacks stack up; so hopefully there won't be too 00076 * many FunctionPointers in a chain. */ 00077 void call(ContextType context) { 00078 if (_function) { 00079 _function(context); 00080 } else if (_object && _membercaller) { 00081 _membercaller(_object, _member, context); 00082 } 00083 00084 /* Propagate the call to next in the chain. */ 00085 if (_next) { 00086 _next->call(context); 00087 } 00088 } 00089 00090 /** 00091 * Setup an external FunctionPointer as a next in the chain of related 00092 * callbacks. Invoking call() on the head FunctionPointer will invoke all 00093 * chained callbacks. 00094 * 00095 * Refer to 'CallChain' as an alternative. 00096 */ 00097 void chainAsNext(pFunctionPointerWithContext_t next) { 00098 _next = next; 00099 } 00100 00101 pFunctionPointerWithContext_t getNext(void) const { 00102 return _next; 00103 } 00104 00105 pvoidfcontext_t get_function() const { 00106 return (pvoidfcontext_t)_function; 00107 } 00108 00109 private: 00110 template<typename T> 00111 static void membercaller(void *object, char *member, ContextType context) { 00112 T *o = static_cast<T *>(object); 00113 void (T::*m)(ContextType); 00114 memcpy((char *)&m, member, sizeof(m)); 00115 (o->*m)(context); 00116 } 00117 00118 void (*_function)(ContextType context); /**< static function pointer - NULL if none attached */ 00119 void *_object; /**< object this pointer - NULL if none attached */ 00120 char _member[16]; /**< raw member function pointer storage - converted back by 00121 * registered _membercaller */ 00122 void (*_membercaller)(void *, char *, ContextType); /**< registered membercaller function to convert back and call 00123 * _member on _object passing the context. */ 00124 pFunctionPointerWithContext_t _next; /**< Optional link to make a chain out of functionPointers; this 00125 * allows chaining function pointers without requiring 00126 * external memory to manage the chain. Also refer to 00127 * 'CallChain' as an alternative. */ 00128 }; 00129 } // namespace mbed 00130 00131 #endif // ifndef MBED_FUNCTIONPOINTER_WITH_CONTEXT_H
Generated on Tue Jul 12 2022 13:52:30 by
