Andrew Reed / Mbed OS CITY1082-i2c_master_wifi_mqtt
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FP.h Source File

FP.h

00001 /*******************************************************************************
00002  * Copyright (c) 2013, 2014 
00003  *
00004  * All rights reserved. This program and the accompanying materials
00005  * are made available under the terms of the Eclipse Public License v1.0
00006  * and Eclipse Distribution License v1.0 which accompany this distribution.
00007  *
00008  * The Eclipse Public License is available at
00009  *    http://www.eclipse.org/legal/epl-v10.html
00010  * and the Eclipse Distribution License is available at
00011  *   http://www.eclipse.org/org/documents/edl-v10.php.
00012  *
00013  * Contributors:
00014  *    Sam Grove - initial API and implementation and/or initial documentation
00015  *    Ian Craggs - added attached and detached member functions
00016  *    Sam Grove - removed need for FP.cpp
00017  *******************************************************************************/
00018 
00019 #ifndef FP_H
00020 #define FP_H
00021 
00022 /** Example using the FP Class with global functions
00023  * @code
00024  *  #include "mbed.h"
00025  *  #include "FP.h"
00026  *
00027  *  FP<void,bool>fp;
00028  *  DigitalOut myled(LED1);
00029  *
00030  *  void handler(bool value)
00031  *  {
00032  *      myled = value;
00033  *      return;
00034  *  }
00035  *
00036  *  int main()
00037  *  {
00038  *      fp.attach(&handler);
00039  *
00040  *      while(1)
00041  *      {
00042  *          fp(1);
00043  *          wait(0.2);
00044  *          fp(0);
00045  *          wait(0.2);
00046  *      }
00047  *  }
00048  * @endcode
00049  */
00050 
00051 /** Example using the FP Class with different class member functions
00052  * @code
00053  *  #include "mbed.h"
00054  *  #include "FP.h"
00055  *
00056  *  FP<void,bool>fp;
00057  *  DigitalOut myled(LED4);
00058  *
00059  *  class Wrapper
00060  *  {
00061  *  public:
00062  *      Wrapper(){}
00063  *
00064  *      void handler(bool value)
00065  *      {
00066  *          myled = value;
00067  *          return;
00068  *      }
00069  *  };
00070  *
00071  *  int main()
00072  *  {
00073  *      Wrapper wrapped;
00074  *      fp.attach(&wrapped, &Wrapper::handler);
00075  *
00076  *      while(1)
00077  *      {
00078  *          fp(1);
00079  *          wait(0.2);
00080  *          fp(0);
00081  *          wait(0.2);
00082  *      }
00083  *  }
00084  * @endcode
00085  */
00086 
00087 /** Example using the FP Class with member FP and member function
00088 * @code
00089 *  #include "mbed.h"
00090 *  #include "FP.h"
00091 *
00092 *  DigitalOut myled(LED2);
00093 *
00094 *  class Wrapper
00095 *  {
00096 *  public:
00097 *      Wrapper()
00098 *      {
00099 *          fp.attach(this, &Wrapper::handler);
00100 *      }
00101 *
00102 *      void handler(bool value)
00103 *      {
00104 *          myled = value;
00105 *          return;
00106 *      }
00107 *
00108 *      FP<void,bool>fp;
00109 *  };
00110 *
00111 *  int main()
00112 *  {
00113 *      Wrapper wrapped;
00114 *
00115 *      while(1)
00116 *      {
00117 *          wrapped.fp(1);
00118 *          wait(0.2);
00119 *          wrapped.fp(0);
00120 *          wait(0.2);
00121 *      }
00122 *  }
00123 * @endcode
00124 */
00125 
00126 /**
00127  *  @class FP
00128  *  @brief API for managing Function Pointers
00129  */
00130 template<class retT, class argT>
00131 class FP
00132 {
00133 public:
00134     /** Create the FP object - only one callback can be attached to the object, that is
00135      *  a member function or a global function, not both at the same time
00136      */
00137     FP()
00138     {
00139         obj_callback = 0;
00140         c_callback  = 0;
00141     }
00142 
00143     /** Add a callback function to the object
00144      *  @param item - Address of the initialized object
00145      *  @param member - Address of the member function (dont forget the scope that the function is defined in)
00146      */
00147     template<class T>
00148     void attach(T *item, retT (T::*method)(argT))
00149     {
00150         obj_callback = (FPtrDummy *)(item);
00151         method_callback  = (retT (FPtrDummy::*)(argT))(method);
00152         return;
00153     }
00154 
00155     /** Add a callback function to the object
00156      *  @param function - The address of a globally defined function
00157      */
00158     void attach(retT (*function)(argT))
00159     {
00160         c_callback  = function;
00161     }
00162 
00163     /** Invoke the function attached to the class
00164      *  @param arg - An argument that is passed into the function handler that is called
00165      *  @return The return from the function hanlder called by this class
00166      */
00167     retT operator()(argT arg) const
00168     {
00169         if( 0 != c_callback  ) {
00170             return obj_callback ? (obj_callback->*method_callback )(arg) : (*c_callback)(arg);
00171         }
00172         return (retT)0;
00173     }
00174 
00175     /** Determine if an callback is currently hooked
00176      *  @return 1 if a method is hooked, 0 otherwise
00177      */
00178     bool attached()
00179     {
00180         return obj_callback || c_callback ;
00181     }
00182 
00183     /** Release a function from the callback hook
00184      */
00185     void detach()
00186     {
00187         obj_callback = 0;
00188         c_callback  = 0;
00189     }
00190 
00191 private:
00192 
00193     // empty type used for casting
00194     class FPtrDummy;
00195 
00196     FPtrDummy *obj_callback;
00197 
00198     /**
00199      *  @union Funciton
00200      *  @brief Member or global callback function
00201      */
00202     union {
00203         retT (*c_callback )(argT);                   /*!< Footprint for a global function */
00204         retT (FPtrDummy::*method_callback )(argT);   /*!< Footprint for a member function */
00205     };
00206 };
00207 
00208 #endif