Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gamecontent/src/libraries/core/Super.h @ 9223

Last change on this file since 9223 was 8866, checked in by dafrick, 13 years ago

Moved clone base method into Pickupable to avoid ambiguity.

  • Property svn:eol-style set to native
File size: 28.9 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 */
28
29/**
30    @defgroup Super Super
31    @ingroup Class
32*/
33
34/**
35    @file
36    @ingroup Class Super
37    @brief Definition of all super-function related macros, used to call functions of the base class.
38
39    This file defines all macros needed to add a new "super-function". If you add
40    a super-function, you can call <tt>SUPER(myclass, functionname, arguments)</tt>
41    inside your code and the function of the parent-class gets called. This is comparable
42    to <tt>super.functionname(arguments)</tt> in Java or other languages.
43
44    This works only with virtual functions that return nothing (@c void) and belong to
45    classes that have an @ref orxonox::Identifier "Identifier". Arguments however are
46    supported, there's no limitation for their number and type, except that the type has
47    to be known in Super.h.
48
49    To add a new super-function, you have to process 4 steps:
50
51    -# Add a new @c SUPER macro <br />
52       This allows you to call the super-function in your code. <br />
53       Location: This file (Super.h), marked with "--> HERE <--" comments (1/3)
54    -# Call the @c SUPER_FUNCTION_GLOBAL_DECLARATION_PART1/2 macros. <br />
55       This defines some global classes and templates, needed to create and call the super-functions. <br />
56       Location: This file (Super.h), marked with "--> HERE <--" comments (2/3)
57    -# Call the @c SUPER_INTRUSIVE_DECLARATION macro. <br />
58       This will be included into the declaration of @c ClassIdentifier<T>. <br />
59       Location: This file (Super.h), marked with "--> HERE <--" comments (3/3)
60    -# Call the @c SUPER_FUNCTION macro. <br />
61       This defines a partially specialized template that will decide if a class is "super" to another class.
62       If the check returns true, a @c SuperFunctionCaller gets created, which will be used by the @c SUPER macro.
63       You have to add this into the header-file of the baseclass of the super-function (the class that first
64       implements the function), below the class declaration. You can't call it directly in this file, because
65       otherwise you had to include the headerfile right here, which would cause some ugly back-dependencies,
66       include loops and slower compilation. <br />
67       Dont forget to include Super.h in the header-file. <br />
68       Location: The header-file of the baseclass (Baseclass.h), below the class declaration
69*/
70
71#ifndef _Super_H__
72#define _Super_H__
73
74#include "CorePrereqs.h"
75#include "util/Output.h"
76
77///////////////////////
78// Macro definitions //
79///////////////////////
80
81//// Common macros ////
82
83    /**
84        @brief Declares a new super-function by creating a specialized template. Add this below the class declaration of the baseclass.
85        @param functionnumber Each super-function needs a unique number, starting with zero, increasing by one
86        @param baseclass The baseclass of the super-function (~the root)
87        @param functionname The name of the super-function
88        @param purevirtualbase "true" if the function is pure virtual in the baseclass, "false" if the function is implemented (without "")
89    */
90    #define SUPER_FUNCTION(functionnumber, baseclass, functionname, purevirtualbase) \
91        template <class T, int templatehack2> \
92        struct SuperFunctionCondition<functionnumber, T, 0, templatehack2> \
93        { \
94            static void superCheck() \
95            { \
96                SuperFunctionCondition<functionnumber, T, 0, templatehack2>::apply(static_cast<T*>(0)); \
97                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::superCheck(); \
98            } \
99            \
100            static void apply(void*) {} \
101            \
102            static void apply(baseclass*) \
103            { \
104                ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier(); \
105                for (std::set<const Identifier*>::iterator it = identifier->getDirectChildrenIntern().begin(); it != identifier->getDirectChildrenIntern().end(); ++it) \
106                { \
107                    if (((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ && ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_) \
108                    { \
109                        delete ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_; \
110                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = 0; \
111                        ((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ = false; \
112                    } \
113                    \
114                    if (!((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_) \
115                    { \
116                        orxout(verbose, context::super) << "Added SuperFunctionCaller for " << #functionname << ": " << ClassIdentifier<T>::getIdentifier()->getName() << " <- " << ((ClassIdentifier<T>*)(*it))->getName() << endl; \
117                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_##functionname <T>; \
118                    } \
119                    else if (((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_->getParentIdentifier() != ClassIdentifier<T>::getIdentifier()) \
120                        orxout(internal_warning, context::super) << "SuperFunctionCaller for " << #functionname << " in " << ((ClassIdentifier<T>*)(*it))->getName() << " calls function of " << ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_->getParentIdentifier()->getName() << " but " << ClassIdentifier<T>::getIdentifier()->getName() << " is also possible (do you use multiple inheritance?)" << endl; \
121                } \
122            } \
123        }; \
124        \
125        SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND##purevirtualbase(functionnumber, baseclass)
126
127    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND0(functionnumber, baseclass) SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDfalse(functionnumber, baseclass)
128    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND1(functionnumber, baseclass) SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDtrue(functionnumber, baseclass)
129    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDfalse(functionnumber, baseclass)
130    #define SUPER_FUNCTION_PUREVIRTUAL_WORKAROUNDtrue(functionnumber, baseclass) \
131        template <int templatehack2> \
132        struct SuperFunctionCondition<functionnumber, baseclass, 0, templatehack2> \
133        { \
134            static void superCheck() \
135            { \
136                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::superCheck(); \
137            } \
138        };
139
140
141    /*
142    //// Comments about the macro ////
143
144        // Partially specialized template (templatehack is now specialized too).
145        //
146        // This ensures the compiler takes THIS template if the header-file of the super-function
147        // is included. In any other case, the compiler just uses the fallback template which is
148        // defined in this file.
149        template <class T, templatehack2>
150        struct SuperFunctionCondition<functionnumber, T, 0, templatehack2>
151        {
152            static void superCheck()
153            {
154                // This call to the apply-function is the whole check. By calling the function with
155                // a T* pointer, the right function get's called.
156                SuperFunctionCondition<functionnumber, T, 0, templatehack2>::apply(static_cast<T*>(0));
157
158                // Go go the superCheck for of next super-function (functionnumber + 1)
159                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::superCheck();
160            }
161
162            // This function gets called if T is not a child of the baseclass.
163            // The function does nothing.
164            static void apply(void* temp) {}
165
166            // This function gets called if T is a child of the baseclass and can therefore be converted.
167            // The function adds a SuperFunctionCaller to the Identifier of all subclasses of T.
168            static void apply(baseclass* temp)
169            {
170                ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier();
171
172                // Iterate through all children
173                for (std::set<const Identifier*>::iterator it = identifier->getDirectChildrenIntern().begin(); it != identifier->getDirectChildrenIntern().end(); ++it)
174                {
175                    // Check if the caller is a fallback-caller
176                    if (((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ && ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_)
177                    {
178                        // Delete the fallback caller an prepare to get a real caller
179                        delete ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_;
180                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = 0;
181                        ((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ = false;
182                    }
183
184                    // Check if there's not already a caller
185                    if (!((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_)
186                    {
187                        // Add the SuperFunctionCaller
188                        orxout(verbose, context::super) << "adding functionpointer to " << ((ClassIdentifier<T>*)(*it))->getName() << endl;
189                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_##functionname <T>;
190                    }
191
192                    // If there is already a caller, but for another parent, print a warning
193                    else if (((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_->getParentIdentifier() != ClassIdentifier<T>::getIdentifier())
194                        orxout(internal_warning, context::super) << "SuperFunctionCaller for " << #functionname << " in " << ((ClassIdentifier<T>*)(*it))->getName() << " calls function of " << ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_->getParentIdentifier()->getName() << " but " << ClassIdentifier<T>::getIdentifier()->getName() << " is also possible (do you use multiple inheritance?)" << endl;
195                }
196            }
197        };
198        SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND##purevirtualbase
199
200
201        // The following piece of code is only added if purevirtualbase = true
202
203        // Explicit specialization of the Condition template for the baseclass to avoid
204        // errors if the function is pure virtual in the baseclass.
205        template <int templatehack2> \
206        struct SuperFunctionCondition<functionnumber, baseclass, 0, templatehack2> \
207        { \
208            // The superCheck function acts like the fallback - it advances to the check for the next super-function (functionnumber + 1)
209            static void superCheck() \
210            { \
211                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::superCheck(); \
212            } \
213        };
214    */
215
216    /// SUPER-macro: Calls Parent::functionname(...) where Parent is the direct parent of @a classname
217    #ifdef ORXONOX_COMPILER_MSVC
218        #define SUPER(classname, functionname, ...) \
219            __super::functionname(__VA_ARGS__)
220    #else
221        #define SUPER(classname, functionname, ...) \
222            SUPER_##functionname(classname, functionname, __VA_ARGS__)
223    #endif
224
225    // helper macro: for functions without arguments
226    #define SUPER_NOARGS(classname, functionname) \
227        (*ClassIdentifier<classname>::getIdentifier()->superFunctionCaller_##functionname##_)(this)
228
229    // helper macro: for functions with arguments
230    #define SUPER_ARGS(classname, functionname, ...) \
231        (*ClassIdentifier<classname>::getIdentifier()->superFunctionCaller_##functionname##_)(this, __VA_ARGS__)
232
233
234//// Function-specific macros ////
235
236    /*
237        Add a macro for each super-function
238
239        Example (no arguments):
240        #define SUPER_myfunction(classname, functionname, ...) \
241            SUPER_NOARGS(classname, functionname)
242
243        Example (with arguments):
244        #define SUPER_myfunction(classname, functionname, ...) \
245            SUPER_ARGS(classname, functionname, __VA_ARGS__)
246    */
247
248    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
249    #define SUPER_XMLPort(classname, functionname, ...) \
250        SUPER_ARGS(classname, functionname, __VA_ARGS__)
251
252    #define SUPER_tick(classname, functionname, ...) \
253        SUPER_ARGS(classname, functionname, __VA_ARGS__)
254
255    #define SUPER_changedActivity(classname, functionname, ...) \
256        SUPER_NOARGS(classname, functionname)
257
258    #define SUPER_changedVisibility(classname, functionname, ...) \
259        SUPER_NOARGS(classname, functionname)
260
261    #define SUPER_XMLEventPort(classname, functionname, ...) \
262        SUPER_ARGS(classname, functionname, __VA_ARGS__)
263
264    #define SUPER_changedScale(classname, functionname, ...) \
265        SUPER_NOARGS(classname, functionname)
266
267    #define SUPER_changedOwner(classname, functionname, ...) \
268        SUPER_NOARGS(classname, functionname)
269
270    #define SUPER_changedOverlayGroup(classname, functionname, ...) \
271        SUPER_NOARGS(classname, functionname)
272
273    #define SUPER_changedName(classname, functionname, ...) \
274        SUPER_NOARGS(classname, functionname)
275
276    #define SUPER_changedGametype(classname, functionname, ...) \
277        SUPER_NOARGS(classname, functionname)
278
279    #define SUPER_changedUsed(classname, functionname, ...) \
280        SUPER_NOARGS(classname, functionname)
281
282    #define SUPER_clone(classname, functionname, ...) \
283        SUPER_ARGS(classname, functionname, __VA_ARGS__)
284
285    #define SUPER_changedCarrier(classname, functionname, ...) \
286        SUPER_NOARGS(classname, functionname)
287
288    #define SUPER_changedPickedUp(classname, functionname, ...) \
289        SUPER_NOARGS(classname, functionname)
290
291    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
292
293
294namespace orxonox
295{
296    /////////////////////////////////////////////////////////////////////////////////////////////////////
297    // This code gets included by Identifier.h and every other header file that needs a super-function //
298    /////////////////////////////////////////////////////////////////////////////////////////////////////
299
300    //// Common code ////
301
302        // Base templates
303        /**
304            @brief Creates the SuperFunctionCaller if T is a child of the super-functions baseclass.
305        */
306        template <int functionnumber, class T, int templatehack1, int templatehack2>
307        struct SuperFunctionCondition
308        {
309            static void superCheck() {}
310        };
311
312        /**
313            @brief Initializes the SuperFunctionCaller-pointer with zero.
314        */
315        template <int functionnumber, class T>
316        struct SuperFunctionInitialization
317        {
318            static void initialize(ClassIdentifier<T>*) {}
319        };
320
321        /**
322            @brief Deletes the SuperFunctionCaller.
323        */
324        template <int functionnumber, class T>
325        struct SuperFunctionDestruction
326        {
327            static void destroy(ClassIdentifier<T>*) {}
328        };
329
330
331    //// Function-specific code ////
332
333        /**
334            @brief Creates the needed objects and templates to call a super-function.
335            @param functionnumber Each super-function needs a unique number, starting with zero, increasing by one
336            @param functionname The name of the super-function
337            @param hasarguments "false" if the function doesn't take any arguments, "true" if it does (without "")
338            @param ... Variadic: If the function takes arguments, add them here with type and name. Example: int myvalue, float myothervalue
339        */
340        #define SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(functionnumber, functionname, hasarguments, ...) \
341            template <class T, int templatehack1, int templatehack2> \
342            struct SuperFunctionCondition<functionnumber, T, templatehack1, templatehack2> \
343            { \
344                static void superCheck() \
345                { \
346                    SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::superCheck(); \
347                } \
348            }; \
349            \
350            class _CoreExport SuperFunctionCaller_##functionname \
351            { \
352                public: \
353                    virtual void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) = 0; \
354                    virtual ~SuperFunctionCaller_##functionname () {} \
355                    virtual Identifier* getParentIdentifier() const = 0; \
356            }; \
357            \
358            template <class T> \
359            class SuperFunctionClassCaller_purevirtualfallback_##functionname : public SuperFunctionCaller_##functionname \
360            { \
361                public: \
362                    inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) \
363                    { \
364                    } \
365                    \
366                    Identifier* getParentIdentifier() const \
367                    { \
368                        return ClassIdentifier<T>::getIdentifier(); \
369                    } \
370            }; \
371            \
372            template <class T> \
373            struct SuperFunctionInitialization<functionnumber, T> \
374            { \
375                static void initialize(ClassIdentifier<T>* identifier) \
376                { \
377                    identifier->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_purevirtualfallback_##functionname <T>; \
378                    identifier->bSuperFunctionCaller_##functionname##_isFallback_ = true; \
379                    SuperFunctionInitialization<functionnumber + 1, T>::initialize(identifier); \
380                } \
381            }; \
382            \
383            template <class T> \
384            struct SuperFunctionDestruction<functionnumber, T> \
385            { \
386                static void destroy(ClassIdentifier<T>* identifier) \
387                { \
388                    if (identifier->superFunctionCaller_##functionname##_) \
389                        delete identifier->superFunctionCaller_##functionname##_; \
390                    SuperFunctionDestruction<functionnumber + 1, T>::destroy(identifier); \
391                } \
392            }; \
393            \
394            template <class T> \
395            class SuperFunctionClassCaller_##functionname : public SuperFunctionCaller_##functionname \
396            { \
397                public: \
398                    inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) \
399                    { \
400                        (dynamic_cast<T*>(object))->T:: functionname
401
402        /*
403            JUST ADD THE FUNCTION ARGUMENTS BETWEEN BOTH MACROS, ENCLOSED BY BRACKETS
404            EXAMPLE:
405
406              SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(0, myfunction, true, int myvalue, float myothervalue) <-- !!! DONT ADD A SEMICOLON HERE !!!
407                (myvalue, myothervalue)
408              SUPER_FUNCTION_GLOBAL_DECLARATION_PART2
409        */
410
411        #define SUPER_FUNCTION_GLOBAL_DECLARATION_PART2 \
412                                                        ; \
413                    } \
414                    \
415                    Identifier* getParentIdentifier() const \
416                    { \
417                        return ClassIdentifier<T>::getIdentifier(); \
418                    } \
419            };
420
421        #define SUPER_CALL_ARGUMENTSfalse(...) OrxonoxClass* object
422        #define SUPER_CALL_ARGUMENTS0(...)     OrxonoxClass* object
423        #define SUPER_CALL_ARGUMENTStrue(...) OrxonoxClass* object, __VA_ARGS__
424        #define SUPER_CALL_ARGUMENTS1(...)    OrxonoxClass* object, __VA_ARGS__
425
426
427    /*
428    //// COMMENTS ABOUT THE MACRO ////
429
430        // Partially specialized template (templatehack not yet specialized, this
431        // will be done by the real condition in the header-file of the super-function)
432        // Only used as fallback
433        template <class T, int templatehack1, int templatehack2>
434        struct SuperFunctionCondition<functionnumber, T, templatehack1, templatehack2>
435        {
436            // If this function gets called, the header-file of the super function is not
437            // included, so this fallback template (templatehack not specialized) is used
438            static void superCheck()
439            {
440                // Calls the condition-check of the next super-function (functionnumber + 1)
441                SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::superCheck();
442            }
443        };
444
445        // Baseclass of the super-function caller. The real call will be done by a
446        // templatized subclass through the virtual () operator.
447        class _CoreExport SuperFunctionCaller_##functionname
448        {
449            public:
450                virtual void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) = 0;
451                virtual ~SuperFunctionCaller_##functionname () {}
452                virtual Identifier* getParentIdentifier() const = 0;
453        };
454
455        // Fallback if the base is pure virtual
456        template <class T>
457        class SuperFunctionClassCaller_purevirtualfallback_##functionname : public SuperFunctionCaller_##functionname
458        {
459            public:
460                // Fallback does nothing
461                inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) )
462                {
463                }
464
465                Identifier* getParentIdentifier() const
466                {
467                    return ClassIdentifier<T>::getIdentifier();
468                }
469        };
470
471        // Initializes the SuperFunctionCaller-pointer with a fallback caller in case the base function is pure virtual
472        template <class T>
473        struct SuperFunctionInitialization<functionnumber, T>
474        {
475            static void initialize(ClassIdentifier<T>* identifier)
476            {
477                identifier->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_purevirtualfallback_##functionname <T>;
478                identifier->bSuperFunctionCaller_##functionname##_isFallback_ = true;
479
480                // Calls the initialization of the next super-function (functionnumber + 1)
481                SuperFunctionInitialization<functionnumber + 1, T>::initialize(identifier);
482            }
483        };
484
485        // Deletes the SuperFunctionCaller.
486        template <class T>
487        struct SuperFunctionDestruction<functionnumber, T>
488        {
489            static void destroy(ClassIdentifier<T>* identifier)
490            {
491                if (identifier->superFunctionCaller_##functionname##_)
492                    delete identifier->superFunctionCaller_##functionname##_;
493
494                // Calls the destruction of the next super-function (functionnumber + 1)
495                SuperFunctionDestruction<functionnumber + 1, T>::destroy(identifier);
496            }
497        };
498
499        // The real super-function caller: Calls T::functionname()
500        // T should be the parent, but this will be done by the spezialized condition template
501        template <class T>
502        class SuperFunctionClassCaller_##functionname : public SuperFunctionCaller_##functionname
503        {
504            public:
505                // @brief Calls the function.
506                // @param object The object to call the function on
507                // @param ... The arguments of the function
508                inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) )
509                {
510                    (dynamic_cast<T*>(object))->T:: functionname ( Call the function with it's arguments );
511                }
512
513                Identifier* getParentIdentifier() const
514                {
515                    return ClassIdentifier<T>::getIdentifier();
516                }
517        }
518    */
519
520
521    //// Execute the code for each super-function ////
522
523        // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
524        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(0, XMLPort, true, Element& xmlelement, XMLPort::Mode mode)
525            (xmlelement, mode)
526        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
527
528        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(1, tick, true, float dt)
529            (dt)
530        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
531
532        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(2, changedActivity, false)
533            ()
534        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
535
536        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(3, changedVisibility, false)
537            ()
538        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
539
540        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(4, XMLEventPort, true, Element& xmlelement, XMLPort::Mode mode)
541            (xmlelement, mode)
542        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
543
544        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(5, changedScale, false)
545            ()
546        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
547
548        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(6, changedOwner, false)
549            ()
550        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
551
552        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(7, changedOverlayGroup, false)
553            ()
554        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
555
556        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(8, changedName, false)
557            ()
558        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
559
560        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(9, changedGametype, false)
561            ()
562        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
563
564        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(10, changedUsed, false)
565            ()
566        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
567
568        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(11, clone, true, OrxonoxClass*& item)
569            (item)
570        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
571
572        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(12, changedCarrier, false)
573            ()
574        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
575
576        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(13, changedPickedUp, false)
577            ()
578        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
579
580        // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
581
582}
583
584#else /* _Super_H__ */
585  #ifdef SUPER_INTRUSIVE_DECLARATION_INCLUDE
586
587//////////////////////////////////////////////////////////////////////////
588// This code gets included within the declaration of ClassIdentifier<T> //
589//////////////////////////////////////////////////////////////////////////
590
591//// Common code ////
592
593    private:
594
595        template <int functionnumber, class TT, int templatehack1, int templatehack2>
596        friend struct SuperFunctionCondition;
597
598        // Creates the super-function-callers by calling the first SuperFunctionCondition check
599        // This get's called within the initialization of an Identifier
600        virtual void createSuperFunctionCaller() const
601        {
602            SuperFunctionCondition<0, T, 0, 0>::superCheck();
603        }
604
605
606//// Function-specific code ////
607
608    public:
609        /**
610            @brief Adds a pointer to the SuperFunctionCaller as a member of ClassIdentifier.
611            @param functionname The name of the super-function
612        */
613        #ifndef SUPER_INTRUSIVE_DECLARATION
614          #define SUPER_INTRUSIVE_DECLARATION(functionname) \
615            SuperFunctionCaller_##functionname * superFunctionCaller_##functionname##_; \
616            bool bSuperFunctionCaller_##functionname##_isFallback_
617        #endif
618
619
620//// Execute the code for each super-function ////
621
622    // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
623    SUPER_INTRUSIVE_DECLARATION(XMLPort);
624    SUPER_INTRUSIVE_DECLARATION(tick);
625    SUPER_INTRUSIVE_DECLARATION(changedActivity);
626    SUPER_INTRUSIVE_DECLARATION(changedVisibility);
627    SUPER_INTRUSIVE_DECLARATION(XMLEventPort);
628    SUPER_INTRUSIVE_DECLARATION(changedScale);
629    SUPER_INTRUSIVE_DECLARATION(changedOwner);
630    SUPER_INTRUSIVE_DECLARATION(changedOverlayGroup);
631    SUPER_INTRUSIVE_DECLARATION(changedName);
632    SUPER_INTRUSIVE_DECLARATION(changedGametype);
633    SUPER_INTRUSIVE_DECLARATION(changedUsed);
634    SUPER_INTRUSIVE_DECLARATION(clone);
635    SUPER_INTRUSIVE_DECLARATION(changedCarrier);
636    SUPER_INTRUSIVE_DECLARATION(changedPickedUp);
637    // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
638
639
640    #undef SUPER_INTRUSIVE_DECLARATION_INCLUDE
641  #endif /* SUPER_INTRUSIVE_DECLARATION_INCLUDE */
642#endif /* _Super_H__ */
Note: See TracBrowser for help on using the repository browser.