root/cafu/trunk/Libs/TypeSys.hpp

Revision 457, 10.3 KB (checked in by Carsten, 4 months ago)

Using UltraEdit's multi-line search-and-replace-in-files feature, replaced


^#ifndef _(CAFU|CF|CFS|CA)_(.*)_$
^#define _\1_\2_$

with

#ifndef CAFU_\2_INCLUDED
#define CAFU_\2_INCLUDED

and


^#ifndef _(.*)_HPP_$
^#define _\1_HPP_$

with

#ifndef CAFU_\1_HPP_INCLUDED
#define CAFU_\1_HPP_INCLUDED

Closes #91.

Line 
1/*
2=================================================================================
3This file is part of Cafu, the open-source game engine and graphics engine
4for multiplayer, cross-platform, real-time 3D action.
5Copyright (C) 2002-2012 Carsten Fuchs Software.
6
7Cafu is free software: you can redistribute it and/or modify it under the terms
8of the GNU General Public License as published by the Free Software Foundation,
9either version 3 of the License, or (at your option) any later version.
10
11Cafu is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
13PURPOSE. See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with Cafu. If not, see <http://www.gnu.org/licenses/>.
17
18For support and more information about Cafu, visit us at <http://www.cafu.de>.
19=================================================================================
20*/
21
22#ifndef CAFU_TYPESYS_TYPEINFO_HPP_INCLUDED
23#define CAFU_TYPESYS_TYPEINFO_HPP_INCLUDED
24
25#include "Templates/Array.hpp"
26#include <ostream>
27
28
29struct luaL_Reg;
30
31
32namespace cf
33{
34    /// The main purpose of the Type System is to make the programmers life easier when he is working with inheritance
35    /// hierarchies of C++ classes. In many such cases, "meta" knowledge about the classes is required.
36    ///
37    /// For example, when binding a hierarchy of C++ classes to Lua it is very helpful during Lua state initialization when
38    /// we can iterate over all classes in the hierarchy (specially ordered so that bases classes always occur before their
39    /// child classes). Additionally, classes should register themselves automatically in the data-structure for the
40    /// iteration, so that adding new classes to the hierarchy is easy and doesn't require any changes elsewhere, such as
41    /// to the Lua init code (a very convenient and important feature for MOD and game developers!).
42    /// The TypeSys is employed for the game entities hierarchy (BaseEntityT), for which the TypeSys was initially invented,
43    /// as well as the windows hierarchy of the GuiSys (cf::GuiSys::WindowT), which supports scripting as well.
44    ///
45    /// Other uses directly suggest themselves from the details of the implementation, or were trivially added to the basic system:
46    ///   - Auto-assign each type a unique type number, e.g. for sending over the network.
47    ///     The type number is also "robust", i.e. independent of actual static initialization order.
48    ///   - Be able to iterate over all types (entity classes), e.g. for early initialization of the Lua state (adding a metatable
49    ///     for each entity class to the registry of the Lua state), or for listing all supported script methods (user help), etc.
50    ///   - Factory: Be able to instantiate an entity class by type name (e.g. from map file) or by type number (e.g. as received over the network).
51    /// ( - Provide a faster means for dynamic_cast<>(). )
52    ///
53    /// The Type System achieves its goals by explicitly modelling an inheritance hierarchy of C++ classes as a graph,
54    /// which presents a "meta-layer" of information about the hierarchy and thus allows other C++ code to become conciously
55    /// aware of the inheritance structure.
56    namespace TypeSys
57    {
58        class TypeInfoManT;
59
60
61        // Unfortunately, when this is nested in TypeInfoT, it cannot be forward-declared...
62        class CreateParamsT
63        {
64        };
65
66
67        /// This class keeps type information (about an entity class that occurs in the game).
68        /// (Supports single, but not multiple inheritance.)
69        class TypeInfoT
70        {
71            public:
72
73            // TODO: Is there a nice way to make the CreateInstance() call-back type-safe?
74            //       Note that for entities (who have a virtual GetType() method), the following asserts should hold:
75            //           BaseEntityT* BE=dynamic_cast<BaseEntityT*>(SomeType->CreateInstance());
76            //        or BaseEntityT* BE=(BaseEntityT*)SomeType->CreateInstance();
77            //           assert(BE!=NULL);
78            //           assert(BE->GetType()==SomeType);
79            typedef void* (*CreateInstanceT)(const CreateParamsT& Params);
80
81            /// The constructor.
82            /// This is supposed to be called only by the static TypeInfoT member of each entity class.
83            TypeInfoT(TypeInfoManT& TIM, const char* ClassName_, const char* BaseClassName_, CreateInstanceT CreateInstance_, const luaL_Reg MethodsList_[]);
84
85            /// Prints the contents of this node to the console.
86            /// @param Recurse    Whether the children (derived classes) of this node should be printed.
87            /// @param RecDepth   The current recursion depth. This is for the methods internal use - user code should never pass it.
88            void Print(bool Recurse=true, unsigned long RecDepth=0) const;
89
90            /// Determines whether the other given type info is in the inheritance tree of this type
91            /// (this method roughly corresponds to dynamic_cast<>() in C++).
92            bool HierarchyHas(const TypeInfoT* Other) const;
93
94            /// Returns the next type info in the hierarchy.
95            const TypeInfoT* GetNext() const;
96
97
98            const char*      ClassName;         ///< The name of this class.
99            const char*      BaseClassName;     ///< The name of the base/super/parent class of this class.
100            CreateInstanceT  CreateInstance;    ///< The call-back function that creates an instance of this class.
101            const luaL_Reg*  MethodsList;       ///< The list (array) of Lua methods that this class implements.
102
103            const TypeInfoT* Base;              ///< The type info for the base class.
104            const TypeInfoT* Sibling;           ///< The type info for the next sibling class (a linked list).
105            const TypeInfoT* Child;             ///< The type info for the first child class.
106            unsigned long    TypeNr;            ///< The unique and "robust" number of this type, obtained by enumerating the hierarchy nodes in depth-first order.
107            unsigned long    LastChildNr;       ///< The highest TypeNr in the subhierarchy of this type. Depth-first enumeration guarantees that for all type numbers T in this subhierarchy, TypeNr<=T<=LastChildNr holds.
108
109
110            private:
111
112            TypeInfoT(const TypeInfoT&);            ///< Use of the Copy Constructor    is not allowed.
113            void operator = (const TypeInfoT&);     ///< Use of the Assignment Operator is not allowed.
114        };
115
116
117        /// This class manages the type infos.
118        ///
119        /// Intended usage:
120        /// Each entity class that occurs in the game keeps a static TypeInfoT member
121        /// (plus a non-static, *virtual* GetTypeInfo() method that returns that member).
122        /// The constructor of each such TypeInfoT member registers its own this-pointer with an instance of this class,
123        /// so that when main() begins, the TypeInfoManT is aware of all TypeInfoTs and thus all entity classes.
124        /// Its Init() method then completes the type initialization.
125        class TypeInfoManT
126        {
127            public:
128
129            /// The constructor.
130            TypeInfoManT();
131
132            /// Registers the given TypeInfoT with this type info manager.
133            /// Only the TypeInfoT constructor code should call this, which in turn should only occur during global static initialization time,
134            /// never after Init() has been called.
135            void Register(TypeInfoT* TI);
136
137            /// Completes the initialization of the TypeInfoManT and the registered type infos.
138            /// Should be called exactly once before any other TypeInfoManT method is called.
139            void Init();
140
141
142            /// Returns the type info matching the class name ClassName.
143            /// @returns the (pointer to the) TypeInfoT matching ClassName, or NULL if not found.
144            const TypeInfoT* FindTypeInfoByName(const char* ClassName) const;
145
146            /// Returns the type info matching the type number TypeNr.
147            /// @returns the (pointer to the) TypeInfoT T, so that T->TypeNr==TypeNr.
148            const TypeInfoT* FindTypeInfoByNr(unsigned long TypeNr) const;
149
150         // const ArrayT<TypeInfoT*>& GetListByName() const;    // Only call after Init().
151         // const ArrayT<TypeInfoT*>& GetListByNr() const;      // Only call after Init().
152            const ArrayT<const TypeInfoT*>& GetTypeInfoRoots() const { assert(IsInited); return TypeInfoRoots; }  // Only call after Init().
153
154            /// This is an auxiliary method for creating Lua scripting documentation for the registered classes.
155            /// Assuming that the classes registered with this type info manager provide methods for access from Lua scripts,
156            /// this method creates Doxygen input files ("fake headers") that documentation writers can complete to create
157            /// related reference documentation.
158            void CreateLuaDoxygenHeader(std::ostream& Out) const;
159
160
161            private:
162
163            bool                     IsInited;        ///< Tells whether Init() has already been called.
164            ArrayT<const TypeInfoT*> TypeInfosByName; ///< The registered type infos listed in alphabetical order.
165            ArrayT<const TypeInfoT*> TypeInfosByNr;   ///< The registered type infos listed in TypeNr order, TypeInfosByNr[i].TypeNr==i.
166            ArrayT<const TypeInfoT*> TypeInfoRoots;   ///< The roots of the inheritance trees. Normally there should only be one root.
167        };
168    }
169}
170
171
172/* #define DECLARE_TYPE_INFO() \
173    /// Returns the proper type info for this class. This method is virtual \
174    /// so that it works even when called with a base class pointer. \
175    virtual const cf::TypeSys::TypeInfoT* GetType() const { return &TypeInfo; } \
176\
177    /// Creates an instance of this class from the given Params object. \
178    /// This call-back function is a part (member) of the TypeInfoT of this class. \
179    static void* CreateInstance(const cf::TypeSys::CreateParamsT& Params); \
180\
181    /// The type info object for (objects/instances of) this class. \
182    static const cf::TypeSys::TypeInfoT TypeInfo; */
183
184
185/* #define IMPLEMENT_TYPE_INFO() \
186//     ... */
187
188#endif
Note: See TracBrowser for help on using the browser.