Holla back

Fork of BLE_API by Bluetooth Low Energy

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers CallChainOfFunctionPointersWithContext.h Source File

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 
00022 namespace mbed {
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  * #include "mbed.h"
00031  *
00032  * CallChainOfFunctionPointersWithContext<void *> chain;
00033  *
00034  * void first(void *context) {
00035  *     printf("'first' function.\n");
00036  * }
00037  *
00038  * void second(void *context) {
00039  *     printf("'second' function.\n");
00040  * }
00041  *
00042  * class Test {
00043  * public:
00044  *     void f(void *context) {
00045  *         printf("A::f (class member).\n");
00046  *     }
00047  * };
00048  *
00049  * int main() {
00050  *     Test test;
00051  *
00052  *     chain.add(second);
00053  *     chain.add_front(first);
00054  *     chain.add(&test, &Test::f);
00055  *     chain.call();
00056  * }
00057  * @endcode
00058  */
00059 
00060 template <typename ContextType>
00061 class CallChainOfFunctionPointersWithContext {
00062 public:
00063     typedef FunctionPointerWithContext<ContextType>* pFunctionPointerWithContext_t;
00064 
00065 public:
00066     /** Create an empty chain
00067      *
00068      *  @param size (optional) Initial size of the chain
00069      */
00070     CallChainOfFunctionPointersWithContext() : chainHead(NULL) {
00071         /* empty */
00072     }
00073 
00074     virtual ~CallChainOfFunctionPointersWithContext() {
00075         clear();
00076     }
00077 
00078     /** Add a function at the front of the chain
00079      *
00080      *  @param function A pointer to a void function
00081      *
00082      *  @returns
00083      *  The function object created for 'function'
00084      */
00085     pFunctionPointerWithContext_t add(void (*function)(ContextType context)) {
00086         return common_add(new FunctionPointerWithContext<ContextType>(function));
00087     }
00088 
00089     /** Add a function at the front of the chain
00090      *
00091      *  @param tptr pointer to the object to call the member function on
00092      *  @param mptr pointer to the member function to be called
00093      *
00094      *  @returns
00095      *  The function object created for 'tptr' and 'mptr'
00096      */
00097     template<typename T>
00098     pFunctionPointerWithContext_t add(T *tptr, void (T::*mptr)(ContextType context)) {
00099         return common_add(new FunctionPointerWithContext<ContextType>(tptr, mptr));
00100     }
00101 
00102     /** Clear the call chain (remove all functions in the chain).
00103      */
00104     void clear(void) {
00105         pFunctionPointerWithContext_t fptr = chainHead;
00106         while (fptr) {
00107             pFunctionPointerWithContext_t deadPtr = fptr;
00108             fptr = deadPtr->getNext();
00109             delete deadPtr;
00110         }
00111 
00112         chainHead = NULL;
00113     }
00114 
00115     bool hasCallbacksAttached(void) const {
00116         return (chainHead != NULL);
00117     }
00118 
00119     /** Call all the functions in the chain in sequence
00120      * @Note: the stack frames of all the callbacks within the chained
00121      *        FunctionPointers will stack up. Hopefully there won't be too many
00122      *        chained FunctionPointers.
00123      */
00124     void call(ContextType context) {
00125         if (chainHead)
00126             chainHead->call(context);
00127     }
00128 
00129 private:
00130     pFunctionPointerWithContext_t common_add(pFunctionPointerWithContext_t pf) {
00131         if (chainHead == NULL) {
00132             chainHead = pf;
00133         } else {
00134             pf->chainAsNext(chainHead);
00135             chainHead = pf;
00136         }
00137 
00138         return chainHead;
00139     }
00140 
00141 private:
00142     pFunctionPointerWithContext_t chainHead;
00143 
00144     /* disallow copy constructor and assignment operators */
00145 private:
00146     CallChainOfFunctionPointersWithContext(const CallChainOfFunctionPointersWithContext &);
00147     CallChainOfFunctionPointersWithContext & operator = (const CallChainOfFunctionPointersWithContext &);
00148 };
00149 
00150 } // namespace mbed
00151 
00152 #endif
00153