Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

reimplementation of the factory and parts of the class-hierarchy-generating-algorithm. interfaces with protected constructors are now allowed.

File size: 9.2 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 true
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        template <class T>
29        friend class ClassFactory;
30
31        public:
32            virtual void removeObject(OrxonoxClass* object) const = 0;
33            virtual void removeObjectIntern(OrxonoxClass* object, bool bIterateForwards) const = 0;
34
35            inline void addFactory(BaseFactory* factory) { this->factory_ = factory; }
36            BaseObject* fabricate();
37
38            bool isA(const Identifier* identifier) const;
39            bool isDirectlyA(const Identifier* identifier) const;
40            bool isChildOf(const Identifier* identifier) const;
41            bool isParentOf(const Identifier* identifier) const;
42
43            inline const std::string& getName() const { return this->name_; }
44            inline const IdentifierList& getParents() const { return this->parents_; }
45            inline IdentifierList& getChildren() const { return *this->children_; }
46
47            inline static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); }
48
49        private:
50            Identifier();
51            Identifier(const Identifier& identifier) {}
52            virtual ~Identifier();
53            void initialize(const IdentifierList* parents);
54
55            inline static void startCreatingHierarchy()
56            {
57                hierarchyCreatingCounter_s++;
58#if HIERARCHY_VERBOSE
59                std::cout << "*** Increased Hierarchy-Creating-Counter to " << hierarchyCreatingCounter_s << "\n";
60#endif
61            }
62
63            inline static void stopCreatingHierarchy()
64            {
65                hierarchyCreatingCounter_s--;
66#if HIERARCHY_VERBOSE
67                std::cout << "*** Decreased Hierarchy-Creating-Counter to " << hierarchyCreatingCounter_s << "\n";
68#endif
69            }
70
71            IdentifierList parents_;
72            IdentifierList* children_;
73
74            std::string name_;
75
76            BaseFactory* factory_;
77            bool bCreatedOneObject_;
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(const IdentifierList* parents, const std::string& name, bool bRootClass);
93            static ClassIdentifier<T>* getIdentifier();
94            static void addObject(T* object);
95            void removeObject(OrxonoxClass* object) const;
96            void removeObjectIntern(OrxonoxClass* object, bool bIterateForwards) const;
97
98        private:
99            ClassIdentifier();
100            ClassIdentifier(const ClassIdentifier<T>& identifier) {}
101            ~ClassIdentifier();
102
103            static ClassIdentifier<T>* pointer_s;
104            ObjectList<T>* objects_;
105    };
106
107    template <class T>
108    ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL;
109
110    template <class T>
111    ClassIdentifier<T>::ClassIdentifier()
112    {
113        this->objects_ = new ObjectList<T>;
114    }
115
116    template <class T>
117    ClassIdentifier<T>::~ClassIdentifier()
118    {
119        delete this->objects_;
120        this->pointer_s = NULL;
121    }
122
123    template <class T>
124    ClassIdentifier<T>* ClassIdentifier<T>::registerClass(const IdentifierList* parents, const std::string& name, bool bRootClass)
125    {
126#if HIERARCHY_VERBOSE
127        std::cout << "*** Register Class in " << name << "-Singleton.\n";
128#endif
129        if (!pointer_s)
130        {
131#if HIERARCHY_VERBOSE
132            std::cout << "*** Register Class in " << name << "-Singleton -> Create Singleton.\n";
133#endif
134            pointer_s = new ClassIdentifier();
135        }
136
137        if (!pointer_s->bCreatedOneObject_)
138        {
139#if HIERARCHY_VERBOSE
140            std::cout << "*** Register Class in " << name << "-Singleton -> Initialize Singleton.\n";
141#endif
142            pointer_s->name_ = name;
143            Factory::add(name, pointer_s);
144
145            if (bRootClass)
146                pointer_s->initialize(NULL);
147            else
148                pointer_s->initialize(parents);
149        }
150
151        return pointer_s;
152    }
153
154    template <class T>
155    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
156    {
157        if (!pointer_s)
158        {
159#if HIERARCHY_VERBOSE
160            std::cout << "*** Create Singleton.\n";
161#endif
162            pointer_s = new ClassIdentifier();
163        }
164
165        return pointer_s;
166    }
167
168    template <class T>
169    void ClassIdentifier<T>::addObject(T* object)
170    {
171#if HIERARCHY_VERBOSE
172        std::cout << "*** Added object to " << ClassIdentifier<T>::getIdentifier()->getName() << "-list.\n";
173#endif
174        ClassIdentifier<T>::getIdentifier()->objects_->add(object);
175    }
176
177    template <class T>
178    void ClassIdentifier<T>::removeObject(OrxonoxClass* object) const
179    {
180        bool bIterateForwards = !Identifier::isCreatingHierarchy();
181
182        this->removeObjectIntern(object, bIterateForwards);
183
184        IdentifierListElement* temp = this->parents_.first_;
185        while (temp)
186        {
187            temp->identifier_->removeObjectIntern(object, bIterateForwards);
188            temp = temp->next_;
189        }
190    }
191
192    template <class T>
193    void ClassIdentifier<T>::removeObjectIntern(OrxonoxClass* object, bool bIterateForwards) const
194    {
195#if HIERARCHY_VERBOSE
196        if (bIterateForwards)
197            std::cout << "*** Removed object from " << this->name_ << "-list, iterating forwards.\n";
198        else
199            std::cout << "*** Removed object from " << this->name_ << "-list, iterating backwards.\n";
200#endif
201
202        this->objects_->remove(object, bIterateForwards);
203    }
204
205
206    // ###############################
207    // ###   SubclassIdentifier    ###
208    // ###############################
209    template <class B>
210    class SubclassIdentifier
211    {
212        public:
213            SubclassIdentifier();
214
215            SubclassIdentifier<B>& operator=(Identifier* identifier)
216            {
217                if (!identifier->isA(ClassIdentifier<B>::getIdentifier()))
218                {
219                    std::cout << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n";
220                    std::cout << "Error: SubclassIdentifier<" << ClassIdentifier<B>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden.\n";
221                    std::cout << "Aborting...\n";
222                    abort();
223                }
224                this->identifier_ = identifier;
225                return *this;
226            }
227
228            Identifier* operator*()
229            {
230                return this->identifier_;
231            }
232
233            Identifier* operator->() const
234            {
235                return this->identifier_;
236            }
237
238            B* fabricate()
239            {
240                BaseObject* newObject = this->identifier_->fabricate();
241                if (newObject)
242                {
243                    return dynamic_cast<B*>(newObject);
244                }
245                else
246                {
247                    if (this->identifier_)
248                    {
249                        std::cout << "Error: Class " << this->identifier_->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n";
250                        std::cout << "Error: Couldn't fabricate a new Object.\n";
251                        std::cout << "Aborting...\n";
252                    }
253                    else
254                    {
255                        std::cout << "Error: Couldn't fabricate a new Object - Identifier is undefined.\n";
256                        std::cout << "Aborting...\n";
257                    }
258
259                    abort();
260                }
261            }
262
263            inline const Identifier* getIdentifier() const
264                { return this->identifier_; }
265            inline bool isA(const Identifier* identifier) const
266                { return this->identifier_->isA(identifier); }
267            inline bool isDirectlyA(const Identifier* identifier) const
268                { return this->identifier_->isDirectlyA(identifier); }
269            inline bool isChildOf(const Identifier* identifier) const
270                { return this->identifier_->isChildOf(identifier); }
271            inline bool isParentOf(const Identifier* identifier) const
272                { return this->identifier_->isParentOf(identifier); }
273
274        private:
275            Identifier* identifier_;
276    };
277
278    template <class B>
279    SubclassIdentifier<B>::SubclassIdentifier()
280    {
281        this->identifier_ = ClassIdentifier<B>::getIdentifier();
282    }
283}
284
285#endif
Note: See TracBrowser for help on using the repository browser.