Templated function pointer class. Common utility that other classes are built on / with

Dependents:   Waldo_Embed_V2 MQTT MQTTSN MQTT ... more

Good resource about declaring templated types for the linker

Basic Use

#include "mbed.h"
#include "FP.h"
  
FP<void,bool>fp;
DigitalOut myled(LED1);
  
void handler(bool value)
{
    myled = value;
    return;
}
  
int main()
{
    fp.attach(&handler);
      
    while(1) 
    {
        fp(1);
        wait(0.2);
        fp(0);
        wait(0.2);
    }
}

Example using the FP Class with different class member functions

#include "mbed.h"
#include "FP.h"
  
FP<void,bool>fp;
DigitalOut myled(LED4);
  
class Wrapper
{
public:
    Wrapper(){}
  
    void handler(bool value)
    {
        myled = value;
        return;
    }
};
  
int main()
{
    Wrapper wrapped;
    fp.attach(&wrapped, &Wrapper::handler);
    
    while(1) 
    {
        fp(1);
        wait(0.2);
        fp(0);
        wait(0.2);
    }
}

Example using the FP Class with member FP and member function

#include "mbed.h"
#include "FP.h"
  
DigitalOut myled(LED2);
  
class Wrapper
{
public:
    Wrapper()
    {
        fp.attach(this, &Wrapper::handler);
    }
  
    void handler(bool value)
    {
        myled = value;
        return;
    }
      
    FP<void,bool>fp;
};
  
int main()
{
    Wrapper wrapped;
      
    while(1) 
    {
        wrapped.fp(1);
        wait(0.2);
        wrapped.fp(0);
        wait(0.2);
    }
}
Revision:
4:3c62ba1807ac
Parent:
3:e0f19cdaa46e
--- a/FP.h	Sun Apr 13 22:31:44 2014 +0000
+++ b/FP.h	Wed Jul 30 19:10:31 2014 +0000
@@ -2,8 +2,8 @@
  * @file    FP.h
  * @brief   Core Utility - Templated Function Pointer Class
  * @author  sam grove
- * @version 1.0
- * @see     
+ * @version 1.1
+ * @see     http://mbed.org/users/sam_grove/code/FP/
  *
  * Copyright (c) 2013
  *
@@ -27,21 +27,57 @@
  * @code
  *  #include "mbed.h"
  *  #include "FP.h"
- *  
+ *
  *  FP<void,bool>fp;
  *  DigitalOut myled(LED1);
- *  
+ *
  *  void handler(bool value)
  *  {
  *      myled = value;
  *      return;
  *  }
- *  
+ *
  *  int main()
  *  {
  *      fp.attach(&handler);
- *      
- *      while(1) 
+ *
+ *      while(1)
+ *      {
+ *          fp(1);
+ *          wait(0.2);
+ *          fp(0);
+ *          wait(0.2);
+ *      }
+ *  }
+ * @endcode
+ */
+
+/** Example using the FP Class with different class member functions
+ * @code
+ *  #include "mbed.h"
+ *  #include "FP.h"
+ *
+ *  FP<void,bool>fp;
+ *  DigitalOut myled(LED4);
+ *
+ *  class Wrapper
+ *  {
+ *  public:
+ *      Wrapper(){}
+ *
+ *      void handler(bool value)
+ *      {
+ *          myled = value;
+ *          return;
+ *      }
+ *  };
+ *
+ *  int main()
+ *  {
+ *      Wrapper wrapped;
+ *      fp.attach(&wrapped, &Wrapper::handler);
+ *
+ *      while(1)
  *      {
  *          fp(1);
  *          wait(0.2);
@@ -51,96 +87,65 @@
  *  }
  * @endcode
  */
