Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core6/src/libraries/core/CoreIncludes.h @ 9650

Last change on this file since 9650 was 9646, checked in by landauf, 11 years ago

implemented new concept to initialize the class hierarchy: each identifier is initialized individually by creating an object of the corresponding class. identifiers of abstract classes must be told explicitly about their direct parents. this allows to build the class tree correctly also for complicated setups like multiple inheritance of abstract classes.

  • Property svn:eol-style set to native
File size: 7.6 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 Factory RegisterObject() and RegisterClass()
31    @ingroup Object
32*/
33
34/**
35    @file
36    @ingroup Object Factory Class Identifier
37    @brief Defines several very important macros used to register objects, register classes, and to work with identifiers.
38
39    Every class needs the @c RegisterObject(class) macro in its constructor. If the class is an interface
40    or the @c BaseObject itself, it needs the macro @c RegisterRootObject(class) instead.
41
42    To register @a class in the class-hierarchy, use the @c RegisterClass(class) macro outside of the class implementation,
43    so it gets executed statically before @c main(). If you don't want @a class to be loadable, but still register it, call
44    @c RegisterUnloadableClass(class).
45
46    Example:
47    @code
48    // register MyClass
49    RegisterClass(MyClass);
50
51    // Constructor:
52    MyClass::MyClass()
53    {
54        // Register the object in the Identifier of MyClass
55        RegisterObject(MyClass);
56    }
57    @endcode
58
59    This file also defines a number of other useful macros, like, for example, @c Class(class) which
60    returns the @ref orxonox::Identifier "Identifier" of @a class, or @c ClassByString("class") which
61    returns the Identifier of a class with name @a "class".
62
63    Example:
64    @code
65    // Assigns the Identifier of MyClass
66    Identifier* identifier = Class(MyClass);
67    @endcode
68    @code
69    // Assigns the Identifier of a class named "MyClass"
70    Identifier* identifier = ClassByString("MyClass");
71    @endcode
72*/
73
74#ifndef _CoreIncludes_H__
75#define _CoreIncludes_H__
76
77#include "CorePrereqs.h"
78
79#include "util/Output.h"
80#include "class/IdentifierManager.h"
81#include "object/ClassFactory.h"
82#include "object/ObjectList.h"
83
84// resolve macro conflict on windows
85#if defined(ORXONOX_PLATFORM_WINDOWS)
86#   include <windows.h>
87#   undef RegisterClass
88#endif
89
90
91/**
92    @brief Registers the class in the framework.
93    @param ClassName The name of the class
94*/
95#define RegisterClass(ClassName) \
96    RegisterClassWithFactory(ClassName, new orxonox::ClassFactoryWithContext<ClassName>(), true)
97
98/**
99    @brief Registers the class in the framework (for classes without arguments in their constructor).
100    @param ClassName The name of the class
101*/
102#define RegisterClassNoArgs(ClassName) \
103    RegisterClassWithFactory(ClassName, new orxonox::ClassFactoryNoArgs<ClassName>(), true)
104
105/**
106    @brief Registers the class in the framework (for classes which should not be loaded through XML).
107    @param ClassName The name of the class
108*/
109#define RegisterUnloadableClass(ClassName) \
110    RegisterClassWithFactory(ClassName, new orxonox::ClassFactoryWithContext<ClassName>(), false)
111
112/**
113    @brief Registers an abstract class in the framework.
114    @param ClassName The name of the class
115*/
116#define RegisterAbstractClass(ClassName) \
117    RegisterClassWithFactory(ClassName, static_cast<ClassFactory<ClassName>*>(NULL), false)
118
119/**
120    @brief Registers the class in the framework with a given Factory.
121    @param ClassName The name of the class
122*/
123#define RegisterClassWithFactory(ClassName, FactoryInstance, bLoadable) \
124    Identifier& _##ClassName##Identifier = orxonox::registerClass<ClassName>(#ClassName, FactoryInstance, bLoadable)
125
126/**
127    @brief Intern macro, containing the common parts of @c RegisterObject and @c RegisterRootObject.
128    @param ClassName The name of the class
129    @param bRootClass True if the class is directly derived from orxonox::OrxonoxClass
130*/
131#define InternRegisterObject(ClassName) \
132    if (ClassIdentifier<ClassName>::getIdentifier(#ClassName)->initializeObject(this)) \
133        return; \
134    else \
135        ((void)0)
136
137/**
138    @brief Registers a newly created object in the framework. Has to be called at the beginning of the constructor of @a ClassName.
139    @param ClassName The name of the class
140*/
141#define RegisterObject(ClassName) \
142    InternRegisterObject(ClassName)
143
144/**
145    @brief Registers a newly created object in the framework. Has to be called at the beginning of the constructor of @a ClassName.
146    @param ClassName The name of the class
147
148    In contrast to RegisterObject, this is used for classes that inherit directly from
149    orxonox::OrxonoxClass, namely all interfaces and orxonox::BaseObject.
150*/
151#define RegisterRootObject(ClassName) \
152    InternRegisterObject(ClassName)
153
154/**
155    @brief Returns the Identifier of the given class.
156    @param ClassName The name of the class
157*/
158#define Class(ClassName) \
159    orxonox::ClassIdentifier<ClassName>::getIdentifier()
160
161
162namespace orxonox
163{
164    /**
165     * @brief Overload of registerClass() which determines T implicitly by the template argument of the ClassFactory.
166     */
167    template <class T>
168    inline Identifier& registerClass(const std::string& name, ClassFactory<T>* factory, bool bLoadable = true)
169    {
170        return registerClass<T>(name, static_cast<Factory*>(factory), bLoadable);
171    }
172
173    /**
174     * @brief Registers a class in the framework.
175     * @param name The name of the class
176     * @param factory The factory which is able to create new instances of this class
177     * @param bLoadable Whether the class is allowed to be loaded through XML
178     */
179    template <class T>
180    inline Identifier& registerClass(const std::string& name, Factory* factory, bool bLoadable = true)
181    {
182        orxout(verbose, context::misc::factory) << "Create entry for " << name << " in Factory." << endl;
183        Identifier* identifier = ClassIdentifier<T>::getIdentifier(name);
184        identifier->setFactory(factory);
185        identifier->setLoadable(bLoadable);
186        return *identifier;
187    }
188
189    /**
190        @brief Returns the Identifier with a given name.
191        @param name The name of the class
192    */
193    inline Identifier* ClassByString(const std::string& name)
194    {
195        return IdentifierManager::getInstance().getIdentifierByString(name);
196    }
197
198    /**
199        @brief Returns the Identifier with a given lowercase name.
200        @param name The lowercase name of the class
201    */
202    inline Identifier* ClassByLowercaseString(const std::string& name)
203    {
204        return IdentifierManager::getInstance().getIdentifierByLowercaseString(name);
205    }
206
207    /**
208        @brief Returns the Identifier with a given network ID.
209        @param id The network ID of the class
210    */
211    inline Identifier* ClassByID(uint32_t id)
212    {
213        return IdentifierManager::getInstance().getIdentifierByID(id);
214    }
215
216    /**
217        @brief Returns the Identifier with a given 'this' pointer.
218        @note This of course only works with Identifiables.
219              The only use is in conjunction with macros that don't know the class type.
220        @param object Pointer to an Identifiable
221    */
222    template <class T>
223    inline Identifier* ClassByObjectType(const T*)
224    {
225        return ClassIdentifier<T>::getIdentifier();
226    }
227}
228
229#endif /* _CoreIncludes_H__ */
Note: See TracBrowser for help on using the repository browser.