Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core2/src/orxonox/core/Functor.h @ 939

Last change on this file since 939 was 931, checked in by landauf, 16 years ago

expanded Executor

File size: 17.9 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *
4 *
5 *   License notice:
6 *
7 *   This program is free software; you can redistribute it and/or
8 *   modify it under the terms of the GNU General Public License
9 *   as published by the Free Software Foundation; either version 2
10 *   of the License, or (at your option) any later version.
11 *
12 *   This program is distributed in the hope that it will be useful,
13 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
14 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 *   GNU General Public License for more details.
16 *
17 *   You should have received a copy of the GNU General Public License
18 *   along with this program; if not, write to the Free Software
19 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 *
21 *   Author:
22 *      Fabian 'x3n' Landau
23 *   Co-authors:
24 *      ...
25 *
26 *   Inspiration: Functor by Benjamin Grauer
27 */
28
29#ifndef _Functor_H__
30#define _Functor_H__
31
32#include "util/MultiTypeMath.h"
33#include "Debug.h"
34
35#include "CorePrereqs.h"
36
37#define MAX_FUNCTOR_ARGUMENTS 5
38
39enum FunctionType
40{
41    FT_MEMBER,
42    FT_CONSTMEMBER,
43    FT_STATIC
44};
45
46
47template <class T>
48inline std::string typeToString();
49
50#define CreateTypeToStringTemplate(type) \
51    template <> \
52    inline std::string typeToString<type>() { return #type; }
53
54CreateTypeToStringTemplate(int);
55CreateTypeToStringTemplate(unsigned int);
56CreateTypeToStringTemplate(char);
57CreateTypeToStringTemplate(unsigned char);
58CreateTypeToStringTemplate(short);
59CreateTypeToStringTemplate(unsigned short);
60CreateTypeToStringTemplate(long);
61CreateTypeToStringTemplate(unsigned long);
62CreateTypeToStringTemplate(float);
63CreateTypeToStringTemplate(double);
64CreateTypeToStringTemplate(long double);
65CreateTypeToStringTemplate(bool);
66CreateTypeToStringTemplate(std::string);
67CreateTypeToStringTemplate(orxonox::Vector2);
68CreateTypeToStringTemplate(orxonox::Vector3);
69CreateTypeToStringTemplate(orxonox::Quaternion);
70CreateTypeToStringTemplate(orxonox::ColourValue);
71CreateTypeToStringTemplate(orxonox::Radian);
72CreateTypeToStringTemplate(orxonox::Degree);
73
74
75class _CoreExport Functor
76{
77    public:
78        Functor() {}
79        virtual ~Functor() {}
80
81        virtual void operator()(const MultiTypeMath& param1 = MT_null, const MultiTypeMath& param2 = MT_null, const MultiTypeMath& param3 = MT_null, const MultiTypeMath& param4 = MT_null, const MultiTypeMath& param5 = MT_null) = 0;
82
83        inline unsigned int getParamCount() const { return this->numParams_; }
84        inline bool hasReturnvalue() const { return this->hasReturnValue_; }
85        inline FunctionType getType() const { return this->type_; }
86        inline MultiTypeMath getReturnvalue() const { return this->returnedValue_; }
87
88        std::string getTypenameParam(int param) const { return (param > 0 && param <= 5) ? this->typeParam_[param-1] : ""; }
89        std::string getTypenameReturnvalue() const { return this->typeReturnvalue_; }
90
91    protected:
92        unsigned int numParams_;
93        bool hasReturnValue_;
94        FunctionType type_;
95        MultiTypeMath returnedValue_;
96
97        std::string typeReturnvalue_;
98        std::string typeParam_[MAX_FUNCTOR_ARGUMENTS];
99};
100
101class _CoreExport FunctorStatic : public Functor
102{
103    public:
104        virtual ~FunctorStatic() {}
105        virtual void operator()(const MultiTypeMath& param1 = MT_null, const MultiTypeMath& param2 = MT_null, const MultiTypeMath& param3 = MT_null, const MultiTypeMath& param4 = MT_null, const MultiTypeMath& param5 = MT_null) = 0;
106};
107
108template <class T>
109class FunctorMember : public Functor
110{
111    public:
112        FunctorMember()
113        {
114            constObject_ = 0;
115            object_ = 0;
116            bConstObject_ = false;
117        }
118        virtual ~FunctorMember() {}
119
120        virtual void operator()(T* object, const MultiTypeMath& param1 = MT_null, const MultiTypeMath& param2 = MT_null, const MultiTypeMath& param3 = MT_null, const MultiTypeMath& param4 = MT_null, const MultiTypeMath& param5 = MT_null) = 0;
121        virtual void operator()(const T* object, const MultiTypeMath& param1 = MT_null, const MultiTypeMath& param2 = MT_null, const MultiTypeMath& param3 = MT_null, const MultiTypeMath& param4 = MT_null, const MultiTypeMath& param5 = MT_null) = 0;
122
123        virtual void operator()(const MultiTypeMath& param1 = MT_null, const MultiTypeMath& param2 = MT_null, const MultiTypeMath& param3 = MT_null, const MultiTypeMath& param4 = MT_null, const MultiTypeMath& param5 = MT_null)
124        {
125            if (this->bConstObject_)
126            {
127                if (this->constObject_)
128                    (*this)(this->constObject_, param1, param2, param3, param4, param5);
129                else
130                {
131                    COUT(1) << "An error occurred in Functor.h:" << std::endl;
132                    COUT(1) << "Error: No const object set." << std::endl;
133                }
134            }
135            else
136            {
137                if (this->object_)
138                    (*this)(this->object_, param1, param2, param3, param4, param5);
139                else
140                {
141                    COUT(1) << "An error occurred in Functor.h:" << std::endl;
142                    COUT(1) << "Error: No object set." << std::endl;
143                }
144            }
145        }
146
147        void setObject(T* object)
148        {
149            this->bConstObject_ = false;
150            this->object_ = object;
151        }
152
153        void setObject(const T* object)
154        {
155            this->bConstObject_ = true;
156            this->constObject_ = object;
157        }
158
159    private:
160        const T* constObject_;
161        T* object_;
162        bool bConstObject_;
163};
164
165
166
167#define FUNCTOR_TEMPLATE(ismember, returnvalue, numparams) FUNCTOR_TEMPLATE##ismember##returnvalue##numparams
168#define FUNCTOR_TEMPLATE000
169#define FUNCTOR_TEMPLATE001 template <class P1>
170#define FUNCTOR_TEMPLATE002 template <class P1, class P2>
171#define FUNCTOR_TEMPLATE003 template <class P1, class P2, class P3>
172#define FUNCTOR_TEMPLATE004 template <class P1, class P2, class P3, class P4>
173#define FUNCTOR_TEMPLATE005 template <class P1, class P2, class P3, class P4, class P5>
174#define FUNCTOR_TEMPLATE010 template <class R>
175#define FUNCTOR_TEMPLATE011 template <class R, class P1>
176#define FUNCTOR_TEMPLATE012 template <class R, class P1, class P2>
177#define FUNCTOR_TEMPLATE013 template <class R, class P1, class P2, class P3>
178#define FUNCTOR_TEMPLATE014 template <class R, class P1, class P2, class P3, class P4>
179#define FUNCTOR_TEMPLATE015 template <class R, class P1, class P2, class P3, class P4, class P5>
180#define FUNCTOR_TEMPLATE100 template <class T>
181#define FUNCTOR_TEMPLATE101 template <class T, class P1>
182#define FUNCTOR_TEMPLATE102 template <class T, class P1, class P2>
183#define FUNCTOR_TEMPLATE103 template <class T, class P1, class P2, class P3>
184#define FUNCTOR_TEMPLATE104 template <class T, class P1, class P2, class P3, class P4>
185#define FUNCTOR_TEMPLATE105 template <class T, class P1, class P2, class P3, class P4, class P5>
186#define FUNCTOR_TEMPLATE110 template <class T, class R>
187#define FUNCTOR_TEMPLATE111 template <class T, class R, class P1>
188#define FUNCTOR_TEMPLATE112 template <class T, class R, class P1, class P2>
189#define FUNCTOR_TEMPLATE113 template <class T, class R, class P1, class P2, class P3>
190#define FUNCTOR_TEMPLATE114 template <class T, class R, class P1, class P2, class P3, class P4>
191#define FUNCTOR_TEMPLATE115 template <class T, class R, class P1, class P2, class P3, class P4, class P5>
192
193
194
195#define FUNCTOR_TEMPLATE_CLASSES(ismember, returnvalue, numparams) FUNCTOR_TEMPLATE_CLASSES##ismember##returnvalue##numparams
196#define FUNCTOR_TEMPLATE_CLASSES000
197#define FUNCTOR_TEMPLATE_CLASSES001 <P1>
198#define FUNCTOR_TEMPLATE_CLASSES002 <P1, P2>
199#define FUNCTOR_TEMPLATE_CLASSES003 <P1, P2, P3>
200#define FUNCTOR_TEMPLATE_CLASSES004 <P1, P2, P3, P4>
201#define FUNCTOR_TEMPLATE_CLASSES005 <P1, P2, P3, P4, P5>
202#define FUNCTOR_TEMPLATE_CLASSES010 <R>
203#define FUNCTOR_TEMPLATE_CLASSES011 <R, P1>
204#define FUNCTOR_TEMPLATE_CLASSES012 <R, P1, P2>
205#define FUNCTOR_TEMPLATE_CLASSES013 <R, P1, P2, P3>
206#define FUNCTOR_TEMPLATE_CLASSES014 <R, P1, P2, P3, P4>
207#define FUNCTOR_TEMPLATE_CLASSES015 <R, P1, P2, P3, P4, P5>
208#define FUNCTOR_TEMPLATE_CLASSES100 <T>
209#define FUNCTOR_TEMPLATE_CLASSES101 <T, P1>
210#define FUNCTOR_TEMPLATE_CLASSES102 <T, P1, P2>
211#define FUNCTOR_TEMPLATE_CLASSES103 <T, P1, P2, P3>
212#define FUNCTOR_TEMPLATE_CLASSES104 <T, P1, P2, P3, P4>
213#define FUNCTOR_TEMPLATE_CLASSES105 <T, P1, P2, P3, P4, P5>
214#define FUNCTOR_TEMPLATE_CLASSES110 <T, R>
215#define FUNCTOR_TEMPLATE_CLASSES111 <T, R, P1>
216#define FUNCTOR_TEMPLATE_CLASSES112 <T, R, P1, P2>
217#define FUNCTOR_TEMPLATE_CLASSES113 <T, R, P1, P2, P3>
218#define FUNCTOR_TEMPLATE_CLASSES114 <T, R, P1, P2, P3, P4>
219#define FUNCTOR_TEMPLATE_CLASSES115 <T, R, P1, P2, P3, P4, P5>
220
221
222
223#define FUNCTOR_TYPENAME_PARAMS(numparams) FUNCTOR_TYPENAME_PARAMS##numparams
224#define FUNCTOR_TYPENAME_PARAMS0
225#define FUNCTOR_TYPENAME_PARAMS1 this->typeParam_[0] = typeToString<P1>();
226#define FUNCTOR_TYPENAME_PARAMS2 this->typeParam_[0] = typeToString<P1>(); this->typeParam_[1] = typeToString<P2>();
227#define FUNCTOR_TYPENAME_PARAMS3 this->typeParam_[0] = typeToString<P1>(); this->typeParam_[1] = typeToString<P2>(); this->typeParam_[2] = typeToString<P3>();
228#define FUNCTOR_TYPENAME_PARAMS4 this->typeParam_[0] = typeToString<P1>(); this->typeParam_[1] = typeToString<P2>(); this->typeParam_[2] = typeToString<P3>(); this->typeParam_[3] = typeToString<P4>();
229#define FUNCTOR_TYPENAME_PARAMS5 this->typeParam_[0] = typeToString<P1>(); this->typeParam_[1] = typeToString<P2>(); this->typeParam_[2] = typeToString<P3>(); this->typeParam_[3] = typeToString<P4>(); this->typeParam_[4] = typeToString<P5>();
230
231#define FUNCTOR_TYPENAME_RETURN(returnvalue) FUNCTOR_TYPENAME_RETURN##returnvalue
232#define FUNCTOR_TYPENAME_RETURN0
233#define FUNCTOR_TYPENAME_RETURN1 this->typeReturnvalue_ = typeToString<R>();
234
235
236
237#define FUNCTOR_FUNCTION_PARAMS(numparams) FUNCTOR_FUNCTION_PARAMS##numparams
238#define FUNCTOR_FUNCTION_PARAMS0
239#define FUNCTOR_FUNCTION_PARAMS1 P1 param1
240#define FUNCTOR_FUNCTION_PARAMS2 P1 param1, P2 param2
241#define FUNCTOR_FUNCTION_PARAMS3 P1 param1, P2 param2, P3 param3
242#define FUNCTOR_FUNCTION_PARAMS4 P1 param1, P2 param2, P3 param3, P4 param4
243#define FUNCTOR_FUNCTION_PARAMS5 P1 param1, P2 param2, P3 param3, P4 param4, P5 param5
244
245#define FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) FUNCTOR_FUNCTION_RETURNVALUE##returnvalue
246#define FUNCTOR_FUNCTION_RETURNVALUE0 void
247#define FUNCTOR_FUNCTION_RETURNVALUE1 R
248
249
250
251#define FUNCTOR_FUNCTION_CALL(numparams) FUNCTOR_FUNCTION_CALL##numparams
252#define FUNCTOR_FUNCTION_CALL0
253#define FUNCTOR_FUNCTION_CALL1 param1
254#define FUNCTOR_FUNCTION_CALL2 param1, param2
255#define FUNCTOR_FUNCTION_CALL3 param1, param2, param3
256#define FUNCTOR_FUNCTION_CALL4 param1, param2, param3, param4
257#define FUNCTOR_FUNCTION_CALL5 param1, param2, param3, param4, param5
258
259#define FUNCTOR_STORE_RETURNVALUE(returnvalue, functioncall) FUNCTOR_STORE_RETURNVALUE##returnvalue(functioncall)
260#define FUNCTOR_STORE_RETURNVALUE0(functioncall) functioncall
261#define FUNCTOR_STORE_RETURNVALUE1(functioncall) this->returnedValue_ = functioncall
262
263
264
265
266
267#define CREATE_STATIC_FUNCTOR(returnvalue, numparams) \
268    FUNCTOR_TEMPLATE(0, returnvalue, numparams) \
269    class FunctorStatic##returnvalue##numparams : public FunctorStatic \
270    { \
271        public: \
272            FunctorStatic##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
273            { \
274                this->numParams_ = numparams; \
275                this->hasReturnValue_ = returnvalue; \
276                this->type_ = FT_STATIC; \
277                this->functionPointer_ = functionPointer; \
278                \
279                FUNCTOR_TYPENAME_PARAMS(numparams); \
280                FUNCTOR_TYPENAME_RETURN(returnvalue); \
281            } \
282    \
283            void operator()(const MultiTypeMath& param1 = MT_null, const MultiTypeMath& param2 = MT_null, const MultiTypeMath& param3 = MT_null, const MultiTypeMath& param4 = MT_null, const MultiTypeMath& param5 = MT_null) \
284            { \
285                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
286            } \
287    \
288        private: \
289            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)); \
290    }; \
291    \
292    \
293    FUNCTOR_TEMPLATE(0, returnvalue, numparams) \
294    inline FunctorStatic##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(0, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
295    { \
296        return new FunctorStatic##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(0, returnvalue, numparams) (functionPointer); \
297    }
298
299
300
301
302
303#define CREATE_MEMBER_FUNCTOR(returnvalue, numparams) \
304    FUNCTOR_TEMPLATE(1, returnvalue, numparams) \
305    class FunctorMember##returnvalue##numparams : public FunctorMember<T> \
306    { \
307        public: \
308            FunctorMember##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
309            { \
310                this->numParams_ = numparams; \
311                this->hasReturnValue_ = returnvalue; \
312                this->type_ = FT_MEMBER; \
313                this->functionPointer_ = functionPointer; \
314            } \
315    \
316            void operator()(T* object, const MultiTypeMath& param1 = MT_null, const MultiTypeMath& param2 = MT_null, const MultiTypeMath& param3 = MT_null, const MultiTypeMath& param4 = MT_null, const MultiTypeMath& param5 = MT_null) \
317            { \
318                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
319            } \
320    \
321            void operator()(const T* object, const MultiTypeMath& param1 = MT_null, const MultiTypeMath& param2 = MT_null, const MultiTypeMath& param3 = MT_null, const MultiTypeMath& param4 = MT_null, const MultiTypeMath& param5 = MT_null) \
322            { \
323                COUT(1) << "An error occurred in Functor.h:" << std::endl; \
324                COUT(1) << "Error: Function is not const." << std::endl; \
325            } \
326    \
327        private: \
328            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)); \
329    }; \
330    \
331    \
332    FUNCTOR_TEMPLATE(1, returnvalue, numparams) \
333    class FunctorConstMember##returnvalue##numparams : public FunctorMember<T> \
334    { \
335        public: \
336            FunctorConstMember##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)) const) \
337            { \
338                this->numParams_ = numparams; \
339                this->hasReturnValue_ = returnvalue; \
340                this->type_ = FT_CONSTMEMBER; \
341                this->functionPointer_ = functionPointer; \
342            } \
343    \
344            void operator()(T* object, const MultiTypeMath& param1 = MT_null, const MultiTypeMath& param2 = MT_null, const MultiTypeMath& param3 = MT_null, const MultiTypeMath& param4 = MT_null, const MultiTypeMath& param5 = MT_null) \
345            { \
346                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
347            } \
348    \
349            void operator()(const T* object, const MultiTypeMath& param1 = MT_null, const MultiTypeMath& param2 = MT_null, const MultiTypeMath& param3 = MT_null, const MultiTypeMath& param4 = MT_null, const MultiTypeMath& param5 = MT_null) \
350            { \
351                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
352            } \
353    \
354        private: \
355            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)) const; \
356    }; \
357    \
358    \
359    FUNCTOR_TEMPLATE(1, returnvalue, numparams) \
360    inline FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
361    { \
362        return new FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
363    } \
364    \
365    \
366    FUNCTOR_TEMPLATE(1, returnvalue, numparams) \
367    inline FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)) const) \
368    { \
369        return new FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
370    }
371
372
373
374
375#define CREATE_ALL_STATIC_FUNCTORS() \
376    CREATE_STATIC_FUNCTOR(0, 0); \
377    CREATE_STATIC_FUNCTOR(0, 1); \
378    CREATE_STATIC_FUNCTOR(0, 2); \
379    CREATE_STATIC_FUNCTOR(0, 3); \
380    CREATE_STATIC_FUNCTOR(0, 4); \
381    CREATE_STATIC_FUNCTOR(0, 5); \
382    CREATE_STATIC_FUNCTOR(1, 0); \
383    CREATE_STATIC_FUNCTOR(1, 1); \
384    CREATE_STATIC_FUNCTOR(1, 2); \
385    CREATE_STATIC_FUNCTOR(1, 3); \
386    CREATE_STATIC_FUNCTOR(1, 4); \
387    CREATE_STATIC_FUNCTOR(1, 5)
388
389
390#define CREATE_ALL_MEMBER_FUNCTORS() \
391    CREATE_MEMBER_FUNCTOR(0, 0); \
392    CREATE_MEMBER_FUNCTOR(0, 1); \
393    CREATE_MEMBER_FUNCTOR(0, 2); \
394    CREATE_MEMBER_FUNCTOR(0, 3); \
395    CREATE_MEMBER_FUNCTOR(0, 4); \
396    CREATE_MEMBER_FUNCTOR(0, 5); \
397    CREATE_MEMBER_FUNCTOR(1, 0); \
398    CREATE_MEMBER_FUNCTOR(1, 1); \
399    CREATE_MEMBER_FUNCTOR(1, 2); \
400    CREATE_MEMBER_FUNCTOR(1, 3); \
401    CREATE_MEMBER_FUNCTOR(1, 4); \
402    CREATE_MEMBER_FUNCTOR(1, 5)
403
404
405CREATE_ALL_STATIC_FUNCTORS();
406CREATE_ALL_MEMBER_FUNCTORS();
407
408#endif /* _Functor_H__ */
Note: See TracBrowser for help on using the repository browser.