just a fork

Fork of BLE_API by Bluetooth Low Energy

Committer:
vcoubard
Date:
Wed Apr 06 19:14:15 2016 +0100
Revision:
1147:79a44226e47a
Parent:
1146:3fbf341b09dd
Child:
1155:e28c7aac64ab
Synchronized with git rev 342a3cde
Author: Andres Amaya Garcia
Add missing documentation to CallchainOfFunctionPointersWithContext.h

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vcoubard 1146:3fbf341b09dd 1 /* mbed Microcontroller Library
vcoubard 1146:3fbf341b09dd 2 * Copyright (c) 2006-2013 ARM Limited
vcoubard 1146:3fbf341b09dd 3 *
vcoubard 1146:3fbf341b09dd 4 * Licensed under the Apache License, Version 2.0 (the "License");
vcoubard 1146:3fbf341b09dd 5 * you may not use this file except in compliance with the License.
vcoubard 1146:3fbf341b09dd 6 * You may obtain a copy of the License at
vcoubard 1146:3fbf341b09dd 7 *
vcoubard 1146:3fbf341b09dd 8 * http://www.apache.org/licenses/LICENSE-2.0
vcoubard 1146:3fbf341b09dd 9 *
vcoubard 1146:3fbf341b09dd 10 * Unless required by applicable law or agreed to in writing, software
vcoubard 1146:3fbf341b09dd 11 * distributed under the License is distributed on an "AS IS" BASIS,
vcoubard 1146:3fbf341b09dd 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vcoubard 1146:3fbf341b09dd 13 * See the License for the specific language governing permissions and
vcoubard 1146:3fbf341b09dd 14 * limitations under the License.
vcoubard 1146:3fbf341b09dd 15 */
vcoubard 1146:3fbf341b09dd 16 #ifndef MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H
vcoubard 1146:3fbf341b09dd 17 #define MBED_CALLCHAIN_OF_FUNCTION_POINTERS_WITH_CONTEXT_H
vcoubard 1146:3fbf341b09dd 18
vcoubard 1146:3fbf341b09dd 19 #include <string.h>
vcoubard 1146:3fbf341b09dd 20 #include "FunctionPointerWithContext.h"
vcoubard 1146:3fbf341b09dd 21 #include "SafeBool.h"
vcoubard 1146:3fbf341b09dd 22
vcoubard 1146:3fbf341b09dd 23
vcoubard 1146:3fbf341b09dd 24 /** Group one or more functions in an instance of a CallChainOfFunctionPointersWithContext, then call them in
vcoubard 1146:3fbf341b09dd 25 * sequence using CallChainOfFunctionPointersWithContext::call(). Used mostly by the interrupt chaining code,
vcoubard 1146:3fbf341b09dd 26 * but can be used for other purposes.
vcoubard 1146:3fbf341b09dd 27 *
vcoubard 1146:3fbf341b09dd 28 * Example:
vcoubard 1146:3fbf341b09dd 29 * @code
vcoubard 1146:3fbf341b09dd 30 *
vcoubard 1146:3fbf341b09dd 31 * CallChainOfFunctionPointersWithContext<void *> chain;
vcoubard 1146:3fbf341b09dd 32 *
vcoubard 1146:3fbf341b09dd 33 * void first(void *context) {
vcoubard 1146:3fbf341b09dd 34 * printf("'first' function.\n");
vcoubard 1146:3fbf341b09dd 35 * }
vcoubard 1146:3fbf341b09dd 36 *
vcoubard 1146:3fbf341b09dd 37 * void second(void *context) {
vcoubard 1146:3fbf341b09dd 38 * printf("'second' function.\n");
vcoubard 1146:3fbf341b09dd 39 * }
vcoubard 1146:3fbf341b09dd 40 *
vcoubard 1146:3fbf341b09dd 41 * class Test {
vcoubard 1146:3fbf341b09dd 42 * public:
vcoubard 1146:3fbf341b09dd 43 * void f(void *context) {
vcoubard 1146:3fbf341b09dd 44 * printf("A::f (class member).\n");
vcoubard 1146:3fbf341b09dd 45 * }
vcoubard 1146:3fbf341b09dd 46 * };
vcoubard 1146:3fbf341b09dd 47 *
vcoubard 1146:3fbf341b09dd 48 * int main() {
vcoubard 1146:3fbf341b09dd 49 * Test test;
vcoubard 1146:3fbf341b09dd 50 *
vcoubard 1146:3fbf341b09dd 51 * chain.add(second);
vcoubard 1146:3fbf341b09dd 52 * chain.add_front(first);
vcoubard 1146:3fbf341b09dd 53 * chain.add(&test, &Test::f);
vcoubard 1146:3fbf341b09dd 54 * chain.call();
vcoubard 1146:3fbf341b09dd 55 * }
vcoubard 1146:3fbf341b09dd 56 * @endcode
vcoubard 1146:3fbf341b09dd 57 */
vcoubard 1146:3fbf341b09dd 58 template <typename ContextType>
vcoubard 1146:3fbf341b09dd 59 class CallChainOfFunctionPointersWithContext : public SafeBool<CallChainOfFunctionPointersWithContext<ContextType> > {
vcoubard 1146:3fbf341b09dd 60 public:
vcoubard 1147:79a44226e47a 61 /**
vcoubard 1147:79a44226e47a 62 * The type of each callback in the callchain.
vcoubard 1147:79a44226e47a 63 */
vcoubard 1146:3fbf341b09dd 64 typedef FunctionPointerWithContext<ContextType> *pFunctionPointerWithContext_t;
vcoubard 1146:3fbf341b09dd 65
vcoubard 1146:3fbf341b09dd 66 public:
vcoubard 1147:79a44226e47a 67 /**
vcoubard 1147:79a44226e47a 68 * Create an empty chain.
vcoubard 1146:3fbf341b09dd 69 */
vcoubard 1146:3fbf341b09dd 70 CallChainOfFunctionPointersWithContext() : chainHead(NULL) {
vcoubard 1146:3fbf341b09dd 71 /* empty */
vcoubard 1146:3fbf341b09dd 72 }
vcoubard 1146:3fbf341b09dd 73
vcoubard 1146:3fbf341b09dd 74 virtual ~CallChainOfFunctionPointersWithContext() {
vcoubard 1146:3fbf341b09dd 75 clear();
vcoubard 1146:3fbf341b09dd 76 }
vcoubard 1146:3fbf341b09dd 77
vcoubard 1147:79a44226e47a 78 /**
vcoubard 1147:79a44226e47a 79 * Add a function at the front of the chain.
vcoubard 1146:3fbf341b09dd 80 *
vcoubard 1147:79a44226e47a 81 * @param[in] function
vcoubard 1147:79a44226e47a 82 * A pointer to a void function.
vcoubard 1146:3fbf341b09dd 83 *
vcoubard 1147:79a44226e47a 84 * @return The function object created for @p function.
vcoubard 1146:3fbf341b09dd 85 */
vcoubard 1146:3fbf341b09dd 86 pFunctionPointerWithContext_t add(void (*function)(ContextType context)) {
vcoubard 1146:3fbf341b09dd 87 return common_add(new FunctionPointerWithContext<ContextType>(function));
vcoubard 1146:3fbf341b09dd 88 }
vcoubard 1146:3fbf341b09dd 89
vcoubard 1147:79a44226e47a 90 /**
vcoubard 1147:79a44226e47a 91 * Add a function at the front of the chain.
vcoubard 1146:3fbf341b09dd 92 *
vcoubard 1147:79a44226e47a 93 * @param[in] tptr
vcoubard 1147:79a44226e47a 94 * Pointer to the object to call the member function on.
vcoubard 1147:79a44226e47a 95 * @param[in] mptr
vcoubard 1147:79a44226e47a 96 * Pointer to the member function to be called.
vcoubard 1146:3fbf341b09dd 97 *
vcoubard 1147:79a44226e47a 98 * @return The function object created for @p tptr and @p mptr.
vcoubard 1146:3fbf341b09dd 99 */
vcoubard 1146:3fbf341b09dd 100 template<typename T>
vcoubard 1146:3fbf341b09dd 101 pFunctionPointerWithContext_t add(T *tptr, void (T::*mptr)(ContextType context)) {
vcoubard 1146:3fbf341b09dd 102 return common_add(new FunctionPointerWithContext<ContextType>(tptr, mptr));
vcoubard 1146:3fbf341b09dd 103 }
vcoubard 1146:3fbf341b09dd 104
vcoubard 1147:79a44226e47a 105 /**
vcoubard 1147:79a44226e47a 106 * Add a function at the front of the chain.
vcoubard 1146:3fbf341b09dd 107 *
vcoubard 1147:79a44226e47a 108 * @param[in] func
vcoubard 1147:79a44226e47a 109 * The FunctionPointerWithContext to add.
vcoubard 1147:79a44226e47a 110 *
vcoubard 1147:79a44226e47a 111 * @return The function object created for @p func.
vcoubard 1146:3fbf341b09dd 112 */
vcoubard 1146:3fbf341b09dd 113 pFunctionPointerWithContext_t add(const FunctionPointerWithContext<ContextType>& func) {
vcoubard 1146:3fbf341b09dd 114 return common_add(new FunctionPointerWithContext<ContextType>(func));
vcoubard 1146:3fbf341b09dd 115 }
vcoubard 1146:3fbf341b09dd 116
vcoubard 1146:3fbf341b09dd 117 /**
vcoubard 1147:79a44226e47a 118 * Detach a function pointer from a callchain.
vcoubard 1146:3fbf341b09dd 119 *
vcoubard 1147:79a44226e47a 120 * @param[in] toDetach
vcoubard 1147:79a44226e47a 121 * FunctionPointerWithContext to detach from this callchain.
vcoubard 1146:3fbf341b09dd 122 *
vcoubard 1147:79a44226e47a 123 * @return true if a function pointer has been detached and false otherwise.
vcoubard 1146:3fbf341b09dd 124 */
vcoubard 1146:3fbf341b09dd 125 bool detach(const FunctionPointerWithContext<ContextType>& toDetach) {
vcoubard 1146:3fbf341b09dd 126 pFunctionPointerWithContext_t current = chainHead;
vcoubard 1146:3fbf341b09dd 127 pFunctionPointerWithContext_t previous = NULL;
vcoubard 1146:3fbf341b09dd 128
vcoubard 1146:3fbf341b09dd 129 while (current) {
vcoubard 1146:3fbf341b09dd 130 if(*current == toDetach) {
vcoubard 1146:3fbf341b09dd 131 if(previous == NULL) {
vcoubard 1146:3fbf341b09dd 132 if(currentCalled == current) {
vcoubard 1146:3fbf341b09dd 133 currentCalled = NULL;
vcoubard 1146:3fbf341b09dd 134 }
vcoubard 1146:3fbf341b09dd 135 chainHead = current->getNext();
vcoubard 1146:3fbf341b09dd 136 } else {
vcoubard 1146:3fbf341b09dd 137 if(currentCalled == current) {
vcoubard 1146:3fbf341b09dd 138 currentCalled = previous;
vcoubard 1146:3fbf341b09dd 139 }
vcoubard 1146:3fbf341b09dd 140 previous->chainAsNext(current->getNext());
vcoubard 1146:3fbf341b09dd 141 }
vcoubard 1146:3fbf341b09dd 142 delete current;
vcoubard 1146:3fbf341b09dd 143 return true;
vcoubard 1146:3fbf341b09dd 144 }
vcoubard 1146:3fbf341b09dd 145
vcoubard 1146:3fbf341b09dd 146 previous = current;
vcoubard 1146:3fbf341b09dd 147 current = current->getNext();
vcoubard 1146:3fbf341b09dd 148 }
vcoubard 1146:3fbf341b09dd 149
vcoubard 1146:3fbf341b09dd 150 return false;
vcoubard 1146:3fbf341b09dd 151 }
vcoubard 1146:3fbf341b09dd 152
vcoubard 1147:79a44226e47a 153 /**
vcoubard 1147:79a44226e47a 154 * Clear the call chain (remove all functions in the chain).
vcoubard 1146:3fbf341b09dd 155 */
vcoubard 1146:3fbf341b09dd 156 void clear(void) {
vcoubard 1146:3fbf341b09dd 157 pFunctionPointerWithContext_t fptr = chainHead;
vcoubard 1146:3fbf341b09dd 158 while (fptr) {
vcoubard 1146:3fbf341b09dd 159 pFunctionPointerWithContext_t deadPtr = fptr;
vcoubard 1146:3fbf341b09dd 160 fptr = deadPtr->getNext();
vcoubard 1146:3fbf341b09dd 161 delete deadPtr;
vcoubard 1146:3fbf341b09dd 162 }
vcoubard 1146:3fbf341b09dd 163
vcoubard 1146:3fbf341b09dd 164 chainHead = NULL;
vcoubard 1146:3fbf341b09dd 165 }
vcoubard 1146:3fbf341b09dd 166
vcoubard 1147:79a44226e47a 167 /**
vcoubard 1147:79a44226e47a 168 * Check whether the callchain contains any callbacks.
vcoubard 1147:79a44226e47a 169 *
vcoubard 1147:79a44226e47a 170 * @return true if the callchain is not empty and false otherwise.
vcoubard 1147:79a44226e47a 171 */
vcoubard 1146:3fbf341b09dd 172 bool hasCallbacksAttached(void) const {
vcoubard 1146:3fbf341b09dd 173 return (chainHead != NULL);
vcoubard 1146:3fbf341b09dd 174 }
vcoubard 1146:3fbf341b09dd 175
vcoubard 1147:79a44226e47a 176 /**
vcoubard 1147:79a44226e47a 177 * Call all the functions in the chain in sequence.
vcoubard 1146:3fbf341b09dd 178 */
vcoubard 1146:3fbf341b09dd 179 void call(ContextType context) {
vcoubard 1146:3fbf341b09dd 180 ((const CallChainOfFunctionPointersWithContext*) this)->call(context);
vcoubard 1146:3fbf341b09dd 181 }
vcoubard 1146:3fbf341b09dd 182
vcoubard 1146:3fbf341b09dd 183 /**
vcoubard 1147:79a44226e47a 184 * Same as call() above, but const.
vcoubard 1146:3fbf341b09dd 185 */
vcoubard 1146:3fbf341b09dd 186 void call(ContextType context) const {
vcoubard 1146:3fbf341b09dd 187 currentCalled = chainHead;
vcoubard 1146:3fbf341b09dd 188
vcoubard 1146:3fbf341b09dd 189 while(currentCalled) {
vcoubard 1146:3fbf341b09dd 190 currentCalled->call(context);
vcoubard 1146:3fbf341b09dd 191 // if this was the head and the call removed the head
vcoubard 1146:3fbf341b09dd 192 if(currentCalled == NULL) {
vcoubard 1146:3fbf341b09dd 193 currentCalled = chainHead;
vcoubard 1146:3fbf341b09dd 194 } else {
vcoubard 1146:3fbf341b09dd 195 currentCalled = currentCalled->getNext();
vcoubard 1146:3fbf341b09dd 196 }
vcoubard 1146:3fbf341b09dd 197 }
vcoubard 1146:3fbf341b09dd 198 }
vcoubard 1146:3fbf341b09dd 199
vcoubard 1146:3fbf341b09dd 200 /**
vcoubard 1147:79a44226e47a 201 * Same as call(), but with function call operator.
vcoubard 1147:79a44226e47a 202 * @code
vcoubard 1146:3fbf341b09dd 203 *
vcoubard 1146:3fbf341b09dd 204 * void first(bool);
vcoubard 1146:3fbf341b09dd 205 * void second(bool);
vcoubard 1146:3fbf341b09dd 206 *
vcoubard 1146:3fbf341b09dd 207 * CallChainOfFunctionPointerWithContext<bool> foo;
vcoubard 1146:3fbf341b09dd 208 *
vcoubard 1146:3fbf341b09dd 209 * foo.attach(first);
vcoubard 1146:3fbf341b09dd 210 * foo.attach(second);
vcoubard 1146:3fbf341b09dd 211 *
vcoubard 1146:3fbf341b09dd 212 * // call the callchain like a function
vcoubard 1146:3fbf341b09dd 213 * foo(true);
vcoubard 1146:3fbf341b09dd 214 *
vcoubard 1147:79a44226e47a 215 * @endcode
vcoubard 1146:3fbf341b09dd 216 */
vcoubard 1146:3fbf341b09dd 217 void operator()(ContextType context) const {
vcoubard 1146:3fbf341b09dd 218 call(context);
vcoubard 1146:3fbf341b09dd 219 }
vcoubard 1146:3fbf341b09dd 220
vcoubard 1146:3fbf341b09dd 221 /**
vcoubard 1147:79a44226e47a 222 * Bool conversion operation.
vcoubard 1147:79a44226e47a 223 *
vcoubard 1147:79a44226e47a 224 * @return true if the callchain is not empty and false otherwise.
vcoubard 1146:3fbf341b09dd 225 */
vcoubard 1146:3fbf341b09dd 226 bool toBool() const {
vcoubard 1146:3fbf341b09dd 227 return chainHead != NULL;
vcoubard 1146:3fbf341b09dd 228 }
vcoubard 1146:3fbf341b09dd 229
vcoubard 1146:3fbf341b09dd 230 private:
vcoubard 1147:79a44226e47a 231 /**
vcoubard 1147:79a44226e47a 232 * Add a callback to the head of the callchain.
vcoubard 1147:79a44226e47a 233 *
vcoubard 1147:79a44226e47a 234 * @return A pointer to the head of the callchain.
vcoubard 1147:79a44226e47a 235 */
vcoubard 1146:3fbf341b09dd 236 pFunctionPointerWithContext_t common_add(pFunctionPointerWithContext_t pf) {
vcoubard 1146:3fbf341b09dd 237 if (chainHead == NULL) {
vcoubard 1146:3fbf341b09dd 238 chainHead = pf;
vcoubard 1146:3fbf341b09dd 239 } else {
vcoubard 1146:3fbf341b09dd 240 pf->chainAsNext(chainHead);
vcoubard 1146:3fbf341b09dd 241 chainHead = pf;
vcoubard 1146:3fbf341b09dd 242 }
vcoubard 1146:3fbf341b09dd 243
vcoubard 1146:3fbf341b09dd 244 return chainHead;
vcoubard 1146:3fbf341b09dd 245 }
vcoubard 1146:3fbf341b09dd 246
vcoubard 1146:3fbf341b09dd 247 private:
vcoubard 1147:79a44226e47a 248 /**
vcoubard 1147:79a44226e47a 249 * A pointer to the first callback in the callchain or NULL if the callchain is empty.
vcoubard 1147:79a44226e47a 250 */
vcoubard 1146:3fbf341b09dd 251 pFunctionPointerWithContext_t chainHead;
vcoubard 1147:79a44226e47a 252
vcoubard 1147:79a44226e47a 253 /**
vcoubard 1147:79a44226e47a 254 * Iterator during a function call, this has to be mutable because the call function is const.
vcoubard 1147:79a44226e47a 255 *
vcoubard 1147:79a44226e47a 256 * @note Mutable is the correct behaviour here, the iterator never leaks outside the object.
vcoubard 1147:79a44226e47a 257 * so the object can still be seen as logically const even if it is modified.
vcoubard 1147:79a44226e47a 258 */
vcoubard 1146:3fbf341b09dd 259 mutable pFunctionPointerWithContext_t currentCalled;
vcoubard 1146:3fbf341b09dd 260
vcoubard 1146:3fbf341b09dd 261
vcoubard 1146:3fbf341b09dd 262 /* Disallow copy constructor and assignment operators. */
vcoubard 1146:3fbf341b09dd 263 private:
vcoubard 1146:3fbf341b09dd 264 CallChainOfFunctionPointersWithContext(const CallChainOfFunctionPointersWithContext &);
vcoubard 1146:3fbf341b09dd 265 CallChainOfFunctionPointersWithContext & operator = (const CallChainOfFunctionPointersWithContext &);
vcoubard 1146:3fbf341b09dd 266 };
vcoubard 1146:3fbf341b09dd 267
rgrover1 710:b2e1a2660ec2 268 #endif