AirsoftTimer software based on mbed

Dependencies:   mbed TextLCD keypad

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FPointer.h Source File

FPointer.h

00001 /*
00002     Copyright (c) 2011 Andy Kirkham
00003  
00004     Permission is hereby granted, free of charge, to any person obtaining a copy
00005     of this software and associated documentation files (the "Software"), to deal
00006     in the Software without restriction, including without limitation the rights
00007     to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00008     copies of the Software, and to permit persons to whom the Software is
00009     furnished to do so, subject to the following conditions:
00010  
00011     The above copyright notice and this permission notice shall be included in
00012     all copies or substantial portions of the Software.
00013  
00014     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00015     IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00016     FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00017     AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
00018     LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
00019     OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00020     THE SOFTWARE.
00021 */
00022 
00023 #ifndef AJK_FPOINTER_H
00024 #define AJK_FPOINTER_H
00025 
00026 namespace AjK {
00027 
00028 class FPointerDummy;
00029 
00030 /** FPointer - Adds callbacks that take and return a 32bit uint32_t data type.
00031  *
00032  * The Mbed library supplies a callback using the FunctionPointer object as 
00033  * defined in FunctionPointer.h  However, this callback system does not allow
00034  * the caller to pass a value to the callback. Likewise, the callback itself
00035  * cannot return a value.
00036  *
00037  * FPointer operates in the same way but allows the callback function to be
00038  * passed one arg, a uint32_t value. Additionally, the callback can return
00039  * a single uint32_t value. The reason for using uint32_t is that the Mbed
00040  * and the microcontroller (LPC1768) have a natural data size of 32bits and
00041  * this means we can use the uint32_t as a pointer. See example1.h for more
00042  * information. This example passes an "int" by passing a pointer to that
00043  * int as a 32bit value. Using this technique you can pass any value you like.
00044  * All you have to do is pass a pointer to your value cast to (uint32_t). Your
00045  * callback can the deference it to get the original value.
00046  *
00047  * example2.h shows how to do the same thing but demostrates how to specify
00048  * the callback into a class object/method.
00049  *
00050  * Finally, example3.h shows how to pass multiple values. In this example we
00051  * define a data structure and in the callback we pass a pointer to that
00052  * data structure thus allowing the callback to again get the values.
00053  *
00054  * Note, when passing pointers to variables to the callback, if the callback
00055  * function/method changes that variable's value then it will also change the
00056  * value the caller sees. If C pointers are new to you, you are strongly
00057  * advised to read up on the subject. It's pointers that often get beginners
00058  * into trouble when mis-used.
00059  *
00060  * @see example1.h
00061  * @see example2.h
00062  * @see example3.h
00063  * @see http://mbed.org/handbook/C-Data-Types
00064  * @see http://mbed.org/projects/libraries/svn/mbed/trunk/FunctionPointer.h
00065  */
00066 class FPointer {
00067 
00068 protected:
00069 
00070     //! C callback function pointer.
00071     uint32_t (*c_callback)(uint32_t); 
00072     
00073     //! C++ callback object/method pointer (the object part).
00074     FPointerDummy  *obj_callback;
00075     
00076     //! C++ callback object/method pointer (the method part).
00077     uint32_t (FPointerDummy::*method_callback)(uint32_t);
00078 
00079 public:
00080     
00081     /** Constructor
00082      */
00083     FPointer() {
00084         c_callback      = NULL;
00085         obj_callback    = NULL;
00086         method_callback = NULL;
00087     }
00088     
00089     /** attach - Overloaded attachment function.
00090      *
00091      * Attach a C type function pointer as the callback.
00092      *
00093      * Note, the callback function prototype must be:-
00094      * @code
00095      * uint32_t myCallbackFunction(uint32_t);
00096      * @endcode
00097      * @param A C function pointer to call.
00098      */
00099     void attach(uint32_t (*function)(uint32_t) = 0) { c_callback = function; }
00100     
00101     /** attach - Overloaded attachment function.
00102      *
00103      * Attach a C++ type object/method pointer as the callback.
00104      *
00105      * Note, the callback method prototype must be:-
00106      * @code
00107      *     public:
00108      *         uint32_t myCallbackFunction(uint32_t);
00109      * @endcode
00110      * @param A C++ object pointer.
00111      * @param A C++ method within the object to call.
00112      */
00113     template<class T> 
00114     void attach(T* item, uint32_t (T::*method)(uint32_t)) { 
00115         obj_callback    = (FPointerDummy *)item; 
00116         method_callback = (uint32_t (FPointerDummy::*)(uint32_t))method; 
00117     }
00118 
00119     /** call - Overloaded callback initiator.
00120      *
00121      * call the callback function.
00122      *
00123      * @param uint32_t The value to pass to the callback.
00124      * @return uint32_t The value the callback returns.
00125      */
00126     uint32_t call(uint32_t arg) {
00127         if (c_callback != NULL) {
00128             return (*c_callback)(arg);
00129         }
00130         else {
00131             if (obj_callback  != NULL && method_callback != NULL) {
00132                 return (obj_callback->*method_callback)(arg);
00133             }
00134         }
00135         return (uint32_t)NULL;
00136     }
00137     
00138     /** call - Overloaded callback initiator.
00139      *
00140      * Call the callback function without passing an argument.
00141      * The callback itself is passed NULL. Note, the callback
00142      * prototype should still be <b>uint32_t callback(uint32_t)</b>.
00143      *
00144      * @return uint32_t The value the callback returns.
00145      */
00146     uint32_t call(void) {
00147         if (c_callback != NULL) {
00148             return (*c_callback)((uint32_t)NULL);
00149         }
00150         else {
00151             if (obj_callback  != NULL && method_callback != NULL) {
00152                 return (obj_callback->*method_callback)((uint32_t)NULL);
00153             }
00154         }
00155         return (uint32_t)NULL;
00156     }    
00157 };
00158 
00159 }; // namespace AjK ends
00160 
00161 using namespace AjK;
00162 
00163 #endif