Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/lastmanstanding2/src/libraries/core/Super.h @ 7988

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

merged doc branch back to trunk

  • 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 */
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
76#include "util/Debug.h"
77#include "Event.h"
78
79///////////////////////
80// Macro definitions //
81///////////////////////
82
83//// Common macros ////
84
85    /**
86        @brief Declares a new super-function by creating a specialized template. Add this below the class declaration of the baseclass.
87        @param functionnumber Each super-function needs a unique number, starting with zero, increasing by one
88        @param baseclass The baseclass of the super-function (~the root)
89        @param functionname The name of the super-function
90        @param purevirtualbase "true" if the function is pure virtual in the baseclass, "false" if the function is implemented (without "")
91    */
92    #define SUPER_FUNCTION(functionnumber, baseclass, functionname, purevirtualbase) \
93        template <class T, int templatehack2> \
94        struct SuperFunctionCondition<functionnumber, T, 0, templatehack2> \
95        { \
96            static void check() \
97            { \
98                SuperFunctionCondition<functionnumber, T, 0, templatehack2>::apply(static_cast<T*>(0)); \
99                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::check(); \
100            } \
101            \
102            static void apply(void* temp) {} \
103            \
104            static void apply(baseclass* temp) \
105            { \
106                ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier(); \
107                for (std::set<const Identifier*>::iterator it = identifier->getDirectChildrenIntern().begin(); it != identifier->getDirectChildrenIntern().end(); ++it) \
108                { \
109                    if (((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ && ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_) \
110                    { \
111                        delete ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_; \
112                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = 0; \
113                        ((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ = false; \
114                    } \
115                    \
116                    if (!((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_) \
117                    { \
118                        COUT(5) << "Added SuperFunctionCaller for " << #functionname << ": " << ClassIdentifier<T>::getIdentifier()->getName() << " <- " << ((ClassIdentifier<T>*)(*it))->getName() << std::endl; \
119                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_##functionname <T>; \
120                    } \
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 check() \
135            { \
136                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::check(); \
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 check()
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 check for of next super-function (functionnumber + 1)
159                SuperFunctionCondition<functionnumber + 1, T, 0, templatehack2>::check();
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                        COUT(5) << "adding functionpointer to " << ((ClassIdentifier<T>*)(*it))->getName() << std::endl;
189                        ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_##functionname <T>;
190                    }
191                }
192            }
193        };
194        SUPER_FUNCTION_PUREVIRTUAL_WORKAROUND##purevirtualbase
195
196
197        // The following piece of code is only added if purevirtualbase = true
198
199        // Explicit specialization of the Condition template for the baseclass to avoid
200        // errors if the function is pure virtual in the baseclass.
201        template <int templatehack2> \
202        struct SuperFunctionCondition<functionnumber, baseclass, 0, templatehack2> \
203        { \
204            // The check function acts like the fallback - it advances to the check for the next super-function (functionnumber + 1)
205            static void check() \
206            { \
207                SuperFunctionCondition<functionnumber + 1, baseclass, 0, templatehack2>::check(); \
208            } \
209        };
210    */
211
212    /// SUPER-macro: Calls Parent::functionname(...) where Parent is the direct parent of @a classname
213    #ifdef ORXONOX_COMPILER_MSVC
214        #define SUPER(classname, functionname, ...) \
215            __super::functionname(__VA_ARGS__)
216    #else
217        #define SUPER(classname, functionname, ...) \
218            SUPER_##functionname(classname, functionname, __VA_ARGS__)
219    #endif
220
221    // helper macro: for functions without arguments
222    #define SUPER_NOARGS(classname, functionname) \
223        (*ClassIdentifier<classname>::getIdentifier()->superFunctionCaller_##functionname##_)(this)
224
225    // helper macro: for functions with arguments
226    #define SUPER_ARGS(classname, functionname, ...) \
227        (*ClassIdentifier<classname>::getIdentifier()->superFunctionCaller_##functionname##_)(this, __VA_ARGS__)
228
229
230//// Function-specific macros ////
231
232    /*
233        Add a macro for each super-function
234
235        Example (no arguments):
236        #define SUPER_myfunction(classname, functionname, ...) \
237            SUPER_NOARGS(classname, functionname)
238
239        Example (with arguments):
240        #define SUPER_myfunction(classname, functionname, ...) \
241            SUPER_ARGS(classname, functionname, __VA_ARGS__)
242    */
243
244    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
245    #define SUPER_XMLPort(classname, functionname, ...) \
246        SUPER_ARGS(classname, functionname, __VA_ARGS__)
247
248    #define SUPER_tick(classname, functionname, ...) \
249        SUPER_ARGS(classname, functionname, __VA_ARGS__)
250
251    #define SUPER_changedActivity(classname, functionname, ...) \
252        SUPER_NOARGS(classname, functionname)
253
254    #define SUPER_changedVisibility(classname, functionname, ...) \
255        SUPER_NOARGS(classname, functionname)
256
257    #define SUPER_XMLEventPort(classname, functionname, ...) \
258        SUPER_ARGS(classname, functionname, __VA_ARGS__)
259
260    #define SUPER_changedScale(classname, functionname, ...) \
261        SUPER_NOARGS(classname, functionname)
262
263    #define SUPER_changedOwner(classname, functionname, ...) \
264        SUPER_NOARGS(classname, functionname)
265
266    #define SUPER_changedOverlayGroup(classname, functionname, ...) \
267        SUPER_NOARGS(classname, functionname)
268
269    #define SUPER_changedName(classname, functionname, ...) \
270        SUPER_NOARGS(classname, functionname)
271
272    #define SUPER_changedGametype(classname, functionname, ...) \
273        SUPER_NOARGS(classname, functionname)
274
275    #define SUPER_changedUsed(classname, functionname, ...) \
276        SUPER_NOARGS(classname, functionname)
277
278    #define SUPER_clone(classname, functionname, ...) \
279        SUPER_ARGS(classname, functionname, __VA_ARGS__)
280
281    #define SUPER_changedCarrier(classname, functionname, ...) \
282        SUPER_NOARGS(classname, functionname)
283
284    #define SUPER_changedPickedUp(classname, functionname, ...) \
285        SUPER_NOARGS(classname, functionname)
286
287    // (1/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
288
289
290namespace orxonox
291{
292    /////////////////////////////////////////////////////////////////////////////////////////////////////
293    // This code gets included by Identifier.h and every other header file that needs a super-function //
294    /////////////////////////////////////////////////////////////////////////////////////////////////////
295
296    //// Common code ////
297
298        // Base templates
299        /**
300            @brief Creates the SuperFunctionCaller if T is a child of the super-functions baseclass.
301        */
302        template <int functionnumber, class T, int templatehack1, int templatehack2>
303        struct SuperFunctionCondition
304        {
305            static void check() {}
306        };
307
308        /**
309            @brief Initializes the SuperFunctionCaller-pointer with zero.
310        */
311        template <int functionnumber, class T>
312        struct SuperFunctionInitialization
313        {
314            static void initialize(ClassIdentifier<T>* identifier) {}
315        };
316
317        /**
318            @brief Deletes the SuperFunctionCaller.
319        */
320        template <int functionnumber, class T>
321        struct SuperFunctionDestruction
322        {
323            static void destroy(ClassIdentifier<T>* identifier) {}
324        };
325
326
327    //// Function-specific code ////
328
329        /**
330            @brief Creates the needed objects and templates to call a super-function.
331            @param functionnumber Each super-function needs a unique number, starting with zero, increasing by one
332            @param functionname The name of the super-function
333            @param hasarguments "false" if the function doesn't take any arguments, "true" if it does (without "")
334            @param ... Variadic: If the function takes arguments, add them here with type and name. Example: int myvalue, float myothervalue
335        */
336        #define SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(functionnumber, functionname, hasarguments, ...) \
337            template <class T, int templatehack1, int templatehack2> \
338            struct SuperFunctionCondition<functionnumber, T, templatehack1, templatehack2> \
339            { \
340                static void check() \
341                { \
342                    SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::check(); \
343                } \
344            }; \
345            \
346            class _CoreExport SuperFunctionCaller_##functionname \
347            { \
348                public: \
349                    virtual void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) = 0; \
350                    virtual ~SuperFunctionCaller_##functionname () {} \
351            }; \
352            \
353            template <class T> \
354            class SuperFunctionClassCaller_purevirtualfallback_##functionname : public SuperFunctionCaller_##functionname \
355            { \
356                public: \
357                    inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) \
358                    { \
359                    } \
360            }; \
361            \
362            template <class T> \
363            struct SuperFunctionInitialization<functionnumber, T> \
364            { \
365                static void initialize(ClassIdentifier<T>* identifier) \
366                { \
367                    identifier->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_purevirtualfallback_##functionname <T>; \
368                    identifier->bSuperFunctionCaller_##functionname##_isFallback_ = true; \
369                    SuperFunctionInitialization<functionnumber + 1, T>::initialize(identifier); \
370                } \
371            }; \
372            \
373            template <class T> \
374            struct SuperFunctionDestruction<functionnumber, T> \
375            { \
376                static void destroy(ClassIdentifier<T>* identifier) \
377                { \
378                    if (identifier->superFunctionCaller_##functionname##_) \
379                        delete identifier->superFunctionCaller_##functionname##_; \
380                    SuperFunctionDestruction<functionnumber + 1, T>::destroy(identifier); \
381                } \
382            }; \
383            \
384            template <class T> \
385            class SuperFunctionClassCaller_##functionname : public SuperFunctionCaller_##functionname \
386            { \
387                public: \
388                    inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) \
389                    { \
390                        (dynamic_cast<T*>(object))->T:: functionname
391
392        /*
393            JUST ADD THE FUNCTION ARGUMENTS BETWEEN BOTH MACROS, ENCLOSED BY BRACKETS
394            EXAMPLE:
395
396              SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(0, myfunction, true, int myvalue, float myothervalue) <-- !!! DONT ADD A SEMICOLON HERE !!!
397                (myvalue, myothervalue)
398              SUPER_FUNCTION_GLOBAL_DECLARATION_PART2
399        */
400
401        #define SUPER_FUNCTION_GLOBAL_DECLARATION_PART2 \
402                                                        ; \
403                    } \
404            };
405
406        #define SUPER_CALL_ARGUMENTSfalse(...) OrxonoxClass* object
407        #define SUPER_CALL_ARGUMENTS0(...)     OrxonoxClass* object
408        #define SUPER_CALL_ARGUMENTStrue(...) OrxonoxClass* object, __VA_ARGS__
409        #define SUPER_CALL_ARGUMENTS1(...)    OrxonoxClass* object, __VA_ARGS__
410
411
412    /*
413    //// COMMENTS ABOUT THE MACRO ////
414
415        // Partially specialized template (templatehack not yet specialized, this
416        // will be done by the real condition in the header-file of the super-function)
417        // Only used as fallback
418        template <class T, int templatehack1, int templatehack2>
419        struct SuperFunctionCondition<functionnumber, T, templatehack1, templatehack2>
420        {
421            // If this function gets called, the header-file of the super function is not
422            // included, so this fallback template (templatehack not specialized) is used
423            static void check()
424            {
425                // Calls the condition-check of the next super-function (functionnumber + 1)
426                SuperFunctionCondition<functionnumber + 1, T, templatehack1, templatehack2>::check();
427            }
428        };
429
430        // Baseclass of the super-function caller. The real call will be done by a
431        // templatized subclass through the virtual () operator.
432        class _CoreExport SuperFunctionCaller_##functionname
433        {
434            public:
435                virtual void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) ) = 0;
436                virtual ~SuperFunctionCaller_##functionname () {}
437        };
438
439        // Fallback if the base is pure virtual
440        template <class T>
441        class SuperFunctionClassCaller_purevirtualfallback_##functionname : public SuperFunctionCaller_##functionname
442        {
443            public:
444                // Fallback does nothing
445                inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) )
446                {
447                }
448        };
449
450        // Initializes the SuperFunctionCaller-pointer with a fallback caller in case the base function is pure virtual
451        template <class T>
452        struct SuperFunctionInitialization<functionnumber, T>
453        {
454            static void initialize(ClassIdentifier<T>* identifier)
455            {
456                identifier->superFunctionCaller_##functionname##_ = new SuperFunctionClassCaller_purevirtualfallback_##functionname <T>;
457                identifier->bSuperFunctionCaller_##functionname##_isFallback_ = true;
458
459                // Calls the initialization of the next super-function (functionnumber + 1)
460                SuperFunctionInitialization<functionnumber + 1, T>::initialize(identifier);
461            }
462        };
463
464        // Deletes the SuperFunctionCaller.
465        template <class T>
466        struct SuperFunctionDestruction<functionnumber, T>
467        {
468            static void destroy(ClassIdentifier<T>* identifier)
469            {
470                if (identifier->superFunctionCaller_##functionname##_)
471                    delete identifier->superFunctionCaller_##functionname##_;
472
473                // Calls the destruction of the next super-function (functionnumber + 1)
474                SuperFunctionDestruction<functionnumber + 1, T>::destroy(identifier);
475            }
476        };
477
478        // The real super-function caller: Calls T::functionname()
479        // T should be the parent, but this will be done by the spezialized condition template
480        template <class T>
481        class SuperFunctionClassCaller_##functionname : public SuperFunctionCaller_##functionname
482        {
483            public:
484                // @brief Calls the function.
485                // @param object The object to call the function on
486                // @param ... The arguments of the function
487                inline void operator()( SUPER_CALL_ARGUMENTS##hasarguments(__VA_ARGS__) )
488                {
489                    (dynamic_cast<T*>(object))->T:: functionname ( Call the function with it's arguments );
490                }
491        }
492    */
493
494
495    //// Execute the code for each super-function ////
496
497        // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
498        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(0, XMLPort, true, Element& xmlelement, XMLPort::Mode mode)
499            (xmlelement, mode)
500        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
501
502        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(1, tick, true, float dt)
503            (dt)
504        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
505
506        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(2, changedActivity, false)
507            ()
508        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
509
510        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(3, changedVisibility, false)
511            ()
512        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
513
514        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(4, XMLEventPort, true, Element& xmlelement, XMLPort::Mode mode)
515            (xmlelement, mode)
516        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
517
518        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(5, changedScale, false)
519            ()
520        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
521
522        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(6, changedOwner, false)
523            ()
524        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
525
526        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(7, changedOverlayGroup, false)
527            ()
528        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
529
530        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(8, changedName, false)
531            ()
532        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
533
534        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(9, changedGametype, false)
535            ()
536        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
537
538        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(10, changedUsed, false)
539            ()
540        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
541
542        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(11, clone, true, OrxonoxClass* item)
543            (item)
544        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
545
546        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(12, changedCarrier, false)
547            ()
548        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
549
550        SUPER_FUNCTION_GLOBAL_DECLARATION_PART1(13, changedPickedUp, false)
551            ()
552        SUPER_FUNCTION_GLOBAL_DECLARATION_PART2;
553
554        // (2/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
555
556}
557
558#else /* _Super_H__ */
559  #ifdef SUPER_INTRUSIVE_DECLARATION_INCLUDE
560
561//////////////////////////////////////////////////////////////////////////
562// This code gets included within the declaration of ClassIdentifier<T> //
563//////////////////////////////////////////////////////////////////////////
564
565//// Common code ////
566
567    private:
568
569        template <int functionnumber, class TT, int templatehack1, int templatehack2>
570        friend struct SuperFunctionCondition;
571
572        // Creates the super-function-callers by calling the first SuperFunctionCondition check
573        // This get's called within the initialization of an Identifier
574        virtual void createSuperFunctionCaller() const
575        {
576            SuperFunctionCondition<0, T, 0, 0>::check();
577        }
578
579
580//// Function-specific code ////
581
582    public:
583        /**
584            @brief Adds a pointer to the SuperFunctionCaller as a member of ClassIdentifier.
585            @param functionname The name of the super-function
586        */
587        #ifndef SUPER_INTRUSIVE_DECLARATION
588          #define SUPER_INTRUSIVE_DECLARATION(functionname) \
589            SuperFunctionCaller_##functionname * superFunctionCaller_##functionname##_; \
590            bool bSuperFunctionCaller_##functionname##_isFallback_
591        #endif
592
593
594//// Execute the code for each super-function ////
595
596    // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
597    SUPER_INTRUSIVE_DECLARATION(XMLPort);
598    SUPER_INTRUSIVE_DECLARATION(tick);
599    SUPER_INTRUSIVE_DECLARATION(changedActivity);
600    SUPER_INTRUSIVE_DECLARATION(changedVisibility);
601    SUPER_INTRUSIVE_DECLARATION(XMLEventPort);
602    SUPER_INTRUSIVE_DECLARATION(changedScale);
603    SUPER_INTRUSIVE_DECLARATION(changedOwner);
604    SUPER_INTRUSIVE_DECLARATION(changedOverlayGroup);
605    SUPER_INTRUSIVE_DECLARATION(changedName);
606    SUPER_INTRUSIVE_DECLARATION(changedGametype);
607    SUPER_INTRUSIVE_DECLARATION(changedUsed);
608    SUPER_INTRUSIVE_DECLARATION(clone);
609    SUPER_INTRUSIVE_DECLARATION(changedCarrier);
610    SUPER_INTRUSIVE_DECLARATION(changedPickedUp);
611    // (3/3) --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <-- --> HERE <--
612
613
614    #undef SUPER_INTRUSIVE_DECLARATION_INCLUDE
615  #endif /* SUPER_INTRUSIVE_DECLARATION_INCLUDE */
616#endif /* _Super_H__ */
Note: See TracBrowser for help on using the repository browser.