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
Line 
1#ifndef _Identifier_H__
2#define _Identifier_H__
3
4#include <iostream>
5
6#include "IdentifierList.h"
7#include "ObjectList.h"
8//#include "OrxonoxClass.h"
9#include "Factory.h"
10
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
24namespace orxonox
25{
26    class BaseObject;
27
28    // ###############################
29    // ###       Identifier        ###
30    // ###############################
31    class Identifier
32    {
33        template <class T>
34        friend class ClassIdentifier;
35
36        template <class T>
37        friend class BaseIdentifier;
38
39        public:
40            virtual void removeObject(OrxonoxClass* object) {};
41
42            virtual BaseObject* fabricate() {};
43
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_; }
52            IdentifierList* getDirectParents() { return &(this->directParents_); }
53            IdentifierList* getAllParents() { return &(this->allParents_); }
54            IdentifierList* getDirectChildren() { return &(this->directChildren_); }
55            IdentifierList* getAllChildren() { return &(this->allChildren_); }
56
57            static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); }
58
59        private:
60            Identifier();
61            Identifier(const Identifier& identifier) {}
62            virtual ~Identifier();
63            void initialize(IdentifierList* parents);
64
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"; }
67
68            IdentifierList directParents_;
69            IdentifierList allParents_;
70            IdentifierList directChildren_;
71            IdentifierList allChildren_;
72
73            std::string name_;
74
75            bool bIsAbstractClass_;
76            bool bCreatedOneObject_;
77
78            static int hierarchyCreatingCounter_s;
79    };
80
81
82    // ###############################
83    // ###     ClassIdentifier     ###
84    // ###############################
85    template <class T>
86    class ClassIdentifier : public Identifier
87    {
88        template <class U>
89        friend class Iterator;
90
91        public:
92            static ClassIdentifier<T>* registerClass(IdentifierList* parents, std::string name, bool bRootClass, bool bIsAbstractClass);
93            static ClassIdentifier<T>* getIdentifier();
94            BaseObject* fabricate();
95            T* fabricateClass();
96            static void addObject(T* object);
97            void removeObject(OrxonoxClass* object);
98
99        private:
100            ClassIdentifier();
101            ClassIdentifier(const ClassIdentifier<T>& identifier) {}
102            ~ClassIdentifier();
103
104            static ClassIdentifier<T>* pointer_s;
105            ObjectList<T> objects_s;
106    };
107
108    template <class T>
109    ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL;
110
111    template <class T>
112    ClassIdentifier<T>::ClassIdentifier()
113    {
114    }
115
116    template <class T>
117    ClassIdentifier<T>::~ClassIdentifier()
118    {
119        this->pointer_s = NULL;
120    }
121
122    template <class T>
123    BaseObject* ClassIdentifier<T>::fabricate()
124    {
125        return dynamic_cast<BaseObject*>(this->fabricateClass());
126    }
127
128    template <class T>
129    T* ClassIdentifier<T>::fabricateClass()
130    {
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        }
141    }
142
143    template <class T>
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";
147        if (!pointer_s)
148        {
149            std::cout << "*** Register Class in " << name << "-Singleton -> Create Singleton.\n";
150            if (parents || bRootClass)
151            {
152                pointer_s = new ClassIdentifier();
153                pointer_s->name_ = name;
154                pointer_s->bIsAbstractClass_ = bIsAbstractClass;
155
156                ClassFactory::add(name, pointer_s);
157
158                if (!bRootClass)
159                    pointer_s->initialize(parents);
160                else
161                    pointer_s->initialize(NULL);
162            }
163            else
164            {
165                pointer_s = getIdentifier();
166            }
167        }
168
169        return pointer_s;
170    }
171
172    template <class T>
173    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
174    {
175//        std::cout << "*** Get Identifier.\n";
176        if (!pointer_s)
177        {
178            std::cout << "*** Get Identifier -> Create Class\n";
179            Identifier::startCreatingHierarchy();
180            T* temp = new T();
181            delete temp;
182            Identifier::stopCreatingHierarchy();
183        }
184
185        return pointer_s;
186    }
187
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    // ###############################
219    template <class B>
220    class BaseIdentifier
221    {
222        public:
223            BaseIdentifier();
224
225            BaseIdentifier<B>& operator=(Identifier* identifier)
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            }
237
238            Identifier* operator*()
239            {
240                return this->identifier_;
241            }
242
243            Identifier* operator->() const
244            {
245                return this->identifier_;
246            }
247
248            B* fabricate()
249            {
250                BaseObject* newObject = this->identifier_->fabricate();
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
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.