The Cayenne MQTT mbed Library provides functions to easily connect to the Cayenne IoT project builder.

Dependents:   Cayenne-ESP8266Interface Cayenne-WIZnet_Library Cayenne-WIZnetInterface Cayenne-X-NUCLEO-IDW01M1 ... more

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