Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/core/Identifier.h @ 632

Last change on this file since 632 was 258, checked in by landauf, 17 years ago

merged object-hierarchy back to trunk

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