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
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"
[218]8#include "Factory.h"
[197]9
[244]10#define HIERARCHY_VERBOSE true
[219]11
12
[197]13namespace orxonox
14{
[219]15    class BaseObject;
16
[224]17    // ###############################
18    // ###       Identifier        ###
19    // ###############################
[197]20    class Identifier
21    {
22        template <class T>
23        friend class ClassIdentifier;
24
25        template <class T>
[242]26        friend class SubclassIdentifier;
[197]27
[244]28        template <class T>
29        friend class ClassFactory;
30
[197]31        public:
[239]32            virtual void removeObject(OrxonoxClass* object) const = 0;
[243]33            virtual void removeObjectIntern(OrxonoxClass* object, bool bIterateForwards) const = 0;
[197]34
[244]35            inline void addFactory(BaseFactory* factory) { this->factory_ = factory; }
36            BaseObject* fabricate();
[218]37
[239]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;
[197]42
[244]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_; }
[197]46
[244]47            inline static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); }
[219]48
[197]49        private:
50            Identifier();
51            Identifier(const Identifier& identifier) {}
52            virtual ~Identifier();
[239]53            void initialize(const IdentifierList* parents);
[197]54
[244]55            inline static void startCreatingHierarchy()
[231]56            {
57                hierarchyCreatingCounter_s++;
58#if HIERARCHY_VERBOSE
59                std::cout << "*** Increased Hierarchy-Creating-Counter to " << hierarchyCreatingCounter_s << "\n";
60#endif
61            }
[197]62
[244]63            inline static void stopCreatingHierarchy()
[231]64            {
65                hierarchyCreatingCounter_s--;
66#if HIERARCHY_VERBOSE
67                std::cout << "*** Decreased Hierarchy-Creating-Counter to " << hierarchyCreatingCounter_s << "\n";
68#endif
69            }
70
[243]71            IdentifierList parents_;
72            IdentifierList* children_;
[219]73
[197]74            std::string name_;
75
[244]76            BaseFactory* factory_;
[197]77            bool bCreatedOneObject_;
[219]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:
[244]92            static ClassIdentifier<T>* registerClass(const IdentifierList* parents, const std::string& name, bool bRootClass);
[197]93            static ClassIdentifier<T>* getIdentifier();
[224]94            static void addObject(T* object);
[239]95            void removeObject(OrxonoxClass* object) const;
[243]96            void removeObjectIntern(OrxonoxClass* object, bool bIterateForwards) const;
[197]97
98        private:
99            ClassIdentifier();
100            ClassIdentifier(const ClassIdentifier<T>& identifier) {}
101            ~ClassIdentifier();
102
[219]103            static ClassIdentifier<T>* pointer_s;
[239]104            ObjectList<T>* objects_;
[197]105    };
106
107    template <class T>
[219]108    ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL;
[197]109
110    template <class T>
111    ClassIdentifier<T>::ClassIdentifier()
112    {
[239]113        this->objects_ = new ObjectList<T>;
[197]114    }
115
116    template <class T>
117    ClassIdentifier<T>::~ClassIdentifier()
118    {
[239]119        delete this->objects_;
[219]120        this->pointer_s = NULL;
[197]121    }
122
123    template <class T>
[244]124    ClassIdentifier<T>* ClassIdentifier<T>::registerClass(const IdentifierList* parents, const std::string& name, bool bRootClass)
[218]125    {
[231]126#if HIERARCHY_VERBOSE
[197]127        std::cout << "*** Register Class in " << name << "-Singleton.\n";
[231]128#endif
[219]129        if (!pointer_s)
[197]130        {
[231]131#if HIERARCHY_VERBOSE
[197]132            std::cout << "*** Register Class in " << name << "-Singleton -> Create Singleton.\n";
[231]133#endif
[244]134            pointer_s = new ClassIdentifier();
135        }
[218]136
[244]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);
[218]144
[244]145            if (bRootClass)
146                pointer_s->initialize(NULL);
[197]147            else
[244]148                pointer_s->initialize(parents);
[197]149        }
150
[219]151        return pointer_s;
[197]152    }
153
154    template <class T>
155    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
156    {
[219]157        if (!pointer_s)
[197]158        {
[231]159#if HIERARCHY_VERBOSE
[244]160            std::cout << "*** Create Singleton.\n";
[231]161#endif
[244]162            pointer_s = new ClassIdentifier();
[197]163        }
164
[219]165        return pointer_s;
[197]166    }
167
[224]168    template <class T>
169    void ClassIdentifier<T>::addObject(T* object)
170    {
[231]171#if HIERARCHY_VERBOSE
[224]172        std::cout << "*** Added object to " << ClassIdentifier<T>::getIdentifier()->getName() << "-list.\n";
[231]173#endif
[239]174        ClassIdentifier<T>::getIdentifier()->objects_->add(object);
[224]175    }
176
177    template <class T>
[239]178    void ClassIdentifier<T>::removeObject(OrxonoxClass* object) const
[224]179    {
180        bool bIterateForwards = !Identifier::isCreatingHierarchy();
181
[243]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    {
[231]195#if HIERARCHY_VERBOSE
[224]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";
[231]200#endif
[224]201
[239]202        this->objects_->remove(object, bIterateForwards);
[224]203    }
204
205
206    // ###############################
[242]207    // ###   SubclassIdentifier    ###
[224]208    // ###############################
[197]209    template <class B>
[242]210    class SubclassIdentifier
[197]211    {
212        public:
[242]213            SubclassIdentifier();
[197]214
[242]215            SubclassIdentifier<B>& operator=(Identifier* identifier)
[197]216            {
217                if (!identifier->isA(ClassIdentifier<B>::getIdentifier()))
218                {
219                    std::cout << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n";
[242]220                    std::cout << "Error: SubclassIdentifier<" << ClassIdentifier<B>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden.\n";
[197]221                    std::cout << "Aborting...\n";
222                    abort();
223                }
224                this->identifier_ = identifier;
225                return *this;
226            }
[218]227
[221]228            Identifier* operator*()
[218]229            {
230                return this->identifier_;
231            }
232
[221]233            Identifier* operator->() const
[218]234            {
235                return this->identifier_;
236            }
237
238            B* fabricate()
239            {
[219]240                BaseObject* newObject = this->identifier_->fabricate();
[218]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
[239]263            inline const Identifier* getIdentifier() const
[197]264                { return this->identifier_; }
[239]265            inline bool isA(const Identifier* identifier) const
[197]266                { return this->identifier_->isA(identifier); }
[239]267            inline bool isDirectlyA(const Identifier* identifier) const
[197]268                { return this->identifier_->isDirectlyA(identifier); }
[239]269            inline bool isChildOf(const Identifier* identifier) const
[197]270                { return this->identifier_->isChildOf(identifier); }
[239]271            inline bool isParentOf(const Identifier* identifier) const
[197]272                { return this->identifier_->isParentOf(identifier); }
273
274        private:
275            Identifier* identifier_;
276    };
277
278    template <class B>
[242]279    SubclassIdentifier<B>::SubclassIdentifier()
[197]280    {
281        this->identifier_ = ClassIdentifier<B>::getIdentifier();
282    }
283}
284
285#endif
Note: See TracBrowser for help on using the repository browser.