Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy2/src/core/Super.h @ 2362

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