Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchie/src/Identifier.h @ 224

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