Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/core/Functor.h @ 882

Last change on this file since 882 was 871, checked in by landauf, 17 years ago

merged core branch to trunk

File size: 18.0 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
38enum FunctionType
39{
40    FT_MEMBER,
41    FT_CONSTMEMBER,
42    FT_STATIC
43};
44
45
46template <class T>
47inline std::string typeToString();
48
49#define CreateTypeToStringTemplate(type) \
50    template <> \
51    inline std::string typeToString<type>() { return #type; }
52
53CreateTypeToStringTemplate(int);
54CreateTypeToStringTemplate(unsigned int);
55CreateTypeToStringTemplate(char);
56CreateTypeToStringTemplate(unsigned char);
57CreateTypeToStringTemplate(short);
58CreateTypeToStringTemplate(unsigned short);
59CreateTypeToStringTemplate(long);
60CreateTypeToStringTemplate(unsigned long);
61CreateTypeToStringTemplate(float);
62CreateTypeToStringTemplate(double);
63CreateTypeToStringTemplate(long double);
64CreateTypeToStringTemplate(bool);
65CreateTypeToStringTemplate(std::string);
66CreateTypeToStringTemplate(orxonox::Vector2);
67CreateTypeToStringTemplate(orxonox::Vector3);
68CreateTypeToStringTemplate(orxonox::Quaternion);
69CreateTypeToStringTemplate(orxonox::ColourValue);
70CreateTypeToStringTemplate(orxonox::Radian);
71CreateTypeToStringTemplate(orxonox::Degree);
72
73
74class _CoreExport Functor
75{
76    public:
77        Functor() {}
78        virtual ~Functor() {}
79
80        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;
81
82        inline int getParamCount() const { return this->numParams_; }
83        inline bool hasReturnvalue() const { return this->hasReturnValue_; }
84        inline FunctionType getType() const { return this->type_; }
85        inline MultiTypeMath getReturnvalue() const { return this->returnedValue_; }
86
87        std::string getTypenameParam(int param) const { return (param > 0 && param <= 5) ? this->typeParam_[param-1] : ""; }
88        std::string getTypenameReturnvalue() const { return this->typeReturnvalue_; }
89
90    protected:
91        int numParams_;
92        bool hasReturnValue_;
93        FunctionType type_;
94        MultiTypeMath returnedValue_;
95
96        std::string typeReturnvalue_;
97        std::string typeParam_[5];
98};
99
100class _CoreExport FunctorStatic : public Functor
101{
102    public:
103        virtual ~FunctorStatic() {}
104        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;
105};
106
107template <class T>
108class FunctorMember : public Functor
109{
110    public:
111        FunctorMember()
112        {
113            constObject_ = 0;
114            object_ = 0;
115            bConstObject_ = false;
116        }
117        virtual ~FunctorMember() {}
118
119        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;
120        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;
121
122        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)
123        {
124            if (this->bConstObject_)
125            {
126                if (this->constObject_)
127                    (*this)(this->constObject_, param1, param2, param3, param4, param5);
128                else
129                {
130                    COUT(1) << "An error occurred in Functor.h:" << std::endl;
131                    COUT(1) << "Error: No const object set." << std::endl;
132                }
133            }
134            else
135            {
136                if (this->object_)
137                    (*this)(this->object_, param1, param2, param3, param4, param5);
138                else
139                {
140                    COUT(1) << "An error occurred in Functor.h:" << std::endl;
141                    COUT(1) << "Error: No object set." << std::endl;
142                }
143            }
144        }
145
146        void setObject(T* object)
147        {
148            this->bConstObject_ = false;
149            this->object_ = object;
150        }
151
152        void setObject(const T* object)
153        {
154            this->bConstObject_ = true;
155            this->constObject_ = object;
156        }
157
158    private:
159        const T* constObject_;
160        T* object_;
161        bool bConstObject_;
162};
163
164
165
166#define MAKE_COMMA(x) MAKE_COMMA##x
167#define MAKE_COMMA0
168#define MAKE_COMMA1 ,
169#define MAKE_COMMA2 ,
170#define MAKE_COMMA3 ,
171#define MAKE_COMMA4 ,
172#define MAKE_COMMA5 ,
173
174
175
176#define FUNCTOR_TEMPLATE(ismember, returnvalue, numparams) FUNCTOR_TEMPLATE##ismember##returnvalue##numparams
177#define FUNCTOR_TEMPLATE000
178#define FUNCTOR_TEMPLATE001 template <class P1>
179#define FUNCTOR_TEMPLATE002 template <class P1, class P2>
180#define FUNCTOR_TEMPLATE003 template <class P1, class P2, class P3>
181#define FUNCTOR_TEMPLATE004 template <class P1, class P2, class P3, class P4>
182#define FUNCTOR_TEMPLATE005 template <class P1, class P2, class P3, class P4, class P5>
183#define FUNCTOR_TEMPLATE010 template <class R>
184#define FUNCTOR_TEMPLATE011 template <class R, class P1>
185#define FUNCTOR_TEMPLATE012 template <class R, class P1, class P2>
186#define FUNCTOR_TEMPLATE013 template <class R, class P1, class P2, class P3>
187#define FUNCTOR_TEMPLATE014 template <class R, class P1, class P2, class P3, class P4>
188#define FUNCTOR_TEMPLATE015 template <class R, class P1, class P2, class P3, class P4, class P5>
189#define FUNCTOR_TEMPLATE100 template <class T>
190#define FUNCTOR_TEMPLATE101 template <class T, class P1>
191#define FUNCTOR_TEMPLATE102 template <class T, class P1, class P2>
192#define FUNCTOR_TEMPLATE103 template <class T, class P1, class P2, class P3>
193#define FUNCTOR_TEMPLATE104 template <class T, class P1, class P2, class P3, class P4>
194#define FUNCTOR_TEMPLATE105 template <class T, class P1, class P2, class P3, class P4, class P5>
195#define FUNCTOR_TEMPLATE110 template <class T, class R>
196#define FUNCTOR_TEMPLATE111 template <class T, class R, class P1>
197#define FUNCTOR_TEMPLATE112 template <class T, class R, class P1, class P2>
198#define FUNCTOR_TEMPLATE113 template <class T, class R, class P1, class P2, class P3>
199#define FUNCTOR_TEMPLATE114 template <class T, class R, class P1, class P2, class P3, class P4>
200#define FUNCTOR_TEMPLATE115 template <class T, class R, class P1, class P2, class P3, class P4, class P5>
201
202
203
204#define FUNCTOR_TEMPLATE_CLASSES(ismember, returnvalue, numparams) FUNCTOR_TEMPLATE_CLASSES##ismember##returnvalue##numparams
205#define FUNCTOR_TEMPLATE_CLASSES000
206#define FUNCTOR_TEMPLATE_CLASSES001 <P1>
207#define FUNCTOR_TEMPLATE_CLASSES002 <P1, P2>
208#define FUNCTOR_TEMPLATE_CLASSES003 <P1, P2, P3>
209#define FUNCTOR_TEMPLATE_CLASSES004 <P1, P2, P3, P4>
210#define FUNCTOR_TEMPLATE_CLASSES005 <P1, P2, P3, P4, P5>
211#define FUNCTOR_TEMPLATE_CLASSES010 <R>
212#define FUNCTOR_TEMPLATE_CLASSES011 <R, P1>
213#define FUNCTOR_TEMPLATE_CLASSES012 <R, P1, P2>
214#define FUNCTOR_TEMPLATE_CLASSES013 <R, P1, P2, P3>
215#define FUNCTOR_TEMPLATE_CLASSES014 <R, P1, P2, P3, P4>
216#define FUNCTOR_TEMPLATE_CLASSES015 <R, P1, P2, P3, P4, P5>
217#define FUNCTOR_TEMPLATE_CLASSES100 <T>
218#define FUNCTOR_TEMPLATE_CLASSES101 <T, P1>
219#define FUNCTOR_TEMPLATE_CLASSES102 <T, P1, P2>
220#define FUNCTOR_TEMPLATE_CLASSES103 <T, P1, P2, P3>
221#define FUNCTOR_TEMPLATE_CLASSES104 <T, P1, P2, P3, P4>
222#define FUNCTOR_TEMPLATE_CLASSES105 <T, P1, P2, P3, P4, P5>
223#define FUNCTOR_TEMPLATE_CLASSES110 <T, R>
224#define FUNCTOR_TEMPLATE_CLASSES111 <T, R, P1>
225#define FUNCTOR_TEMPLATE_CLASSES112 <T, R, P1, P2>
226#define FUNCTOR_TEMPLATE_CLASSES113 <T, R, P1, P2, P3>
227#define FUNCTOR_TEMPLATE_CLASSES114 <T, R, P1, P2, P3, P4>
228#define FUNCTOR_TEMPLATE_CLASSES115 <T, R, P1, P2, P3, P4, P5>
229
230
231
232#define FUNCTOR_TYPENAME_PARAMS(numparams) FUNCTOR_TYPENAME_PARAMS##numparams
233#define FUNCTOR_TYPENAME_PARAMS0
234#define FUNCTOR_TYPENAME_PARAMS1 this->typeParam_[0] = typeToString<P1>();
235#define FUNCTOR_TYPENAME_PARAMS2 this->typeParam_[0] = typeToString<P1>(); this->typeParam_[1] = typeToString<P2>();
236#define FUNCTOR_TYPENAME_PARAMS3 this->typeParam_[0] = typeToString<P1>(); this->typeParam_[1] = typeToString<P2>(); this->typeParam_[2] = typeToString<P3>();
237#define FUNCTOR_TYPENAME_PARAMS4 this->typeParam_[0] = typeToString<P1>(); this->typeParam_[1] = typeToString<P2>(); this->typeParam_[2] = typeToString<P3>(); this->typeParam_[3] = typeToString<P4>();
238#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>();
239
240#define FUNCTOR_TYPENAME_RETURN(returnvalue) FUNCTOR_TYPENAME_RETURN##returnvalue
241#define FUNCTOR_TYPENAME_RETURN0
242#define FUNCTOR_TYPENAME_RETURN1 this->typeReturnvalue_ = typeToString<R>();
243
244
245
246#define FUNCTOR_FUNCTION_PARAMS(numparams) FUNCTOR_FUNCTION_PARAMS##numparams
247#define FUNCTOR_FUNCTION_PARAMS0
248#define FUNCTOR_FUNCTION_PARAMS1 P1 param1
249#define FUNCTOR_FUNCTION_PARAMS2 P1 param1, P2 param2
250#define FUNCTOR_FUNCTION_PARAMS3 P1 param1, P2 param2, P3 param3
251#define FUNCTOR_FUNCTION_PARAMS4 P1 param1, P2 param2, P3 param3, P4 param4
252#define FUNCTOR_FUNCTION_PARAMS5 P1 param1, P2 param2, P3 param3, P4 param4, P5 param5
253
254#define FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) FUNCTOR_FUNCTION_RETURNVALUE##returnvalue
255#define FUNCTOR_FUNCTION_RETURNVALUE0 void
256#define FUNCTOR_FUNCTION_RETURNVALUE1 R
257
258
259
260#define FUNCTOR_FUNCTION_CALL(numparams) FUNCTOR_FUNCTION_CALL##numparams
261#define FUNCTOR_FUNCTION_CALL0
262#define FUNCTOR_FUNCTION_CALL1 param1
263#define FUNCTOR_FUNCTION_CALL2 param1, param2
264#define FUNCTOR_FUNCTION_CALL3 param1, param2, param3
265#define FUNCTOR_FUNCTION_CALL4 param1, param2, param3, param4
266#define FUNCTOR_FUNCTION_CALL5 param1, param2, param3, param4, param5
267
268#define FUNCTOR_STORE_RETURNVALUE(returnvalue, functioncall) FUNCTOR_STORE_RETURNVALUE##returnvalue(functioncall)
269#define FUNCTOR_STORE_RETURNVALUE0(functioncall) functioncall
270#define FUNCTOR_STORE_RETURNVALUE1(functioncall) this->returnedValue_ = functioncall
271
272
273
274
275
276#define CREATE_STATIC_FUNCTOR(returnvalue, numparams) \
277    FUNCTOR_TEMPLATE(0, returnvalue, numparams) \
278    class FunctorStatic##returnvalue##numparams : public FunctorStatic \
279    { \
280        public: \
281            FunctorStatic##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
282            { \
283                this->numParams_ = numparams; \
284                this->hasReturnValue_ = returnvalue; \
285                this->type_ = FT_STATIC; \
286                this->functionPointer_ = functionPointer; \
287                \
288                FUNCTOR_TYPENAME_PARAMS(numparams); \
289                FUNCTOR_TYPENAME_RETURN(returnvalue); \
290            } \
291    \
292            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) \
293            { \
294                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
295            } \
296    \
297        private: \
298            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)); \
299    }; \
300    \
301    \
302    FUNCTOR_TEMPLATE(0, returnvalue, numparams) \
303    inline FunctorStatic##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(0, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
304    { \
305        return new FunctorStatic##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(0, returnvalue, numparams) (functionPointer); \
306    }
307
308
309
310
311
312#define CREATE_MEMBER_FUNCTOR(returnvalue, numparams) \
313    FUNCTOR_TEMPLATE(1, returnvalue, numparams) \
314    class FunctorMember##returnvalue##numparams : public FunctorMember<T> \
315    { \
316        public: \
317            FunctorMember##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
318            { \
319                this->numParams_ = numparams; \
320                this->hasReturnValue_ = returnvalue; \
321                this->type_ = FT_MEMBER; \
322                this->functionPointer_ = functionPointer; \
323            } \
324    \
325            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) \
326            { \
327                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
328            } \
329    \
330            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) \
331            { \
332                COUT(1) << "An error occurred in Functor.h:" << std::endl; \
333                COUT(1) << "Error: Function is not const." << std::endl; \
334            } \
335    \
336        private: \
337            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)); \
338    }; \
339    \
340    \
341    FUNCTOR_TEMPLATE(1, returnvalue, numparams) \
342    class FunctorConstMember##returnvalue##numparams : public FunctorMember<T> \
343    { \
344        public: \
345            FunctorConstMember##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)) const) \
346            { \
347                this->numParams_ = numparams; \
348                this->hasReturnValue_ = returnvalue; \
349                this->type_ = FT_CONSTMEMBER; \
350                this->functionPointer_ = functionPointer; \
351            } \
352    \
353            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) \
354            { \
355                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
356            } \
357    \
358            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) \
359            { \
360                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
361            } \
362    \
363        private: \
364            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)) const; \
365    }; \
366    \
367    \
368    FUNCTOR_TEMPLATE(1, returnvalue, numparams) \
369    inline FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
370    { \
371        return new FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
372    } \
373    \
374    \
375    FUNCTOR_TEMPLATE(1, returnvalue, numparams) \
376    inline FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)) const) \
377    { \
378        return new FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
379    }
380
381
382
383
384#define CREATE_ALL_STATIC_FUNCTORS() \
385    CREATE_STATIC_FUNCTOR(0, 0); \
386    CREATE_STATIC_FUNCTOR(0, 1); \
387    CREATE_STATIC_FUNCTOR(0, 2); \
388    CREATE_STATIC_FUNCTOR(0, 3); \
389    CREATE_STATIC_FUNCTOR(0, 4); \
390    CREATE_STATIC_FUNCTOR(0, 5); \
391    CREATE_STATIC_FUNCTOR(1, 0); \
392    CREATE_STATIC_FUNCTOR(1, 1); \
393    CREATE_STATIC_FUNCTOR(1, 2); \
394    CREATE_STATIC_FUNCTOR(1, 3); \
395    CREATE_STATIC_FUNCTOR(1, 4); \
396    CREATE_STATIC_FUNCTOR(1, 5)
397
398
399#define CREATE_ALL_MEMBER_FUNCTORS() \
400    CREATE_MEMBER_FUNCTOR(0, 0); \
401    CREATE_MEMBER_FUNCTOR(0, 1); \
402    CREATE_MEMBER_FUNCTOR(0, 2); \
403    CREATE_MEMBER_FUNCTOR(0, 3); \
404    CREATE_MEMBER_FUNCTOR(0, 4); \
405    CREATE_MEMBER_FUNCTOR(0, 5); \
406    CREATE_MEMBER_FUNCTOR(1, 0); \
407    CREATE_MEMBER_FUNCTOR(1, 1); \
408    CREATE_MEMBER_FUNCTOR(1, 2); \
409    CREATE_MEMBER_FUNCTOR(1, 3); \
410    CREATE_MEMBER_FUNCTOR(1, 4); \
411    CREATE_MEMBER_FUNCTOR(1, 5)
412
413
414CREATE_ALL_STATIC_FUNCTORS();
415CREATE_ALL_MEMBER_FUNCTORS();
416
417#endif /* _Functor_H__ */
Note: See TracBrowser for help on using the repository browser.