Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/core/Super.h @ 8972

Last change on this file since 8972 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
RevLine 
[1679]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
[1684]29/**
[7401]30    @defgroup Super Super
31    @ingroup Class
32*/
33
34/**
[2171]35    @file
[7401]36    @ingroup Class Super
37    @brief Definition of all super-function related macros, used to call functions of the base class.
[1684]38
[7401]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.
[1684]43
[7401]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.
[1684]48
[7401]49    To add a new super-function, you have to process 4 steps:
[1684]50
[7401]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 />
[1684]61       This defines a partially specialized template that will decide if a class is "super" to another class.
[7401]62       If the check returns true, a @c SuperFunctionCaller gets created, which will be used by the @c SUPER macro.
[1684]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
[7401]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 />
[1684]68       Location: The header-file of the baseclass (Baseclass.h), below the class declaration
69*/
70
[1679]71#ifndef _Super_H__
72#define _Super_H__
73
[1684]74#include "CorePrereqs.h"
[8858]75#include "util/Output.h"
[1679]76
[1684]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        { \
[8351]94            static void superCheck() \
[1684]95            { \
[3301]96                SuperFunctionCondition<functionnumber, T, 0, templatehack2>::apply(static_cast<T*>(0)); \
[8351]97                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::superCheck(); \
[1684]98            } \
99            \
[8706]100            static void apply(void*) {} \
[2662]101            \
[8706]102            static void apply(baseclass*) \
[1684]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                { \
[2662]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                    \
[1684]114                    if (!((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_) \
115                    { \
[8858]116                        orxout(verbose, context::super) << "Added SuperFunctionCaller for " << #functionname << ": " << ClassIdentifier<T>::getIdentifier()->getName() << " <- " << ((ClassIdentifier<T>*)(*it))->getName() << endl; \
[1684]117                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_##functionname <T>; \
118                    } \
[8863]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; \
[1684]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        { \
[8351]134            static void superCheck() \
[1684]135            { \
[8351]136                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::superCheck(); \
[1684]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        {
[8351]152            static void superCheck()
[1684]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.
[3301]156                SuperFunctionCondition<functionnumber, T, 0, templatehack2>::apply(static_cast<T*>(0));
[1684]157
[8351]158                // Go go the superCheck for of next super-function (functionnumber + 1)
159                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::superCheck();
[1684]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                {
[2662]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
[1684]184                    // Check if there's not already a caller
185                    if (!((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_)
186                    {
187                        // Add the SuperFunctionCaller
[8858]188                        orxout(verbose, context::super) << "adding functionpointer to " << ((ClassIdentifier<T>*)(*it))->getName() << endl;
[1684]189                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_##functionname <T>;
190                    }
[8863]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;
[1684]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        { \
[8351]208            // The superCheck function acts like the fallback - it advances to the check for the next super-function (functionnumber + 1)
209            static void superCheck() \
[1684]210            { \
[8351]211                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::superCheck(); \
[1684]212            } \
213        };
214    */
215
[7401]216    /// SUPER-macro: Calls Parent::functionname(...) where Parent is the direct parent of @a classname
[3325]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
[1684]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
[1687]248    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
[1684]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)
[2087]260
[5929]261    #define SUPER_XMLEventPort(classname, functionname, ...) \
[2087]262        SUPER_ARGS(classname, functionname, __VA_ARGS__)
[2662]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)
[7163]278
[6524]279    #define SUPER_changedUsed(classname, functionname, ...) \
280        SUPER_NOARGS(classname, functionname)
[7163]281
[6524]282    #define SUPER_clone(classname, functionname, ...) \
283        SUPER_ARGS(classname, functionname, __VA_ARGS__)
[7163]284
[6524]285    #define SUPER_changedCarrier(classname, functionname, ...) \
286        SUPER_NOARGS(classname, functionname)
[7163]287
[6524]288    #define SUPER_changedPickedUp(classname, functionname, ...) \
289        SUPER_NOARGS(classname, functionname)
[7163]290
[1687]291    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
[1684]292
293
[1679]294namespace orxonox
295{
[1684]296    /////////////////////////////////////////////////////////////////////////////////////////////////////
297    // This code gets included by Identifier.h and every other header file that needs a super-function //
298    /////////////////////////////////////////////////////////////////////////////////////////////////////
[1679]299
[1684]300    //// Common code ////
[1679]301
[1687]302        // Base templates
303        /**
304            @brief Creates the SuperFunctionCaller if T is a child of the super-functions baseclass.
305        */
[1684]306        template <int functionnumber, class T, int templatehack1, int templatehack2>
307        struct SuperFunctionCondition
[1679]308        {
[8351]309            static void superCheck() {}
[1684]310        };
[1679]311
[1687]312        /**
313            @brief Initializes the SuperFunctionCaller-pointer with zero.
314        */
315        template <int functionnumber, class T>
316        struct SuperFunctionInitialization
317        {
[8706]318            static void initialize(ClassIdentifier<T>*) {}
[1687]319        };
[1679]320
[1687]321        /**
322            @brief Deletes the SuperFunctionCaller.
323        */
324        template <int functionnumber, class T>
325        struct SuperFunctionDestruction
326        {
[8706]327            static void destroy(ClassIdentifier<T>*) {}
[1687]328        };
329
330
[1684]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            { \
[8351]344                static void superCheck() \
[1684]345                { \
[8351]346                    SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::superCheck(); \
[1684]347                } \
348            }; \
349            \
[2662]350            class _CoreExport SuperFunctionCaller_##functionname \
351            { \
352                public: \
353                    virtual void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) = 0; \
354                    virtual ~SuperFunctionCaller_##functionname () {} \
[8863]355                    virtual Identifier* getParentIdentifier() const = 0; \
[2662]356            }; \
357            \
[1687]358            template <class T> \
[2662]359            class SuperFunctionClassCaller_purevirtualfallback_##functionname : public SuperFunctionCaller_##functionname \
360            { \
361                public: \
362                    inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) \
363                    { \
364                    } \
[8863]365                    \
366                    Identifier* getParentIdentifier() const \
367                    { \
368                        return ClassIdentifier<T>::getIdentifier(); \
369                    } \
[2662]370            }; \
371            \
372            template <class T> \
[1687]373            struct SuperFunctionInitialization<functionnumber, T> \
374            { \
375                static void initialize(ClassIdentifier<T>* identifier) \
376                { \
[2662]377                    identifier->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_purevirtualfallback_##functionname <T>; \
378                    identifier->bSuperFunctionCaller_##functionname##_isFallback_ = true; \
[1687]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            \
[1684]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                    } \
[8863]414                    \
415                    Identifier* getParentIdentifier() const \
416                    { \
417                        return ClassIdentifier<T>::getIdentifier(); \
418                    } \
[1684]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
[8351]438            static void superCheck()
[1679]439            {
[1684]440                // Calls the condition-check of the next super-function (functionnumber + 1)
[8351]441                SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::superCheck();
[1679]442            }
[1684]443        };
444
[2662]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 () {}
[8863]452                virtual Identifier* getParentIdentifier() const = 0;
[2662]453        };
454
455        // Fallback if the base is pure virtual
[1687]456        template <class T>
[2662]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                }
[8863]464
465                Identifier* getParentIdentifier() const
466                {
467                    return ClassIdentifier<T>::getIdentifier();
468                }
[2662]469        };
470
471        // Initializes the SuperFunctionCaller-pointer with a fallback caller in case the base function is pure virtual
472        template <class T>
[1687]473        struct SuperFunctionInitialization<functionnumber, T>
474        {
475            static void initialize(ClassIdentifier<T>* identifier)
476            {
[2662]477                identifier->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_purevirtualfallback_##functionname <T>;
478                identifier->bSuperFunctionCaller_##functionname##_isFallback_ = true;
[1687]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
[1684]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                }
[8863]512
513                Identifier* getParentIdentifier() const
514                {
515                    return ClassIdentifier<T>::getIdentifier();
516                }
[1684]517        }
518    */
519
[1687]520
[1684]521    //// Execute the code for each super-function ////
[1687]522
523        // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
[1736]524        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(0, XMLPort, true, Element& xmlelement, XMLPort::Mode mode)
[1684]525            (xmlelement, mode)
526        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
527
[1736]528        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(1, tick, true, float dt)
[1684]529            (dt)
530        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
531
[1736]532        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(2, changedActivity, false)
[1684]533            ()
534        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
535
[1736]536        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(3, changedVisibility, false)
[1684]537            ()
538        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
[2087]539
[5929]540        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(4, XMLEventPort, true, Element& xmlelement, XMLPort::Mode mode)
541            (xmlelement, mode)
[2087]542        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
[2662]543
544        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(5, changedScale, false)
545            ()
546        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
547
[5929]548        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(6, changedOwner, false)
[2662]549            ()
550        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
551
[5929]552        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(7, changedOverlayGroup, false)
[2662]553            ()
554        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
555
[5929]556        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(8, changedName, false)
[2662]557            ()
558        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
559
[5929]560        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(9, changedGametype, false)
[2662]561            ()
562        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
[7163]563
[6524]564        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(10, changedUsed, false)
565            ()
566        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
567
[8866]568        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(11, clone, true, OrxonoxClass*& item)
[6524]569            (item)
570        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
[7163]571
[6524]572        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(12, changedCarrier, false)
573            ()
574        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
[7163]575
[6524]576        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(13, changedPickedUp, false)
577            ()
578        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
579
[1687]580        // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
[1684]581
[1679]582}
583
584#else /* _Super_H__ */
[1684]585  #ifdef SUPER_INTRUSIVE_DECLARATION_INCLUDE
[1679]586
[1684]587//////////////////////////////////////////////////////////////////////////
588// This code gets included within the declaration of ClassIdentifier<T> //
589//////////////////////////////////////////////////////////////////////////
[1679]590
[1684]591//// Common code ////
[1679]592
[1684]593    private:
[1687]594
[1684]595        template <int functionnumber, class TT, int templatehack1, int templatehack2>
596        friend struct SuperFunctionCondition;
[1679]597
[1684]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        {
[8351]602            SuperFunctionCondition<0, T, 0, 0>::superCheck();
[1684]603        }
[1679]604
605
[1684]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) \
[2662]615            SuperFunctionCaller_##functionname * superFunctionCaller_##functionname##_; \
616            bool bSuperFunctionCaller_##functionname##_isFallback_
[1684]617        #endif
618
619
620//// Execute the code for each super-function ////
[1687]621
622    // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
[1684]623    SUPER_INTRUSIVE_DECLARATION(XMLPort);
624    SUPER_INTRUSIVE_DECLARATION(tick);
625    SUPER_INTRUSIVE_DECLARATION(changedActivity);
626    SUPER_INTRUSIVE_DECLARATION(changedVisibility);
[5929]627    SUPER_INTRUSIVE_DECLARATION(XMLEventPort);
[2662]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);
[6524]633    SUPER_INTRUSIVE_DECLARATION(changedUsed);
634    SUPER_INTRUSIVE_DECLARATION(clone);
635    SUPER_INTRUSIVE_DECLARATION(changedCarrier);
636    SUPER_INTRUSIVE_DECLARATION(changedPickedUp);
[1687]637    // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
[1684]638
639
640    #undef SUPER_INTRUSIVE_DECLARATION_INCLUDE
641  #endif /* SUPER_INTRUSIVE_DECLARATION_INCLUDE */
[1679]642#endif /* _Super_H__ */
Note: See TracBrowser for help on using the repository browser.