Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 240 was 239, checked in by landauf, 17 years ago

added some "const" qualifiers to the identifier-functions

File size: 10.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
[231]10#define HIERARCHY_VERBOSE false
[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>
26        friend class BaseIdentifier;
27
28        public:
[239]29            virtual void removeObject(OrxonoxClass* object) const = 0;
[197]30
[239]31            virtual BaseObject* fabricate() const = 0;
[218]32
[239]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;
[197]39
[239]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            const IdentifierList* getDirectChildren() const { return this->directChildren_; }
44            const IdentifierList* getAllChildren() const { return this->allChildren_; }
[197]45
[219]46            static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); }
47
[197]48        private:
49            Identifier();
50            Identifier(const Identifier& identifier) {}
51            virtual ~Identifier();
[239]52            void initialize(const IdentifierList* parents);
[197]53
[231]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            }
[197]61
[231]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
[239]70            IdentifierList* directParents_;
71            IdentifierList* allParents_;
72            IdentifierList* directChildren_;
73            IdentifierList* allChildren_;
[219]74
[197]75            std::string name_;
76
77            bool bIsAbstractClass_;
78            bool bCreatedOneObject_;
[219]79
80            static int hierarchyCreatingCounter_s;
[197]81    };
82
83
[224]84    // ###############################
85    // ###     ClassIdentifier     ###
86    // ###############################
[197]87    template <class T>
88    class ClassIdentifier : public Identifier
89    {
[224]90        template <class U>
91        friend class Iterator;
92
[197]93        public:
[239]94            static ClassIdentifier<T>* registerClass(const IdentifierList* parents, const std::string& name, bool bRootClass, bool bIsAbstractClass);
[197]95            static ClassIdentifier<T>* getIdentifier();
[239]96            BaseObject* fabricate() const;
97            T* fabricateClass() const;
[224]98            static void addObject(T* object);
[239]99            void removeObject(OrxonoxClass* object) const;
[197]100
101        private:
102            ClassIdentifier();
103            ClassIdentifier(const ClassIdentifier<T>& identifier) {}
104            ~ClassIdentifier();
105
[219]106            static ClassIdentifier<T>* pointer_s;
[239]107            ObjectList<T>* objects_;
[197]108    };
109
110    template <class T>
[219]111    ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL;
[197]112
113    template <class T>
114    ClassIdentifier<T>::ClassIdentifier()
115    {
[239]116        this->objects_ = new ObjectList<T>;
[197]117    }
118
119    template <class T>
120    ClassIdentifier<T>::~ClassIdentifier()
121    {
[239]122        delete this->objects_;
[219]123        this->pointer_s = NULL;
[197]124    }
125
126    template <class T>
[239]127    BaseObject* ClassIdentifier<T>::fabricate() const
[218]128    {
[219]129        return dynamic_cast<BaseObject*>(this->fabricateClass());
[218]130    }
131
132    template <class T>
[239]133    T* ClassIdentifier<T>::fabricateClass() const
[218]134    {
[219]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        }
[218]145    }
146
147    template <class T>
[239]148    ClassIdentifier<T>* ClassIdentifier<T>::registerClass(const IdentifierList* parents, const std::string& name, bool bRootClass, bool bIsAbstractClass)
[197]149    {
[231]150#if HIERARCHY_VERBOSE
[197]151        std::cout << "*** Register Class in " << name << "-Singleton.\n";
[231]152#endif
[219]153        if (!pointer_s)
[197]154        {
[231]155#if HIERARCHY_VERBOSE
[197]156            std::cout << "*** Register Class in " << name << "-Singleton -> Create Singleton.\n";
[231]157#endif
[197]158            if (parents || bRootClass)
159            {
[219]160                pointer_s = new ClassIdentifier();
161                pointer_s->name_ = name;
162                pointer_s->bIsAbstractClass_ = bIsAbstractClass;
[218]163
[219]164                ClassFactory::add(name, pointer_s);
[218]165
[220]166                if (!bRootClass)
167                    pointer_s->initialize(parents);
168                else
169                    pointer_s->initialize(NULL);
[197]170            }
171            else
172            {
[219]173                pointer_s = getIdentifier();
[197]174            }
175        }
176
[219]177        return pointer_s;
[197]178    }
179
180    template <class T>
181    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
182    {
[231]183#if HIERARCHY_VERBOSE
[197]184//        std::cout << "*** Get Identifier.\n";
[231]185#endif
[219]186        if (!pointer_s)
[197]187        {
[231]188#if HIERARCHY_VERBOSE
[197]189            std::cout << "*** Get Identifier -> Create Class\n";
[231]190#endif
[219]191            Identifier::startCreatingHierarchy();
[197]192            T* temp = new T();
[221]193            delete temp;
[219]194            Identifier::stopCreatingHierarchy();
[197]195        }
196
[219]197        return pointer_s;
[197]198    }
199
[224]200    template <class T>
201    void ClassIdentifier<T>::addObject(T* object)
202    {
[231]203#if HIERARCHY_VERBOSE
[224]204        std::cout << "*** Added object to " << ClassIdentifier<T>::getIdentifier()->getName() << "-list.\n";
[231]205#endif
[239]206        ClassIdentifier<T>::getIdentifier()->objects_->add(object);
[224]207    }
208
209    template <class T>
[239]210    void ClassIdentifier<T>::removeObject(OrxonoxClass* object) const
[224]211    {
212        bool bIterateForwards = !Identifier::isCreatingHierarchy();
213
[231]214#if HIERARCHY_VERBOSE
[224]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";
[231]219#endif
[224]220
[239]221        this->objects_->remove(object, bIterateForwards);
[224]222
[239]223        IdentifierListElement* temp = this->directParents_->first_;
[224]224        while (temp)
225        {
226            temp->identifier_->removeObject(object);
227            temp = temp->next_;
228        }
229    }
230
231
232    // ###############################
233    // ###     BaseIdentifier      ###
234    // ###############################
[197]235    template <class B>
[218]236    class BaseIdentifier
[197]237    {
238        public:
239            BaseIdentifier();
240
[221]241            BaseIdentifier<B>& operator=(Identifier* identifier)
[197]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: BaseIdentifier<" << 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            }
[218]253
[221]254            Identifier* operator*()
[218]255            {
256                return this->identifier_;
257            }
258
[221]259            Identifier* operator->() const
[218]260            {
261                return this->identifier_;
262            }
263
264            B* fabricate()
265            {
[219]266                BaseObject* newObject = this->identifier_->fabricate();
[218]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
[239]289            inline const Identifier* getIdentifier() const
[197]290                { return this->identifier_; }
[239]291            inline bool isA(const Identifier* identifier) const
[197]292                { return this->identifier_->isA(identifier); }
[239]293            inline bool isDirectlyA(const Identifier* identifier) const
[197]294                { return this->identifier_->isDirectlyA(identifier); }
[239]295            inline bool isChildOf(const Identifier* identifier) const
[197]296                { return this->identifier_->isChildOf(identifier); }
[239]297            inline bool isDirectChildOf(const Identifier* identifier) const
[197]298                { return this->identifier_->isDirectChildOf(identifier); }
[239]299            inline bool isParentOf(const Identifier* identifier) const
[197]300                { return this->identifier_->isParentOf(identifier); }
[239]301            inline bool isDirectParentOf(const Identifier* identifier) const
[197]302                { return this->identifier_->isDirectParentOf(identifier); }
303
304        private:
305            Identifier* identifier_;
306    };
307
308    template <class B>
309    BaseIdentifier<B>::BaseIdentifier()
310    {
311        this->identifier_ = ClassIdentifier<B>::getIdentifier();
312    }
313}
314
315#endif
Note: See TracBrowser for help on using the repository browser.