Don't chain header includes if we don't have to, use predeclaration if we only need...
[clinton/Smoothieware.git] / src / libs / FPointer.h
CommitLineData
8b8b3339
AW
1/*
2Copyright (c) 2011 Andy Kirkham
3Permission is hereby granted, free of charge, to any person obtaining a copy
4of this software and associated documentation files (the "Software"), to deal
5in the Software without restriction, including without limitation the rights
6to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7copies of the Software, and to permit persons to whom the Software is
8furnished to do so, subject to the following conditions:
9The above copyright notice and this permission notice shall be included in
10all copies or substantial portions of the Software.
11THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
17THE SOFTWARE.
18*/
19
20#ifndef AJK_FPOINTER_H
21#define AJK_FPOINTER_H
5673fe39 22
8b8b3339
AW
23#ifndef NULL
24#define NULL 0
25#endif
5673fe39
MM
26
27#include <cstdint>
28
8b8b3339
AW
29namespace AjK {
30
31class FPointerDummy;
32
33/** FPointer - Adds callbacks that take and return a 32bit uint32_t data type.
34*
35* The Mbed library supplies a callback using the FunctionPointer object as
36* defined in FunctionPointer.h However, this callback system does not allow
37* the caller to pass a value to the callback. Likewise, the callback itself
38* cannot return a value.
39*
40* FPointer operates in the same way but allows the callback function to be
41* passed one arg, a uint32_t value. Additionally, the callback can return
42* a single uint32_t value. The reason for using uint32_t is that the Mbed
43* and the microcontroller (LPC1768) have a natural data size of 32bits and
44* this means we can use the uint32_t as a pointer. See example1.h for more
45* information. This example passes an "int" by passing a pointer to that
46* int as a 32bit value. Using this technique you can pass any value you like.
47* All you have to do is pass a pointer to your value cast to (uint32_t). Your
48* callback can the deference it to get the original value.
49*
50* example2.h shows how to do the same thing but demostrates how to specify
51* the callback into a class object/method.
52*
53* Finally, example3.h shows how to pass multiple values. In this example we
54* define a data structure and in the callback we pass a pointer to that
55* data structure thus allowing the callback to again get the values.
56*
57* Note, when passing pointers to variables to the callback, if the callback
58* function/method changes that variable's value then it will also change the
59* value the caller sees. If C pointers are new to you, you are strongly
60* advised to read up on the subject. It's pointers that often get beginners
61* into trouble when mis-used.
62*
63* @see example1.h
64* @see example2.h
65* @see example3.h
66* @see http://mbed.org/handbook/C-Data-Types
67* @see http://mbed.org/projects/libraries/svn/mbed/trunk/FunctionPointer.h
68*/
69class FPointer {
70
71protected:
72
73 //! C callback function pointer.
74 uint32_t (*c_callback)(uint32_t);
75
76 //! C++ callback object/method pointer (the object part).
77 FPointerDummy *obj_callback;
78
79 //! C++ callback object/method pointer (the method part).
80 uint32_t (FPointerDummy::*method_callback)(uint32_t);
81
82public:
83
84 /** Constructor
85*/
86 FPointer() {
87 c_callback = NULL;
88 obj_callback = NULL;
89 method_callback = NULL;
90 }
91
92 /** attach - Overloaded attachment function.
93*
94* Attach a C type function pointer as the callback.
95*
96* Note, the callback function prototype must be:-
97* @code
98* uint32_t myCallbackFunction(uint32_t);
99* @endcode
100* @param A C function pointer to call.
101*/
102 void attach(uint32_t (*function)(uint32_t) = 0) { c_callback = function; }
103
104 /** attach - Overloaded attachment function.
105*
106* Attach a C++ type object/method pointer as the callback.
107*
108* Note, the callback method prototype must be:-
109* @code
110* public:
111* uint32_t myCallbackFunction(uint32_t);
112* @endcode
113* @param A C++ object pointer.
114* @param A C++ method within the object to call.
115*/
116 template<class T>
117 void attach(T* item, uint32_t (T::*method)(uint32_t)) {
118 obj_callback = (FPointerDummy *)item;
119 method_callback = (uint32_t (FPointerDummy::*)(uint32_t))method;
120 }
121
122 /** call - Overloaded callback initiator.
123*
124* call the callback function.
125*
126* @param uint32_t The value to pass to the callback.
127* @return uint32_t The value the callback returns.
128*/
129 uint32_t call(uint32_t arg) {
130 if (c_callback != NULL) {
131 return (*c_callback)(arg);
132 }
133 else {
134 if (obj_callback != NULL && method_callback != NULL) {
135 return (obj_callback->*method_callback)(arg);
136 }
137 }
138 return (uint32_t)NULL;
139 }
140
141 /** call - Overloaded callback initiator.
142*
143* Call the callback function without passing an argument.
144* The callback itself is passed NULL. Note, the callback
145* prototype should still be <b>uint32_t callback(uint32_t)</b>.
146*
147* @return uint32_t The value the callback returns.
148*/
149 uint32_t call(void) {
150 if (c_callback != NULL) {
151 return (*c_callback)((uint32_t)NULL);
152 }
153 else {
154 if (obj_callback != NULL && method_callback != NULL) {
155 return (obj_callback->*method_callback)((uint32_t)NULL);
156 }
157 }
158 return (uint32_t)NULL;
159 }
160};
161
162}; // namespace AjK ends
163
164using namespace AjK;
165
166#endif