Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

renamed "BaseIdentifier" to "SubclassIdentifier" to avoid misunderstandings

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