• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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