Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/objecthierarchy/src/orxonox/core/Identifier.h @ 362

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

added NetworkID

File size: 8.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 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            inline const unsigned int getNetworkID() const { return this->classID_; }
47            void setNetworkID(unsigned int id);
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            static unsigned int classIDcounter_s;
80            unsigned int classID_;
81    };
82
83
84    // ###############################
85    // ###     ClassIdentifier     ###
86    // ###############################
87    template <class T>
88    class ClassIdentifier : public Identifier
89    {
90        public:
91            static ClassIdentifier<T>* registerClass(const IdentifierList* parents, const std::string& name, bool bRootClass);
92            static ClassIdentifier<T>* getIdentifier();
93            static void addObject(T* object);
94
95        private:
96            ClassIdentifier();
97            ClassIdentifier(const ClassIdentifier<T>& identifier) {}
98            ~ClassIdentifier();
99
100            static ClassIdentifier<T>* pointer_s;
101            ObjectList<T>* objects_;
102    };
103
104    template <class T>
105    ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL;
106
107    template <class T>
108    ClassIdentifier<T>::ClassIdentifier()
109    {
110        this->objects_ = new ObjectList<T>;
111    }
112
113    template <class T>
114    ClassIdentifier<T>::~ClassIdentifier()
115    {
116        delete this->objects_;
117        this->pointer_s = NULL;
118    }
119
120    template <class T>
121    ClassIdentifier<T>* ClassIdentifier<T>::registerClass(const IdentifierList* parents, const std::string& name, bool bRootClass)
122    {
123#if HIERARCHY_VERBOSE
124        std::cout << "*** Register Class in " << name << "-Singleton.\n";
125#endif
126        if (!pointer_s)
127        {
128#if HIERARCHY_VERBOSE
129            std::cout << "*** Register Class in " << name << "-Singleton -> Create Singleton.\n";
130#endif
131            pointer_s = new ClassIdentifier();
132        }
133
134        if (!pointer_s->bCreatedOneObject_)
135        {
136#if HIERARCHY_VERBOSE
137            std::cout << "*** Register Class in " << name << "-Singleton -> Initialize Singleton.\n";
138#endif
139            pointer_s->name_ = name;
140            Factory::add(name, pointer_s);
141
142            if (bRootClass)
143                pointer_s->initialize(NULL);
144            else
145                pointer_s->initialize(parents);
146        }
147
148        return pointer_s;
149    }
150
151    template <class T>
152    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
153    {
154        if (!pointer_s)
155        {
156#if HIERARCHY_VERBOSE
157            std::cout << "*** Create Singleton.\n";
158#endif
159            pointer_s = new ClassIdentifier();
160        }
161
162        return pointer_s;
163    }
164
165    template <class T>
166    void ClassIdentifier<T>::addObject(T* object)
167    {
168#if HIERARCHY_VERBOSE
169        std::cout << "*** Added object to " << ClassIdentifier<T>::getIdentifier()->getName() << "-list.\n";
170#endif
171        object->getMetaList()->add(ClassIdentifier<T>::getIdentifier()->objects_, ClassIdentifier<T>::getIdentifier()->objects_->add(object));
172    }
173
174
175    // ###############################
176    // ###   SubclassIdentifier    ###
177    // ###############################
178    template <class B>
179    class SubclassIdentifier
180    {
181        public:
182            SubclassIdentifier();
183
184            SubclassIdentifier<B>& operator=(Identifier* identifier)
185            {
186                if (!identifier->isA(ClassIdentifier<B>::getIdentifier()))
187                {
188                    std::cout << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n";
189                    std::cout << "Error: SubclassIdentifier<" << ClassIdentifier<B>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden.\n";
190                    std::cout << "Aborting...\n";
191                    abort();
192                }
193                this->identifier_ = identifier;
194                return *this;
195            }
196
197            Identifier* operator*()
198            {
199                return this->identifier_;
200            }
201
202            Identifier* operator->() const
203            {
204                return this->identifier_;
205            }
206
207            B* fabricate()
208            {
209                BaseObject* newObject = this->identifier_->fabricate();
210                if (newObject)
211                {
212                    return dynamic_cast<B*>(newObject);
213                }
214                else
215                {
216                    if (this->identifier_)
217                    {
218                        std::cout << "Error: Class " << this->identifier_->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n";
219                        std::cout << "Error: Couldn't fabricate a new Object.\n";
220                        std::cout << "Aborting...\n";
221                    }
222                    else
223                    {
224                        std::cout << "Error: Couldn't fabricate a new Object - Identifier is undefined.\n";
225                        std::cout << "Aborting...\n";
226                    }
227
228                    abort();
229                }
230            }
231
232            inline const Identifier* getIdentifier() const
233                { return this->identifier_; }
234            inline bool isA(const Identifier* identifier) const
235                { return this->identifier_->isA(identifier); }
236            inline bool isDirectlyA(const Identifier* identifier) const
237                { return this->identifier_->isDirectlyA(identifier); }
238            inline bool isChildOf(const Identifier* identifier) const
239                { return this->identifier_->isChildOf(identifier); }
240            inline bool isParentOf(const Identifier* identifier) const
241                { return this->identifier_->isParentOf(identifier); }
242
243        private:
244            Identifier* identifier_;
245    };
246
247    template <class B>
248    SubclassIdentifier<B>::SubclassIdentifier()
249    {
250        this->identifier_ = ClassIdentifier<B>::getIdentifier();
251    }
252}
253
254#endif
Note: See TracBrowser for help on using the repository browser.