Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/FICN/src/orxonox/core/Identifier.h @ 382

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