Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/core/Functor.h @ 7188

Last change on this file since 7188 was 7188, checked in by landauf, 14 years ago

reduced amount of member variables in Functor by moving these rarely used properties into virtual functions (which also fixes a small bug, because only FunctorStatic provided all required information so far)

  • Property svn:eol-style set to native
File size: 26.8 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 *   Inspiration: Functor by Benjamin Grauer
28 */
29
30#ifndef _Functor_H__
31#define _Functor_H__
32
33#include <typeinfo>
34
35#include "CorePrereqs.h"
36
37#include "util/Convert.h"
38#include "util/Debug.h"
39#include "util/MultiType.h"
40
41namespace orxonox
42{
43    const unsigned int MAX_FUNCTOR_ARGUMENTS = 5;
44
45    template <class T>
46    inline std::string typeToString() { return "unknown"; }
47
48#define CreateTypeToStringTemplate(type) \
49    template <> \
50    inline std::string typeToString<type>() { return #type; } \
51    template <> \
52    inline std::string typeToString<type&>() { return #type; } \
53    template <> \
54    inline std::string typeToString<const type>() { return #type; } \
55    template <> \
56    inline std::string typeToString<const type&>() { return #type; }
57
58    CreateTypeToStringTemplate(int);
59    CreateTypeToStringTemplate(unsigned int);
60    CreateTypeToStringTemplate(char);
61    CreateTypeToStringTemplate(unsigned char);
62    CreateTypeToStringTemplate(short);
63    CreateTypeToStringTemplate(unsigned short);
64    CreateTypeToStringTemplate(long);
65    CreateTypeToStringTemplate(unsigned long);
66    CreateTypeToStringTemplate(long long);
67    CreateTypeToStringTemplate(unsigned long long);
68    CreateTypeToStringTemplate(float);
69    CreateTypeToStringTemplate(double);
70    CreateTypeToStringTemplate(long double);
71    CreateTypeToStringTemplate(bool);
72    CreateTypeToStringTemplate(Vector2);
73    CreateTypeToStringTemplate(Vector3);
74    CreateTypeToStringTemplate(Quaternion);
75    CreateTypeToStringTemplate(ColourValue);
76    CreateTypeToStringTemplate(Radian);
77    CreateTypeToStringTemplate(Degree);
78
79    template <>
80    inline std::string typeToString<std::string>() { return "string"; }
81    template <>
82    inline std::string typeToString<std::string&>() { return "string"; }
83    template <>
84    inline std::string typeToString<const std::string>() { return "string"; }
85    template <>
86    inline std::string typeToString<const std::string&>() { return "string"; }
87
88    class _CoreExport Functor
89    {
90        public:
91            struct Type
92            {
93                enum Enum
94                {
95                    Member,
96                    ConstMember,
97                    Static,
98                    Lua
99                };
100            };
101
102        public:
103            Functor() {}
104            virtual ~Functor() {}
105
106            virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
107
108            inline const MultiType& getReturnvalue() const { return this->returnedValue_; }
109
110            virtual Type::Enum getType() const = 0;
111            virtual unsigned int getParamCount() const = 0;
112            virtual bool hasReturnvalue() const = 0;
113
114            virtual std::string getTypenameParam(unsigned int param) const = 0;
115            virtual std::string getTypenameReturnvalue() const = 0;
116
117            virtual void evaluateParam(unsigned int index, MultiType& param) const = 0;
118
119            virtual void setRawObjectPointer(void* object) {}
120            virtual void* getRawObjectPointer() const { return 0; }
121
122            virtual const std::type_info& getHeaderIdentifier() const = 0;
123
124        protected:
125            MultiType returnedValue_;
126    };
127
128    class _CoreExport FunctorStatic : public Functor
129    {
130        public:
131            virtual ~FunctorStatic() {}
132            virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
133    };
134
135    template <class T>
136    class FunctorMember : public Functor
137    {
138        public:
139            FunctorMember()
140            {
141                this->object_ = 0;
142                this->constObject_ = 0;
143            }
144            virtual ~FunctorMember() {}
145
146            virtual void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
147            virtual void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) = 0;
148
149            virtual void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null)
150            {
151                if (this->object_)
152                    (*this)(this->object_, param1, param2, param3, param4, param5);
153                else if (this->constObject_)
154                    (*this)(this->constObject_, param1, param2, param3, param4, param5);
155                else
156                {
157                    COUT(1) << "An error occurred in Functor.h:" << std::endl;
158                    COUT(1) << "Error: No object set." << std::endl;
159                }
160            }
161
162            inline FunctorMember<T>* setObject(T* object)
163            {
164                this->object_ = object;
165                this->constObject_ = 0;
166                return this;
167            }
168
169            inline FunctorMember<T>* setObject(const T* object)
170            {
171                this->object_ = 0;
172                this->constObject_ = object;
173                return this;
174            }
175
176            void setRawObjectPointer(void* object)
177            {
178                this->object_ = (T*)object;
179                this->constObject_ = 0;
180            }
181
182            void* getRawObjectPointer() const
183            {
184                if (this->object_)
185                    return (void*)this->object_;
186                else
187                    return (void*)this->constObject_;
188            }
189
190            typedef std::pair<T*, const T*> Objects;
191
192            inline Objects getObjects() const
193            {
194                return Objects(this->object_, this->constObject_);
195            }
196
197            inline void setObjects(const Objects& objects)
198            {
199                this->object_ = objects.first;
200                this->constObject_ = objects.second;
201            }
202
203        private:
204            T* object_;
205            const T* constObject_;
206    };
207
208
209
210    template <class R, class P1, class P2, class P3, class P4, class P5>
211    struct FunctorHeaderIdentifier {};
212
213
214
215    inline Functor* createFunctor(Functor* functor)
216    {
217        return functor;
218    }
219
220
221
222#define FUNCTOR_TEMPLATE(ismember, returnvalue, numparams, additionalobject) FUNCTOR_TEMPLATE##ismember##returnvalue##numparams(additionalobject)
223#define FUNCTOR_TEMPLATE000(additionalobject)
224#define FUNCTOR_TEMPLATE001(additionalobject) template <class P1>
225#define FUNCTOR_TEMPLATE002(additionalobject) template <class P1, class P2>
226#define FUNCTOR_TEMPLATE003(additionalobject) template <class P1, class P2, class P3>
227#define FUNCTOR_TEMPLATE004(additionalobject) template <class P1, class P2, class P3, class P4>
228#define FUNCTOR_TEMPLATE005(additionalobject) template <class P1, class P2, class P3, class P4, class P5>
229#define FUNCTOR_TEMPLATE010(additionalobject) template <class R>
230#define FUNCTOR_TEMPLATE011(additionalobject) template <class R, class P1>
231#define FUNCTOR_TEMPLATE012(additionalobject) template <class R, class P1, class P2>
232#define FUNCTOR_TEMPLATE013(additionalobject) template <class R, class P1, class P2, class P3>
233#define FUNCTOR_TEMPLATE014(additionalobject) template <class R, class P1, class P2, class P3, class P4>
234#define FUNCTOR_TEMPLATE015(additionalobject) template <class R, class P1, class P2, class P3, class P4, class P5>
235#define FUNCTOR_TEMPLATE100(additionalobject) template <class T FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
236#define FUNCTOR_TEMPLATE101(additionalobject) template <class T, class P1 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
237#define FUNCTOR_TEMPLATE102(additionalobject) template <class T, class P1, class P2 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
238#define FUNCTOR_TEMPLATE103(additionalobject) template <class T, class P1, class P2, class P3 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
239#define FUNCTOR_TEMPLATE104(additionalobject) template <class T, class P1, class P2, class P3, class P4 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
240#define FUNCTOR_TEMPLATE105(additionalobject) template <class T, class P1, class P2, class P3, class P4, class P5 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
241#define FUNCTOR_TEMPLATE110(additionalobject) template <class T, class R FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
242#define FUNCTOR_TEMPLATE111(additionalobject) template <class T, class R, class P1 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
243#define FUNCTOR_TEMPLATE112(additionalobject) template <class T, class R, class P1, class P2 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
244#define FUNCTOR_TEMPLATE113(additionalobject) template <class T, class R, class P1, class P2, class P3 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
245#define FUNCTOR_TEMPLATE114(additionalobject) template <class T, class R, class P1, class P2, class P3, class P4 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
246#define FUNCTOR_TEMPLATE115(additionalobject) template <class T, class R, class P1, class P2, class P3, class P4, class P5 FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) >
247
248
249
250#define FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT(additionalobject) FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT##additionalobject
251#define FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT0
252#define FUNCTOR_TEMPLATE_ADDITIONAL_OBJECT1 , class O
253
254
255
256#define FUNCTOR_TEMPLATE_CLASSES(ismember, returnvalue, numparams) FUNCTOR_TEMPLATE_CLASSES##ismember##returnvalue##numparams
257#define FUNCTOR_TEMPLATE_CLASSES000
258#define FUNCTOR_TEMPLATE_CLASSES001 <P1>
259#define FUNCTOR_TEMPLATE_CLASSES002 <P1, P2>
260#define FUNCTOR_TEMPLATE_CLASSES003 <P1, P2, P3>
261#define FUNCTOR_TEMPLATE_CLASSES004 <P1, P2, P3, P4>
262#define FUNCTOR_TEMPLATE_CLASSES005 <P1, P2, P3, P4, P5>
263#define FUNCTOR_TEMPLATE_CLASSES010 <R>
264#define FUNCTOR_TEMPLATE_CLASSES011 <R, P1>
265#define FUNCTOR_TEMPLATE_CLASSES012 <R, P1, P2>
266#define FUNCTOR_TEMPLATE_CLASSES013 <R, P1, P2, P3>
267#define FUNCTOR_TEMPLATE_CLASSES014 <R, P1, P2, P3, P4>
268#define FUNCTOR_TEMPLATE_CLASSES015 <R, P1, P2, P3, P4, P5>
269#define FUNCTOR_TEMPLATE_CLASSES100 <T>
270#define FUNCTOR_TEMPLATE_CLASSES101 <T, P1>
271#define FUNCTOR_TEMPLATE_CLASSES102 <T, P1, P2>
272#define FUNCTOR_TEMPLATE_CLASSES103 <T, P1, P2, P3>
273#define FUNCTOR_TEMPLATE_CLASSES104 <T, P1, P2, P3, P4>
274#define FUNCTOR_TEMPLATE_CLASSES105 <T, P1, P2, P3, P4, P5>
275#define FUNCTOR_TEMPLATE_CLASSES110 <T, R>
276#define FUNCTOR_TEMPLATE_CLASSES111 <T, R, P1>
277#define FUNCTOR_TEMPLATE_CLASSES112 <T, R, P1, P2>
278#define FUNCTOR_TEMPLATE_CLASSES113 <T, R, P1, P2, P3>
279#define FUNCTOR_TEMPLATE_CLASSES114 <T, R, P1, P2, P3, P4>
280#define FUNCTOR_TEMPLATE_CLASSES115 <T, R, P1, P2, P3, P4, P5>
281
282
283
284#define FUNCTOR_TYPENAME_PARAM(numparams) FUNCTOR_TYPENAME_PARAM##numparams
285#define FUNCTOR_TYPENAME_PARAM0 \
286    return BLANKSTRING
287#define FUNCTOR_TYPENAME_PARAM1 \
288    if (param == 0) { return typeToString<P1>(); } \
289    else { return BLANKSTRING; }
290#define FUNCTOR_TYPENAME_PARAM2 \
291    if (param == 0) { return typeToString<P1>(); } \
292    else if (param == 1) { return typeToString<P2>(); } \
293    else { return BLANKSTRING; }
294#define FUNCTOR_TYPENAME_PARAM3 \
295    if (param == 0) { return typeToString<P1>(); } \
296    else if (param == 1) { return typeToString<P2>(); } \
297    else if (param == 2) { return typeToString<P3>(); } \
298    else { return BLANKSTRING; }
299#define FUNCTOR_TYPENAME_PARAM4 \
300    if (param == 0) { return typeToString<P1>(); } \
301    else if (param == 1) { return typeToString<P2>(); } \
302    else if (param == 2) { return typeToString<P3>(); } \
303    else if (param == 3) { return typeToString<P4>(); } \
304    else { return BLANKSTRING; }
305#define FUNCTOR_TYPENAME_PARAM5 \
306    if (param == 0) { return typeToString<P1>(); } \
307    else if (param == 1) { return typeToString<P2>(); } \
308    else if (param == 2) { return typeToString<P3>(); } \
309    else if (param == 3) { return typeToString<P4>(); } \
310    else if (param == 4) { return typeToString<P5>(); } \
311    else { return BLANKSTRING; }
312
313#define FUNCTOR_TYPENAME_RETURN(returnvalue) FUNCTOR_TYPENAME_RETURN##returnvalue
314#define FUNCTOR_TYPENAME_RETURN0 BLANKSTRING
315#define FUNCTOR_TYPENAME_RETURN1 typeToString<R>()
316
317
318
319#define FUNCTOR_FUNCTION_PARAMS(numparams) FUNCTOR_FUNCTION_PARAMS##numparams
320#define FUNCTOR_FUNCTION_PARAMS0
321#define FUNCTOR_FUNCTION_PARAMS1 P1 param1
322#define FUNCTOR_FUNCTION_PARAMS2 P1 param1, P2 param2
323#define FUNCTOR_FUNCTION_PARAMS3 P1 param1, P2 param2, P3 param3
324#define FUNCTOR_FUNCTION_PARAMS4 P1 param1, P2 param2, P3 param3, P4 param4
325#define FUNCTOR_FUNCTION_PARAMS5 P1 param1, P2 param2, P3 param3, P4 param4, P5 param5
326
327#define FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) FUNCTOR_FUNCTION_RETURNVALUE##returnvalue
328#define FUNCTOR_FUNCTION_RETURNVALUE0 void
329#define FUNCTOR_FUNCTION_RETURNVALUE1 R
330
331
332
333#define FUNCTOR_FUNCTION_CALL(numparams) FUNCTOR_FUNCTION_CALL##numparams
334#define FUNCTOR_FUNCTION_CALL0
335#define FUNCTOR_FUNCTION_CALL1 param1
336#define FUNCTOR_FUNCTION_CALL2 param1, param2
337#define FUNCTOR_FUNCTION_CALL3 param1, param2, param3
338#define FUNCTOR_FUNCTION_CALL4 param1, param2, param3, param4
339#define FUNCTOR_FUNCTION_CALL5 param1, param2, param3, param4, param5
340
341#define FUNCTOR_STORE_RETURNVALUE(returnvalue, functioncall) FUNCTOR_STORE_RETURNVALUE##returnvalue(functioncall)
342#define FUNCTOR_STORE_RETURNVALUE0(functioncall) functioncall
343#define FUNCTOR_STORE_RETURNVALUE1(functioncall) this->returnedValue_ = functioncall
344
345
346
347#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES(returnvalue, numparams) FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES##numparams(returnvalue)
348#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES0(returnvalue) <FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), void, void, void, void, void>
349#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES1(returnvalue) <FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), P1, void, void, void, void>
350#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES2(returnvalue) <FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), P1, P2, void, void, void>
351#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES3(returnvalue) <FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), P1, P2, P3, void, void>
352#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES4(returnvalue) <FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), P1, P2, P3, P4, void>
353#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES5(returnvalue) <FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue), P1, P2, P3, P4, P5>
354
355#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE(returnvalue) FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE##returnvalue
356#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE0 void
357#define FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES_RETURNVALUE1 R
358
359
360
361#define FUNCTOR_EVALUATE_PARAM(numparams) FUNCTOR_EVALUATE_PARAM##numparams
362#define FUNCTOR_EVALUATE_PARAM0
363#define FUNCTOR_EVALUATE_PARAM1 \
364    if (index == 0) { param.convert<P1>(); }
365#define FUNCTOR_EVALUATE_PARAM2 \
366    if (index == 0) { param.convert<P1>(); } \
367    else if (index == 1) { param.convert<P2>(); }
368#define FUNCTOR_EVALUATE_PARAM3 \
369    if (index == 0) { param.convert<P1>(); } \
370    else if (index == 1) { param.convert<P2>(); } \
371    else if (index == 2) { param.convert<P3>(); }
372#define FUNCTOR_EVALUATE_PARAM4 \
373    if (index == 0) { param.convert<P1>(); } \
374    else if (index == 1) { param.convert<P2>(); } \
375    else if (index == 2) { param.convert<P3>(); } \
376    else if (index == 3) { param.convert<P4>(); }
377#define FUNCTOR_EVALUATE_PARAM5 \
378    if (index == 0) { param.convert<P1>(); } \
379    else if (index == 1) { param.convert<P2>(); } \
380    else if (index == 2) { param.convert<P3>(); } \
381    else if (index == 3) { param.convert<P4>(); } \
382    else if (index == 4) { param.convert<P5>(); }
383
384
385
386
387#define CREATE_STATIC_FUNCTOR(returnvalue, numparams) \
388    FUNCTOR_TEMPLATE(0, returnvalue, numparams, 0) \
389    class FunctorStatic##returnvalue##numparams : public FunctorStatic \
390    { \
391        public: \
392            FunctorStatic##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
393            { \
394                this->functionPointer_ = functionPointer; \
395            } \
396    \
397            void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
398            { \
399                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
400            } \
401    \
402            void evaluateParam(unsigned int index, MultiType& param) const \
403            { \
404                FUNCTOR_EVALUATE_PARAM(numparams); \
405            } \
406    \
407            Functor::Type::Enum getType() const { return Functor::Type::Static; } \
408            unsigned int getParamCount() const { return numparams; } \
409            bool hasReturnvalue() const { return returnvalue; } \
410            std::string getTypenameParam(unsigned int param) const { FUNCTOR_TYPENAME_PARAM(numparams); } \
411            std::string getTypenameReturnvalue() const { return FUNCTOR_TYPENAME_RETURN(returnvalue); } \
412    \
413            const std::type_info& getHeaderIdentifier() const \
414            { \
415                return typeid(FunctorHeaderIdentifier FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES(returnvalue, numparams)); \
416            } \
417    \
418        private: \
419            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)); \
420    }; \
421    \
422    \
423    FUNCTOR_TEMPLATE(0, returnvalue, numparams, 0) \
424    inline FunctorStatic##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(0, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
425    { \
426        return new FunctorStatic##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(0, returnvalue, numparams) (functionPointer); \
427    }
428
429
430
431
432
433#define CREATE_MEMBER_FUNCTOR(returnvalue, numparams) \
434    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 0) \
435    class FunctorMember##returnvalue##numparams : public FunctorMember<T> \
436    { \
437        public: \
438            FunctorMember##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
439            { \
440                this->functionPointer_ = functionPointer; \
441            } \
442    \
443            void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
444            { \
445                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
446            } \
447    \
448            void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
449            { \
450                COUT(1) << "An error occurred in Functor.h:" << std::endl; \
451                COUT(1) << "Error: Function is not const." << std::endl; \
452            } \
453    \
454            void evaluateParam(unsigned int index, MultiType& param) const \
455            { \
456                FUNCTOR_EVALUATE_PARAM(numparams); \
457            } \
458    \
459            Functor::Type::Enum getType() const { return Functor::Type::Member; } \
460            unsigned int getParamCount() const { return numparams; } \
461            bool hasReturnvalue() const { return returnvalue; } \
462            std::string getTypenameParam(unsigned int param) const { FUNCTOR_TYPENAME_PARAM(numparams); } \
463            std::string getTypenameReturnvalue() const { return FUNCTOR_TYPENAME_RETURN(returnvalue); } \
464    \
465            const std::type_info& getHeaderIdentifier() const \
466            { \
467                return typeid(FunctorHeaderIdentifier FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES(returnvalue, numparams)); \
468            } \
469    \
470        private: \
471            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)); \
472    }; \
473    \
474    \
475    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 0) \
476    class FunctorConstMember##returnvalue##numparams : public FunctorMember<T> \
477    { \
478        public: \
479            FunctorConstMember##returnvalue##numparams(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)) const) \
480            { \
481                this->functionPointer_ = functionPointer; \
482            } \
483    \
484            void operator()(T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
485            { \
486                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
487            } \
488    \
489            void operator()(const T* object, const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null) \
490            { \
491                FUNCTOR_STORE_RETURNVALUE(returnvalue, (*object.*this->functionPointer_)(FUNCTOR_FUNCTION_CALL(numparams))); \
492            } \
493    \
494            void evaluateParam(unsigned int index, MultiType& param) const \
495            { \
496                FUNCTOR_EVALUATE_PARAM(numparams); \
497            } \
498    \
499            Functor::Type::Enum getType() const { return Functor::Type::ConstMember; } \
500            unsigned int getParamCount() const { return numparams; } \
501            bool hasReturnvalue() const { return returnvalue; } \
502            std::string getTypenameParam(unsigned int param) const { FUNCTOR_TYPENAME_PARAM(numparams); } \
503            std::string getTypenameReturnvalue() const { return FUNCTOR_TYPENAME_RETURN(returnvalue); } \
504    \
505            const std::type_info& getHeaderIdentifier() const \
506            { \
507                return typeid(FunctorHeaderIdentifier FUNCTOR_HEADER_IDENTIFIER_TEMPLATE_CLASSES(returnvalue, numparams)); \
508            } \
509    \
510        private: \
511            FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer_)(FUNCTOR_FUNCTION_PARAMS(numparams)) const; \
512    }; \
513    \
514    \
515    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 0) \
516    inline FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams))) \
517    { \
518        return new FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
519    } \
520    \
521    \
522    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 0) \
523    inline FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)) const) \
524    { \
525        return new FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
526    } \
527    \
528    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 1) \
529    inline FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)), O* object) \
530    { \
531        FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* functor = new FunctorMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
532        functor->setObject(object); \
533        return functor; \
534    } \
535    \
536    \
537    FUNCTOR_TEMPLATE(1, returnvalue, numparams, 1) \
538    inline FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* createFunctor(FUNCTOR_FUNCTION_RETURNVALUE(returnvalue) (T::*functionPointer)(FUNCTOR_FUNCTION_PARAMS(numparams)) const, O* object) \
539    { \
540        FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams)* functor = new FunctorConstMember##returnvalue##numparams FUNCTOR_TEMPLATE_CLASSES(1, returnvalue, numparams) (functionPointer); \
541        functor->setObject(object); \
542        return functor; \
543    }
544
545
546
547// disable annoying warning about forcing value to boolean
548#ifdef ORXONOX_COMPILER_MSVC
549#pragma warning(push)
550#pragma warning(disable:4100 4800)
551#endif
552
553#define CREATE_ALL_STATIC_FUNCTORS() \
554    CREATE_STATIC_FUNCTOR(0, 0); \
555    CREATE_STATIC_FUNCTOR(0, 1); \
556    CREATE_STATIC_FUNCTOR(0, 2); \
557    CREATE_STATIC_FUNCTOR(0, 3); \
558    CREATE_STATIC_FUNCTOR(0, 4); \
559    CREATE_STATIC_FUNCTOR(0, 5); \
560    CREATE_STATIC_FUNCTOR(1, 0); \
561    CREATE_STATIC_FUNCTOR(1, 1); \
562    CREATE_STATIC_FUNCTOR(1, 2); \
563    CREATE_STATIC_FUNCTOR(1, 3); \
564    CREATE_STATIC_FUNCTOR(1, 4); \
565    CREATE_STATIC_FUNCTOR(1, 5)
566
567
568#define CREATE_ALL_MEMBER_FUNCTORS() \
569    CREATE_MEMBER_FUNCTOR(0, 0); \
570    CREATE_MEMBER_FUNCTOR(0, 1); \
571    CREATE_MEMBER_FUNCTOR(0, 2); \
572    CREATE_MEMBER_FUNCTOR(0, 3); \
573    CREATE_MEMBER_FUNCTOR(0, 4); \
574    CREATE_MEMBER_FUNCTOR(0, 5); \
575    CREATE_MEMBER_FUNCTOR(1, 0); \
576    CREATE_MEMBER_FUNCTOR(1, 1); \
577    CREATE_MEMBER_FUNCTOR(1, 2); \
578    CREATE_MEMBER_FUNCTOR(1, 3); \
579    CREATE_MEMBER_FUNCTOR(1, 4); \
580    CREATE_MEMBER_FUNCTOR(1, 5)
581
582
583    CREATE_ALL_STATIC_FUNCTORS();
584    CREATE_ALL_MEMBER_FUNCTORS();
585}
586
587#ifdef ORXONOX_COMPILER_MSVC
588#pragma warning(pop)
589#endif
590
591#endif /* _Functor_H__ */
Note: See TracBrowser for help on using the repository browser.