- 
-/** Example using the FP Class with different class member functions
- * @code
- *  #include "mbed.h"
- *  #include "FP.h"
- *  
- *  FP<void,bool>fp;
- *  DigitalOut myled(LED4);
- *  
- *  class Wrapper
- *  {
- *  public:
- *      Wrapper(){}
- *  
- *      void handler(bool value)
- *      {
- *          myled = value;
- *          return;
- *      }
- *  };
- *  
- *  int main()
- *  {
- *      Wrapper wrapped;
- *      fp.attach(&wrapped, &Wrapper::handler);
- *      
- *      while(1) 
- *      {
- *          fp(1);
- *          wait(0.2);
- *          fp(0);
- *          wait(0.2);
- *      }
- *  }
- * @endcode
- */
- 
- /** Example using the FP Class with member FP and member function
- * @code
- *  #include "mbed.h"
- *  #include "FP.h"
- *  
- *  DigitalOut myled(LED2);
- *  
- *  class Wrapper
- *  {
- *  public:
- *      Wrapper()
- *      {
- *          fp.attach(this, &Wrapper::handler);
- *      }
- *  
- *      void handler(bool value)
- *      {
- *          myled = value;
- *          return;
- *      }
- *      
- *      FP<void,bool>fp;
- *  };
- *  
- *  int main()
- *  {
- *      Wrapper wrapped;
- *      
- *      while(1) 
- *      {
- *          wrapped.fp(1);
- *          wait(0.2);
- *          wrapped.fp(0);
- *          wait(0.2);
- *      }
- *  }
- * @endcode
- */
+
+/** Example using the FP Class with member FP and member function
+* @code
+*  #include "mbed.h"
+*  #include "FP.h"
+*
+*  DigitalOut myled(LED2);
+*
+*  class Wrapper
+*  {
+*  public:
+*      Wrapper()
+*      {
+*          fp.attach(this, &Wrapper::handler);
+*      }
+*
+*      void handler(bool value)
+*      {
+*          myled = value;
+*          return;
+*      }
+*
+*      FP<void,bool>fp;
+*  };
+*
+*  int main()
+*  {
+*      Wrapper wrapped;
+*
+*      while(1)
+*      {
+*          wrapped.fp(1);
+*          wait(0.2);
+*          wrapped.fp(0);
+*          wait(0.2);
+*      }
+*  }
+* @endcode
+*/
 
 /**
  *  @class FP
- *  @brief API abstraction for a Function Pointers
- */ 
+ *  @brief API for managing Function Pointers
+ */
 template<class retT, class argT>
 class FP
 {
 public:
-    /** Create the FP object
-     */ 
-    FP();
+    /** Create the FP object - only one callback can be attached to the object, that is
+     *  a member function or a global function, not both at the same time
+     */
+    FP()
+    {
+        obj_callback = 0;
+        c_callback = 0;
+    }
 
-    /** Add a callback function to the class
-     *  @param item - Address of the initialized class
+    /** Add a callback function to the object
+     *  @param item - Address of the initialized object
      *  @param member - Address of the member function (dont forget the scope that the function is defined in)
      */
     template<class T>
@@ -151,34 +156,54 @@
         return;
     }
 
-    /** Add a callback function to the class
+    /** Add a callback function to the object
      *  @param function - The address of a globally defined function
      */
-    void attach(retT (*function)(argT));
-    
+    void attach(retT (*function)(argT))
+    {
+        c_callback = function;
+    }
+
     /** Invoke the function attached to the class
      *  @param arg - An argument that is passed into the function handler that is called
      *  @return The return from the function hanlder called by this class
      */
-    retT operator()(argT arg) const;
-    
-    bool attached();
-    
-    void detach();
+    retT operator()(argT arg) const
+    {
+        if( 0 != c_callback ) {
+            return obj_callback ? (obj_callback->*method_callback)(arg) : (*c_callback)(arg);
+        }
+        return (retT)0;
+    }
+
+    /** Determine if an callback is currently hooked
+     *  @return 1 if a method is hooked, 0 otherwise
+     */
+    bool attached()
+    {
+        return obj_callback || c_callback;
+    }
+
+    /** Release a function from the callback hook
+     */
+    void detach()
+    {
+        obj_callback = 0;
+        c_callback = 0;
+    }
 
 private:
-    
+
     // empty type used for casting
     class FPtrDummy;
-    
+
     FPtrDummy *obj_callback;
-    
+
     /**
      *  @union Funciton
      *  @brief Member or global callback function
-     */ 
-    union
-    {
+     */
+    union {
         retT (*c_callback)(argT);                   /*!< Footprint for a global function */
         retT (FPtrDummy::*method_callback)(argT);   /*!< Footprint for a member function */
     };