project

Dependencies:   mbed HTTPClient LM75B mbed-rtos EthernetInterface MMA7660

Committer:
rr387
Date:
Thu Dec 30 15:22:40 2021 +0000
Revision:
3:e68b56ffa127
l

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rr387 3:e68b56ffa127 1 /**
rr387 3:e68b56ffa127 2 * @file FP.h
rr387 3:e68b56ffa127 3 * @brief Core Utility - Templated Function Pointer Class
rr387 3:e68b56ffa127 4 * @author sam grove
rr387 3:e68b56ffa127 5 * @version 1.1
rr387 3:e68b56ffa127 6 * @see http://mbed.org/users/sam_grove/code/FP/
rr387 3:e68b56ffa127 7 *
rr387 3:e68b56ffa127 8 * Copyright (c) 2013
rr387 3:e68b56ffa127 9 *
rr387 3:e68b56ffa127 10 * Licensed under the Apache License, Version 2.0 (the "License");
rr387 3:e68b56ffa127 11 * you may not use this file except in compliance with the License.
rr387 3:e68b56ffa127 12 * You may obtain a copy of the License at
rr387 3:e68b56ffa127 13 *
rr387 3:e68b56ffa127 14 * http://www.apache.org/licenses/LICENSE-2.0
rr387 3:e68b56ffa127 15 *
rr387 3:e68b56ffa127 16 * Unless required by applicable law or agreed to in writing, software
rr387 3:e68b56ffa127 17 * distributed under the License is distributed on an "AS IS" BASIS,
rr387 3:e68b56ffa127 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rr387 3:e68b56ffa127 19 * See the License for the specific language governing permissions and
rr387 3:e68b56ffa127 20 * limitations under the License.
rr387 3:e68b56ffa127 21 */
rr387 3:e68b56ffa127 22
rr387 3:e68b56ffa127 23 #ifndef FP_H
rr387 3:e68b56ffa127 24 #define FP_H
rr387 3:e68b56ffa127 25
rr387 3:e68b56ffa127 26 /** Example using the FP Class with global functions
rr387 3:e68b56ffa127 27 * @code
rr387 3:e68b56ffa127 28 * #include "mbed.h"
rr387 3:e68b56ffa127 29 * #include "FP.h"
rr387 3:e68b56ffa127 30 *
rr387 3:e68b56ffa127 31 * FP<void,bool>fp;
rr387 3:e68b56ffa127 32 * DigitalOut myled(LED1);
rr387 3:e68b56ffa127 33 *
rr387 3:e68b56ffa127 34 * void handler(bool value)
rr387 3:e68b56ffa127 35 * {
rr387 3:e68b56ffa127 36 * myled = value;
rr387 3:e68b56ffa127 37 * return;
rr387 3:e68b56ffa127 38 * }
rr387 3:e68b56ffa127 39 *
rr387 3:e68b56ffa127 40 * int main()
rr387 3:e68b56ffa127 41 * {
rr387 3:e68b56ffa127 42 * fp.attach(&handler);
rr387 3:e68b56ffa127 43 *
rr387 3:e68b56ffa127 44 * while(1)
rr387 3:e68b56ffa127 45 * {
rr387 3:e68b56ffa127 46 * fp(1);
rr387 3:e68b56ffa127 47 * wait(0.2);
rr387 3:e68b56ffa127 48 * fp(0);
rr387 3:e68b56ffa127 49 * wait(0.2);
rr387 3:e68b56ffa127 50 * }
rr387 3:e68b56ffa127 51 * }
rr387 3:e68b56ffa127 52 * @endcode
rr387 3:e68b56ffa127 53 */
rr387 3:e68b56ffa127 54
rr387 3:e68b56ffa127 55 /** Example using the FP Class with different class member functions
rr387 3:e68b56ffa127 56 * @code
rr387 3:e68b56ffa127 57 * #include "mbed.h"
rr387 3:e68b56ffa127 58 * #include "FP.h"
rr387 3:e68b56ffa127 59 *
rr387 3:e68b56ffa127 60 * FP<void,bool>fp;
rr387 3:e68b56ffa127 61 * DigitalOut myled(LED4);
rr387 3:e68b56ffa127 62 *
rr387 3:e68b56ffa127 63 * class Wrapper
rr387 3:e68b56ffa127 64 * {
rr387 3:e68b56ffa127 65 * public:
rr387 3:e68b56ffa127 66 * Wrapper(){}
rr387 3:e68b56ffa127 67 *
rr387 3:e68b56ffa127 68 * void handler(bool value)
rr387 3:e68b56ffa127 69 * {
rr387 3:e68b56ffa127 70 * myled = value;
rr387 3:e68b56ffa127 71 * return;
rr387 3:e68b56ffa127 72 * }
rr387 3:e68b56ffa127 73 * };
rr387 3:e68b56ffa127 74 *
rr387 3:e68b56ffa127 75 * int main()
rr387 3:e68b56ffa127 76 * {
rr387 3:e68b56ffa127 77 * Wrapper wrapped;
rr387 3:e68b56ffa127 78 * fp.attach(&wrapped, &Wrapper::handler);
rr387 3:e68b56ffa127 79 *
rr387 3:e68b56ffa127 80 * while(1)
rr387 3:e68b56ffa127 81 * {
rr387 3:e68b56ffa127 82 * fp(1);
rr387 3:e68b56ffa127 83 * wait(0.2);
rr387 3:e68b56ffa127 84 * fp(0);
rr387 3:e68b56ffa127 85 * wait(0.2);
rr387 3:e68b56ffa127 86 * }
rr387 3:e68b56ffa127 87 * }
rr387 3:e68b56ffa127 88 * @endcode
rr387 3:e68b56ffa127 89 */
rr387 3:e68b56ffa127 90
rr387 3:e68b56ffa127 91 /** Example using the FP Class with member FP and member function
rr387 3:e68b56ffa127 92 * @code
rr387 3:e68b56ffa127 93 * #include "mbed.h"
rr387 3:e68b56ffa127 94 * #include "FP.h"
rr387 3:e68b56ffa127 95 *
rr387 3:e68b56ffa127 96 * DigitalOut myled(LED2);
rr387 3:e68b56ffa127 97 *
rr387 3:e68b56ffa127 98 * class Wrapper
rr387 3:e68b56ffa127 99 * {
rr387 3:e68b56ffa127 100 * public:
rr387 3:e68b56ffa127 101 * Wrapper()
rr387 3:e68b56ffa127 102 * {
rr387 3:e68b56ffa127 103 * fp.attach(this, &Wrapper::handler);
rr387 3:e68b56ffa127 104 * }
rr387 3:e68b56ffa127 105 *
rr387 3:e68b56ffa127 106 * void handler(bool value)
rr387 3:e68b56ffa127 107 * {
rr387 3:e68b56ffa127 108 * myled = value;
rr387 3:e68b56ffa127 109 * return;
rr387 3:e68b56ffa127 110 * }
rr387 3:e68b56ffa127 111 *
rr387 3:e68b56ffa127 112 * FP<void,bool>fp;
rr387 3:e68b56ffa127 113 * };
rr387 3:e68b56ffa127 114 *
rr387 3:e68b56ffa127 115 * int main()
rr387 3:e68b56ffa127 116 * {
rr387 3:e68b56ffa127 117 * Wrapper wrapped;
rr387 3:e68b56ffa127 118 *
rr387 3:e68b56ffa127 119 * while(1)
rr387 3:e68b56ffa127 120 * {
rr387 3:e68b56ffa127 121 * wrapped.fp(1);
rr387 3:e68b56ffa127 122 * wait(0.2);
rr387 3:e68b56ffa127 123 * wrapped.fp(0);
rr387 3:e68b56ffa127 124 * wait(0.2);
rr387 3:e68b56ffa127 125 * }
rr387 3:e68b56ffa127 126 * }
rr387 3:e68b56ffa127 127 * @endcode
rr387 3:e68b56ffa127 128 */
rr387 3:e68b56ffa127 129
rr387 3:e68b56ffa127 130 /**
rr387 3:e68b56ffa127 131 * @class FP
rr387 3:e68b56ffa127 132 * @brief API for managing Function Pointers
rr387 3:e68b56ffa127 133 */
rr387 3:e68b56ffa127 134 template<class retT, class argT>
rr387 3:e68b56ffa127 135 class FP
rr387 3:e68b56ffa127 136 {
rr387 3:e68b56ffa127 137 public:
rr387 3:e68b56ffa127 138 /** Create the FP object - only one callback can be attached to the object, that is
rr387 3:e68b56ffa127 139 * a member function or a global function, not both at the same time
rr387 3:e68b56ffa127 140 */
rr387 3:e68b56ffa127 141 FP()
rr387 3:e68b56ffa127 142 {
rr387 3:e68b56ffa127 143 obj_callback = 0;
rr387 3:e68b56ffa127 144 c_callback = 0;
rr387 3:e68b56ffa127 145 }
rr387 3:e68b56ffa127 146
rr387 3:e68b56ffa127 147 /** Add a callback function to the object
rr387 3:e68b56ffa127 148 * @param item - Address of the initialized object
rr387 3:e68b56ffa127 149 * @param member - Address of the member function (dont forget the scope that the function is defined in)
rr387 3:e68b56ffa127 150 */
rr387 3:e68b56ffa127 151 template<class T>
rr387 3:e68b56ffa127 152 void attach(T *item, retT (T::*method)(argT))
rr387 3:e68b56ffa127 153 {
rr387 3:e68b56ffa127 154 obj_callback = (FPtrDummy *)(item);
rr387 3:e68b56ffa127 155 method_callback = (retT (FPtrDummy::*)(argT))(method);
rr387 3:e68b56ffa127 156 return;
rr387 3:e68b56ffa127 157 }
rr387 3:e68b56ffa127 158
rr387 3:e68b56ffa127 159 /** Add a callback function to the object
rr387 3:e68b56ffa127 160 * @param function - The address of a globally defined function
rr387 3:e68b56ffa127 161 */
rr387 3:e68b56ffa127 162 void attach(retT (*function)(argT))
rr387 3:e68b56ffa127 163 {
rr387 3:e68b56ffa127 164 c_callback = function;
rr387 3:e68b56ffa127 165 }
rr387 3:e68b56ffa127 166
rr387 3:e68b56ffa127 167 /** Invoke the function attached to the class
rr387 3:e68b56ffa127 168 * @param arg - An argument that is passed into the function handler that is called
rr387 3:e68b56ffa127 169 * @return The return from the function hanlder called by this class
rr387 3:e68b56ffa127 170 */
rr387 3:e68b56ffa127 171 retT operator()(argT arg) const
rr387 3:e68b56ffa127 172 {
rr387 3:e68b56ffa127 173 if( 0 != c_callback ) {
rr387 3:e68b56ffa127 174 return obj_callback ? (obj_callback->*method_callback)(arg) : (*c_callback)(arg);
rr387 3:e68b56ffa127 175 }
rr387 3:e68b56ffa127 176 return (retT)0;
rr387 3:e68b56ffa127 177 }
rr387 3:e68b56ffa127 178
rr387 3:e68b56ffa127 179 /** Determine if an callback is currently hooked
rr387 3:e68b56ffa127 180 * @return 1 if a method is hooked, 0 otherwise
rr387 3:e68b56ffa127 181 */
rr387 3:e68b56ffa127 182 bool attached()
rr387 3:e68b56ffa127 183 {
rr387 3:e68b56ffa127 184 return obj_callback || c_callback;
rr387 3:e68b56ffa127 185 }
rr387 3:e68b56ffa127 186
rr387 3:e68b56ffa127 187 /** Release a function from the callback hook
rr387 3:e68b56ffa127 188 */
rr387 3:e68b56ffa127 189 void detach()
rr387 3:e68b56ffa127 190 {
rr387 3:e68b56ffa127 191 obj_callback = 0;
rr387 3:e68b56ffa127 192 c_callback = 0;
rr387 3:e68b56ffa127 193 }
rr387 3:e68b56ffa127 194
rr387 3:e68b56ffa127 195 private:
rr387 3:e68b56ffa127 196
rr387 3:e68b56ffa127 197 // empty type used for casting
rr387 3:e68b56ffa127 198 class FPtrDummy;
rr387 3:e68b56ffa127 199
rr387 3:e68b56ffa127 200 FPtrDummy *obj_callback;
rr387 3:e68b56ffa127 201
rr387 3:e68b56ffa127 202 /**
rr387 3:e68b56ffa127 203 * @union Funciton
rr387 3:e68b56ffa127 204 * @brief Member or global callback function
rr387 3:e68b56ffa127 205 */
rr387 3:e68b56ffa127 206 union {
rr387 3:e68b56ffa127 207 retT (*c_callback)(argT); /*!< Footprint for a global function */
rr387 3:e68b56ffa127 208 retT (FPtrDummy::*method_callback)(argT); /*!< Footprint for a member function */
rr387 3:e68b56ffa127 209 };
rr387 3:e68b56ffa127 210 };
rr387 3:e68b56ffa127 211
rr387 3:e68b56ffa127 212 #endif
rr387 3:e68b56ffa127 213