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);
    }
}
Committer:
sam_grove
Date:
Wed Jul 30 19:10:31 2014 +0000
Revision:
4:3c62ba1807ac
Parent:
3:e0f19cdaa46e
Moved all implementations to FP.h to not pre-define all templated data types for the linker

Who changed what in which revision?

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