add "LE Device Address" 0x1B to advertising data types
Fork of BLE_API by
CallChainOfFunctionPointersWithContext.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 #ifndef MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H 00017 #define MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H 00018 00019 #include <string.h> 00020 #include "FunctionPointerWithContext.h" 00021 #include "SafeBool.h" 00022 00023 00024 /** Group one or more functions in an instance of a CallChainOfFunctionPointersWithContext, then call them in 00025 * sequence using CallChainOfFunctionPointersWithContext::call(). Used mostly by the interrupt chaining code, 00026 * but can be used for other purposes. 00027 * 00028 * Example: 00029 * @code 00030 * 00031 * CallChainOfFunctionPointersWithContext<void *> chain; 00032 * 00033 * void first(void *context) { 00034 * printf("'first' function.\n"); 00035 * } 00036 * 00037 * void second(void *context) { 00038 * printf("'second' function.\n"); 00039 * } 00040 * 00041 * class Test { 00042 * public: 00043 * void f(void *context) { 00044 * printf("A::f (class member).\n"); 00045 * } 00046 * }; 00047 * 00048 * int main() { 00049 * Test test; 00050 * 00051 * chain.add(second); 00052 * chain.add_front(first); 00053 * chain.add(&test, &Test::f); 00054 * chain.call(); 00055 * } 00056 * @endcode 00057 */ 00058 00059 template <typename ContextType> 00060 class CallChainOfFunctionPointersWithContext : public SafeBool<CallChainOfFunctionPointersWithContext<ContextType> > { 00061 public: 00062 typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t; 00063 00064 public: 00065 /** Create an empty chain. 00066 * 00067 * @param size (optional) Initial size of the chain. 00068 */ 00069 CallChainOfFunctionPointersWithContext() : chainHead(NULL) { 00070 /* empty */ 00071 } 00072 00073 virtual ~CallChainOfFunctionPointersWithContext() { 00074 clear(); 00075 } 00076 00077 /** Add a function at the front of the chain. 00078 * 00079 * @param function A pointer to a void function. 00080 * 00081 * @returns 00082 * The function object created for 'function'. 00083 */ 00084 pFunctionPointerWithContext_t add(void (*function)(ContextType context)) { 00085 return common_add(new FunctionPointerWithContext<ContextType>(function)); 00086 } 00087 00088 /** Add a function at the front of the chain. 00089 * 00090 * @param tptr Pointer to the object to call the member function on. 00091 * @param mptr Pointer to the member function to be called. 00092 * 00093 * @returns 00094 * The function object created for 'tptr' and 'mptr'. 00095 */ 00096 template<typename T> 00097 pFunctionPointerWithContext_t add(T *tptr, void (T::*mptr)(ContextType context)) { 00098 return common_add(new FunctionPointerWithContext<ContextType>(tptr, mptr)); 00099 } 00100 00101 /** Add a function at the front of the chain. 00102 * 00103 * @param func The FunctionPointerWithContext to add. 00104 */ 00105 pFunctionPointerWithContext_t add(const FunctionPointerWithContext<ContextType>& func) { 00106 return common_add(new FunctionPointerWithContext<ContextType>(func)); 00107 } 00108 00109 /** 00110 * Detach a function pointer from a callchain 00111 * 00112 * @oaram toDetach FunctionPointerWithContext to detach from this callchain 00113 * 00114 * @return true if a function pointer has been detached and false otherwise 00115 */ 00116 bool detach(const FunctionPointerWithContext<ContextType>& toDetach) { 00117 pFunctionPointerWithContext_t current = chainHead; 00118 pFunctionPointerWithContext_t previous = NULL; 00119 00120 while (current) { 00121 if(*current == toDetach) { 00122 if(previous == NULL) { 00123 if(currentCalled == current) { 00124 currentCalled = NULL; 00125 } 00126 chainHead = current->getNext(); 00127 } else { 00128 if(currentCalled == current) { 00129 currentCalled = previous; 00130 } 00131 previous->chainAsNext(current->getNext()); 00132 } 00133 delete current; 00134 return true; 00135 } 00136 00137 previous = current; 00138 current = current->getNext(); 00139 } 00140 00141 return false; 00142 } 00143 00144 /** Clear the call chain (remove all functions in the chain). 00145 */ 00146 void clear(void) { 00147 pFunctionPointerWithContext_t fptr = chainHead; 00148 while (fptr) { 00149 pFunctionPointerWithContext_t deadPtr = fptr; 00150 fptr = deadPtr->getNext(); 00151 delete deadPtr; 00152 } 00153 00154 chainHead = NULL; 00155 } 00156 00157 bool hasCallbacksAttached(void) const { 00158 return (chainHead != NULL); 00159 } 00160 00161 /** Call all the functions in the chain in sequence 00162 */ 00163 void call(ContextType context) { 00164 ((const CallChainOfFunctionPointersWithContext*) this)->call(context); 00165 } 00166 00167 /** 00168 * @brief same as above but const 00169 */ 00170 void call(ContextType context) const { 00171 currentCalled = chainHead; 00172 00173 while(currentCalled) { 00174 currentCalled->call(context); 00175 // if this was the head and the call removed the head 00176 if(currentCalled == NULL) { 00177 currentCalled = chainHead; 00178 } else { 00179 currentCalled = currentCalled->getNext(); 00180 } 00181 } 00182 } 00183 00184 /** 00185 * @brief same as above but with function call operator 00186 * \code 00187 * 00188 * void first(bool); 00189 * void second(bool); 00190 * 00191 * CallChainOfFunctionPointerWithContext<bool> foo; 00192 * 00193 * foo.attach(first); 00194 * foo.attach(second); 00195 * 00196 * // call the callchain like a function 00197 * foo(true); 00198 * 00199 * \endcode 00200 */ 00201 void operator()(ContextType context) const { 00202 call(context); 00203 } 00204 00205 /** 00206 * @brief bool conversion operation 00207 */ 00208 bool toBool() const { 00209 return chainHead != NULL; 00210 } 00211 00212 private: 00213 pFunctionPointerWithContext_t common_add(pFunctionPointerWithContext_t pf) { 00214 if (chainHead == NULL) { 00215 chainHead = pf; 00216 } else { 00217 pf->chainAsNext(chainHead); 00218 chainHead = pf; 00219 } 00220 00221 return chainHead; 00222 } 00223 00224 private: 00225 pFunctionPointerWithContext_t chainHead; 00226 // iterator during a function call, this has to be mutable because the call function is const. 00227 // Note: mutable is the correct behaviour here, the iterator never leak outside the object. 00228 // So the object can still be seen as logically const even if it change its internal state 00229 mutable pFunctionPointerWithContext_t currentCalled; 00230 00231 00232 /* Disallow copy constructor and assignment operators. */ 00233 private: 00234 CallChainOfFunctionPointersWithContext(const CallChainOfFunctionPointersWithContext &); 00235 CallChainOfFunctionPointersWithContext & operator = (const CallChainOfFunctionPointersWithContext &); 00236 }; 00237 00238 #endif
Generated on Fri Jul 15 2022 20:49:45 by 1.7.2