Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchie/src/ClassHierarchy.h @ 176

Last change on this file since 176 was 176, checked in by landauf, 16 years ago

started to implement BaseIdentifier<class B> template

File size: 9.0 KB
RevLine 
[132]1#ifndef _ClassHierarchy_H__
2#define _ClassHierarchy_H__
3
4#include <string>
[162]5#include <iostream>
[132]6
[172]7// DONE AND TESTED:
[176]8// - build class hierarchy
9// - isA, isChildOf, ...
10// - insert into class-lists
11// - ClassIdentifier
[172]12
13// IN WORK:
[176]14// - BaseIdentifier
15// - Factory
[132]16
[172]17// TO DO:
[176]18// - iterate through lists
19// - searchtree for classname-strings
[132]20
[149]21
22namespace orxonox
23{
[162]24    // ##### ClassHierarchy #####
[172]25    template <class T>
26    class ClassIdentifier;
27
[162]28    class ClassHierarchy
29    {
[172]30        template <class T>
31        friend class ClassIdentifier;
32
[162]33        public:
34            static ClassHierarchy* getSingleton();
[172]35            bool isCreatingHierarchy() { return (this->hierarchyCreatingCounter_ > 0); }
[162]36
37        private:
38            ClassHierarchy();
[172]39            ~ClassHierarchy();
40            void startCreatingHierarchy() { this->hierarchyCreatingCounter_++; std::cout << "*** Increased Hierarchy-Creating-Counter to " << this->hierarchyCreatingCounter_ << "\n"; }
41            void stopCreatingHierarchy() { this->hierarchyCreatingCounter_--; std::cout << "*** Decreased Hierarchy-Creating-Counter to " << this->hierarchyCreatingCounter_ << "\n"; }
[162]42
43            static ClassHierarchy* pointer_;
[172]44            int hierarchyCreatingCounter_;
[162]45    };
46
[149]47    // ##### Identifier #####
48    class IdentifierList;
[132]49    class ObjectList;
[162]50    class OrxonoxClass;
[132]51
[149]52    class Identifier
[132]53    {
[149]54        template <class T>
55        friend class ClassIdentifier;
56
[172]57        template <class T>
58        friend class BaseIdentifier;
59
[132]60        public:
[162]61            void addObject(OrxonoxClass* object);
62            void removeObject(OrxonoxClass* object);
[132]63
[149]64            bool isA(Identifier* identifier);
[172]65            bool isDirectlyA(Identifier* identifier);
[149]66            bool isChildOf(Identifier* identifier);
67            bool isDirectChildOf(Identifier* identifier);
68            bool isParentOf(Identifier* identifier);
69            bool isDirectParentOf(Identifier* identifier);
70
[172]71            std::string getName() { return this->name_; }
72            IdentifierList* getDirectParents() { return this->directParents_; }
73            IdentifierList* getAllParents() { return this->allParents_; }
74            IdentifierList* getDirectChildren() { return this->directChildren_; }
75            IdentifierList* getAllChildren() { return this->allChildren_; }
76
[150]77        private:
[149]78            Identifier();
[176]79            Identifier(const Identifier& identifier) {}
80            virtual ~Identifier();
[150]81            void initialize(IdentifierList* parents);
[149]82
83            IdentifierList* directParents_;
84            IdentifierList* allParents_;
85            IdentifierList* directChildren_;
86            IdentifierList* allChildren_;
87
88            ObjectList* objects_;
89            std::string name_;
90
91            bool bCreatedOneObject_;
[132]92    };
93
[172]94
95    // ##### ClassIdentifier #####
[149]96    template <class T>
97    class ClassIdentifier : public Identifier
[132]98    {
99        public:
[162]100            static ClassIdentifier<T>* registerClass(IdentifierList* parents, std::string name, bool bRootClass);
[150]101            static ClassIdentifier<T>* getIdentifier();
[149]102            static T* create();
[132]103
[149]104        private:
105            ClassIdentifier();
[176]106            ClassIdentifier(const ClassIdentifier<T>& identifier) {}
[172]107            ~ClassIdentifier();
[150]108
109            static ClassIdentifier<T>* pointer_;
110
[132]111    };
112
[149]113    template <class T>
[150]114    ClassIdentifier<T>* ClassIdentifier<T>::pointer_ = NULL;
115
116    template <class T>
[149]117    ClassIdentifier<T>::ClassIdentifier()
[132]118    {
[149]119    }
[132]120
[149]121    template <class T>
[172]122    ClassIdentifier<T>::~ClassIdentifier()
123    {
124        this->pointer_ = NULL;
125    }
126
127    template <class T>
[162]128    ClassIdentifier<T>* ClassIdentifier<T>::registerClass(IdentifierList* parents, std::string name, bool bRootClass)
[149]129    {
[162]130        std::cout << "*** Register Class in " << name << "-Singleton.\n";
[149]131        if (!pointer_)
132        {
[162]133            std::cout << "*** Register Class in " << name << "-Singleton -> Create Singleton.\n";
134            if (parents || bRootClass)
135            {
136                pointer_ = new ClassIdentifier();
137                pointer_->name_ = name;
138                pointer_->initialize(parents);
139            }
140            else
141            {
142                pointer_ = getIdentifier();
143            }
[149]144        }
[132]145
[149]146        return pointer_;
147    }
148
149    template <class T>
[150]150    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
[132]151    {
[172]152//        std::cout << "*** Get Identifier.\n";
[149]153        if (!pointer_)
154        {
[162]155            std::cout << "*** Get Identifier -> Create Class\n";
[172]156            ClassHierarchy::getSingleton()->startCreatingHierarchy();
[149]157            T* temp = new T();
[172]158            ClassHierarchy::getSingleton()->stopCreatingHierarchy();
[149]159            delete temp;
160        }
161
162        return pointer_;
163    }
164
165    template <class T>
166    T* ClassIdentifier<T>::create()
167    {
168        return new T();
169    }
170
[172]171
[176]172    // ##### BaseIdentifier #####
173    template <class B>
174    class BaseIdentifier// : public Identifier
175    {
176        public:
177            BaseIdentifier();
178
179            template <class T>
180            BaseIdentifier<B>& operator= (ClassIdentifier<T>* identifier)
181            {
182                std::cout << "####### Class(" << identifier->getName() << ")->isA( Class(" << ClassIdentifier<B>::getIdentifier()->getName() << ") ) = " << identifier->isA( ClassIdentifier<B>::getIdentifier() ) << "\n";
183                if (!identifier->isA(ClassIdentifier<B>::getIdentifier()))
184                {
185                    std::cout << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n";
186                    std::cout << "Error: BaseIdentifier<" << ClassIdentifier<B>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden.\n";
187                    std::cout << "Aborting...\n";
188                    abort();
189                }
190                this->identifier_ = identifier;
191                return *this;
192            }
193
194            operator Identifier()
195            {
196                return this->identifier_;
197            }
198
199        private:
200            Identifier* identifier_;
201    };
202
203    template <class B>
204    BaseIdentifier<B>::BaseIdentifier()
205    {
206        this->identifier_ = ClassIdentifier<B>::getIdentifier();
207    }
208
209
[149]210    // ##### Identifier List #####
211    class IdentifierListElement;
212
213    class IdentifierList
214    {
[132]215        public:
[149]216            IdentifierList();
217            ~IdentifierList();
218            void add(Identifier* identifier);
219            void remove(Identifier* identifier);
220            bool isInList(Identifier* identifier);
[172]221            std::string toString();
[132]222
[149]223            IdentifierListElement* first_;
[132]224    };
225
[149]226    class IdentifierListElement
[132]227    {
228        public:
[149]229            IdentifierListElement(Identifier* identifier);
[172]230            ~IdentifierListElement();
[132]231
[149]232            Identifier* identifier_;
233            IdentifierListElement* next_;
234            bool bDirect_;
[132]235    };
236
[149]237
238    // ##### Object List #####
239    class ObjectListElement;
240
[132]241    class ObjectList
242    {
243        public:
244            ObjectList();
245            ~ObjectList();
[162]246            void add(OrxonoxClass* object);
247            void remove(OrxonoxClass* object);
[132]248
[149]249            ObjectListElement* first_;
[132]250    };
251
[149]252    class ObjectListElement
[132]253    {
254        public:
[162]255            ObjectListElement(OrxonoxClass* object);
[172]256            ~ObjectListElement();
[132]257
[162]258            OrxonoxClass* object_;
[149]259            ObjectListElement* next_;
[132]260    };
261
[149]262    // ##### Macros #####
263    #define registerRootObject(ClassName) \
[162]264        std::cout << "*** Register Root-Object: " << #ClassName << "\n"; \
265        if (ClassHierarchy::getSingleton()->isCreatingHierarchy() && !this->getParents()) \
266            this->setParents(new IdentifierList()); \
267        if (this->getIdentifier()) \
268            this->getIdentifier()->removeObject(this); \
269        this->setIdentifier(ClassIdentifier<ClassName>::registerClass(this->getParents(), #ClassName, true)); \
270        if (ClassHierarchy::getSingleton()->isCreatingHierarchy() && this->getParents()) \
271            this->getParents()->add(this->getIdentifier()); \
272        this->getIdentifier()->addObject(this)
[132]273
[149]274    #define registerObject(ClassName) \
[162]275        std::cout << "*** Register Object: " << #ClassName << "\n"; \
276        this->getIdentifier()->removeObject(this); \
277        this->setIdentifier(ClassIdentifier<ClassName>::registerClass(this->getParents(), #ClassName, false)); \
278        if (ClassHierarchy::getSingleton()->isCreatingHierarchy() && this->getParents()) \
279            this->getParents()->add(this->getIdentifier()); \
280        this->getIdentifier()->addObject(this)
[132]281
282    #define unregisterObject() \
[162]283        this->getIdentifier()->removeObject(this)
[132]284
[149]285    #define Class(ClassName) \
286        ClassIdentifier<ClassName>::getIdentifier()
[132]287
[149]288    #define Factory(ClassName) \
289        ClassIdentifier<ClassName>::create()
290}
291
[132]292#endif
Note: See TracBrowser for help on using the repository browser.