1 /******************************************************************************* 2 * Copyright (c) 2013, 2014 3 * 4 * All rights reserved. This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License v1.0 6 * and Eclipse Distribution License v1.0 which accompany this distribution. 7 * 8 * The Eclipse Public License is available at 9 * http://www.eclipse.org/legal/epl-v10.html 10 * and the Eclipse Distribution License is available at 11 * http://www.eclipse.org/org/documents/edl-v10.php. 12 * 13 * Contributors: 14 * Sam Grove - initial API and implementation and/or initial documentation 15 * Ian Craggs - added attached and detached member functions 16 * Sam Grove - removed need for FP.cpp 17 *******************************************************************************/ 18 19 #ifndef FP_H 20 #define FP_H 21 22 /** Example using the FP Class with global functions 23 * @code 24 * #include "mbed.h" 25 * #include "FP.h" 26 * 27 * FP<void,bool>fp; 28 * DigitalOut myled(LED1); 29 * 30 * void handler(bool value) 31 * { 32 * myled = value; 33 * return; 34 * } 35 * 36 * int main() 37 * { 38 * fp.attach(&handler); 39 * 40 * while(1) 41 * { 42 * fp(1); 43 * wait(0.2); 44 * fp(0); 45 * wait(0.2); 46 * } 47 * } 48 * @endcode 49 */ 50 51 /** Example using the FP Class with different class member functions 52 * @code 53 * #include "mbed.h" 54 * #include "FP.h" 55 * 56 * FP<void,bool>fp; 57 * DigitalOut myled(LED4); 58 * 59 * class Wrapper 60 * { 61 * public: 62 * Wrapper(){} 63 * 64 * void handler(bool value) 65 * { 66 * myled = value; 67 * return; 68 * } 69 * }; 70 * 71 * int main() 72 * { 73 * Wrapper wrapped; 74 * fp.attach(&wrapped, &Wrapper::handler); 75 * 76 * while(1) 77 * { 78 * fp(1); 79 * wait(0.2); 80 * fp(0); 81 * wait(0.2); 82 * } 83 * } 84 * @endcode 85 */ 86 87 /** Example using the FP Class with member FP and member function 88 * @code 89 * #include "mbed.h" 90 * #include "FP.h" 91 * 92 * DigitalOut myled(LED2); 93 * 94 * class Wrapper 95 * { 96 * public: 97 * Wrapper() 98 * { 99 * fp.attach(this, &Wrapper::handler); 100 * } 101 * 102 * void handler(bool value) 103 * { 104 * myled = value; 105 * return; 106 * } 107 * 108 * FP<void,bool>fp; 109 * }; 110 * 111 * int main() 112 * { 113 * Wrapper wrapped; 114 * 115 * while(1) 116 * { 117 * wrapped.fp(1); 118 * wait(0.2); 119 * wrapped.fp(0); 120 * wait(0.2); 121 * } 122 * } 123 * @endcode 124 */ 125 126 /** 127 * @class FP 128 * @brief API for managing Function Pointers 129 */ 130 template<class retT, class argT> 131 class FP 132 { 133 public: 134 /** Create the FP object - only one callback can be attached to the object, that is 135 * a member function or a global function, not both at the same time 136 */ FP()137 FP() 138 { 139 obj_callback = 0; 140 c_callback = 0; 141 } 142 143 /** Add a callback function to the object 144 * @param item - Address of the initialized object 145 * @param member - Address of the member function (dont forget the scope that the function is defined in) 146 */ 147 template<class T> attach(T * item,retT (T::* method)(argT))148 void attach(T *item, retT (T::*method)(argT)) 149 { 150 obj_callback = (FPtrDummy *)(item); 151 method_callback = (retT (FPtrDummy::*)(argT))(method); 152 return; 153 } 154 155 /** Add a callback function to the object 156 * @param function - The address of a globally defined function 157 */ attach(retT (* function)(argT))158 void attach(retT (*function)(argT)) 159 { 160 c_callback = function; 161 } 162 163 /** Invoke the function attached to the class 164 * @param arg - An argument that is passed into the function handler that is called 165 * @return The return from the function hanlder called by this class 166 */ operator()167 retT operator()(argT arg) const 168 { 169 if( 0 != c_callback ) { 170 return obj_callback ? (obj_callback->*method_callback)(arg) : (*c_callback)(arg); 171 } 172 return (retT)0; 173 } 174 175 /** Determine if an callback is currently hooked 176 * @return 1 if a method is hooked, 0 otherwise 177 */ attached()178 bool attached() 179 { 180 return obj_callback || c_callback; 181 } 182 183 /** Release a function from the callback hook 184 */ detach()185 void detach() 186 { 187 obj_callback = 0; 188 c_callback = 0; 189 } 190 191 private: 192 193 // empty type used for casting 194 class FPtrDummy; 195 196 FPtrDummy *obj_callback; 197 198 /** 199 * @union Funciton 200 * @brief Member or global callback function 201 */ 202 union { 203 retT (*c_callback)(argT); /*!< Footprint for a global function */ 204 retT (FPtrDummy::*method_callback)(argT); /*!< Footprint for a member function */ 205 }; 206 }; 207 208 #endif 209