Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

removed the "directParent" feature - it was a clever but unnecessary feature.

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