Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 219 was 219, checked in by landauf, 16 years ago
  • removed the "ClassHierarchy" manager-class and put its sole feature (bIsCreatingClassHierarchy_) directly into the Identifier.
  • added a dynamic_cast from OrxonoxClass to BaseObject to the Factory. OrxonoxClass is needed because several classes use Interfaces, but all classes are derived at least from BaseObject, so the cast will work.
File size: 8.3 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 "OrxonoxClass.h"
9#include "Factory.h"
10
11// DONE AND TESTED:
12// - build class hierarchy
13// - isA, isChildOf, ...
14// - insert into class-lists
15// - ClassIdentifier
16// - BaseIdentifier
17// - Factory
18
19// IN WORK:
20
21// TO DO:
22// - iterate through lists
23
24namespace orxonox
25{
26    class BaseObject;
27
28    // ##### Identifier #####
29    class Identifier
30    {
31        template <class T>
32        friend class ClassIdentifier;
33
34        template <class T>
35        friend class BaseIdentifier;
36
37        public:
38            void addObject(OrxonoxClass* object);
39            void removeObject(OrxonoxClass* object);
40
41            virtual BaseObject* fabricate() {};
42
43            bool isA(Identifier* identifier);
44            bool isDirectlyA(Identifier* identifier);
45            bool isChildOf(Identifier* identifier);
46            bool isDirectChildOf(Identifier* identifier);
47            bool isParentOf(Identifier* identifier);
48            bool isDirectParentOf(Identifier* identifier);
49
50            std::string getName() { return this->name_; }
51            IdentifierList* getDirectParents() { return &(this->directParents_); }
52            IdentifierList* getAllParents() { return &(this->allParents_); }
53            IdentifierList* getDirectChildren() { return &(this->directChildren_); }
54            IdentifierList* getAllChildren() { return &(this->allChildren_); }
55
56            static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); }
57
58        private:
59            Identifier();
60            Identifier(const Identifier& identifier) {}
61            virtual ~Identifier();
62            void initialize(IdentifierList* parents);
63
64            static void startCreatingHierarchy() { hierarchyCreatingCounter_s++; std::cout << "*** Increased Hierarchy-Creating-Counter to " << hierarchyCreatingCounter_s << "\n"; }
65            static void stopCreatingHierarchy() { hierarchyCreatingCounter_s--; std::cout << "*** Decreased Hierarchy-Creating-Counter to " << hierarchyCreatingCounter_s << "\n"; }
66
67            IdentifierList directParents_;
68            IdentifierList allParents_;
69            IdentifierList directChildren_;
70            IdentifierList allChildren_;
71
72            ObjectList objects_;
73            std::string name_;
74
75            bool bIsAbstractClass_;
76            bool bCreatedOneObject_;
77
78            static int hierarchyCreatingCounter_s;
79    };
80
81
82    // ##### ClassIdentifier #####
83    template <class T>
84    class ClassIdentifier : public Identifier
85    {
86        public:
87            static ClassIdentifier<T>* registerClass(IdentifierList* parents, std::string name, bool bRootClass, bool bIsAbstractClass);
88            static ClassIdentifier<T>* getIdentifier();
89            BaseObject* fabricate();
90            T* fabricateClass();
91
92        private:
93            ClassIdentifier();
94            ClassIdentifier(const ClassIdentifier<T>& identifier) {}
95            ~ClassIdentifier();
96
97            static ClassIdentifier<T>* pointer_s;
98
99    };
100
101    template <class T>
102    ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL;
103
104    template <class T>
105    ClassIdentifier<T>::ClassIdentifier()
106    {
107    }
108
109    template <class T>
110    ClassIdentifier<T>::~ClassIdentifier()
111    {
112        this->pointer_s = NULL;
113    }
114
115    template <class T>
116    BaseObject* ClassIdentifier<T>::fabricate()
117    {
118        return dynamic_cast<BaseObject*>(this->fabricateClass());
119    }
120
121    template <class T>
122    T* ClassIdentifier<T>::fabricateClass()
123    {
124        if (!this->bIsAbstractClass_)
125        {
126            return new T;
127        }
128        else
129        {
130            std::cout << "Error: Couldn't create a new Object - Class " << this->name_ << " is abstract!\n";
131            std::cout << "Aborting...\n";
132            abort();
133        }
134    }
135
136    template <class T>
137    ClassIdentifier<T>* ClassIdentifier<T>::registerClass(IdentifierList* parents, std::string name, bool bRootClass, bool bIsAbstractClass)
138    {
139        std::cout << "*** Register Class in " << name << "-Singleton.\n";
140        if (!pointer_s)
141        {
142            std::cout << "*** Register Class in " << name << "-Singleton -> Create Singleton.\n";
143            if (parents || bRootClass)
144            {
145                pointer_s = new ClassIdentifier();
146                pointer_s->name_ = name;
147                pointer_s->bIsAbstractClass_ = bIsAbstractClass;
148
149                ClassFactory::add(name, pointer_s);
150
151                pointer_s->initialize(parents);
152            }
153            else
154            {
155                pointer_s = getIdentifier();
156            }
157        }
158
159        return pointer_s;
160    }
161
162    template <class T>
163    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
164    {
165//        std::cout << "*** Get Identifier.\n";
166        if (!pointer_s)
167        {
168            std::cout << "*** Get Identifier -> Create Class\n";
169            Identifier::startCreatingHierarchy();
170            T* temp = new T();
171            Identifier::stopCreatingHierarchy();
172            delete temp;
173        }
174
175        return pointer_s;
176    }
177
178    // ##### BaseIdentifier #####
179    template <class B>
180    class BaseIdentifier
181    {
182        public:
183            BaseIdentifier();
184
185            BaseIdentifier<B>& operator= (Identifier* identifier)
186            {
187                if (!identifier->isA(ClassIdentifier<B>::getIdentifier()))
188                {
189                    std::cout << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n";
190                    std::cout << "Error: BaseIdentifier<" << ClassIdentifier<B>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden.\n";
191                    std::cout << "Aborting...\n";
192                    abort();
193                }
194                this->identifier_ = identifier;
195                return *this;
196            }
197
198            Identifier* operator* ()
199            {
200                return this->identifier_;
201            }
202
203            Identifier* operator-> () const
204            {
205                return this->identifier_;
206            }
207
208            B* fabricate()
209            {
210                BaseObject* newObject = this->identifier_->fabricate();
211                if (newObject)
212                {
213                    return dynamic_cast<B*>(newObject);
214                }
215                else
216                {
217                    if (this->identifier_)
218                    {
219                        std::cout << "Error: Class " << this->identifier_->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n";
220                        std::cout << "Error: Couldn't fabricate a new Object.\n";
221                        std::cout << "Aborting...\n";
222                    }
223                    else
224                    {
225                        std::cout << "Error: Couldn't fabricate a new Object - Identifier is undefined.\n";
226                        std::cout << "Aborting...\n";
227                    }
228
229                    abort();
230                }
231            }
232
233            inline Identifier* getIdentifier()
234                { return this->identifier_; }
235            inline bool isA(Identifier* identifier)
236                { return this->identifier_->isA(identifier); }
237            inline bool isDirectlyA(Identifier* identifier)
238                { return this->identifier_->isDirectlyA(identifier); }
239            inline bool isChildOf(Identifier* identifier)
240                { return this->identifier_->isChildOf(identifier); }
241            inline bool isDirectChildOf(Identifier* identifier)
242                { return this->identifier_->isDirectChildOf(identifier); }
243            inline bool isParentOf(Identifier* identifier)
244                { return this->identifier_->isParentOf(identifier); }
245            inline bool isDirectParentOf(Identifier* identifier)
246                { return this->identifier_->isDirectParentOf(identifier); }
247
248        private:
249            Identifier* identifier_;
250    };
251
252    template <class B>
253    BaseIdentifier<B>::BaseIdentifier()
254    {
255        this->identifier_ = ClassIdentifier<B>::getIdentifier();
256    }
257}
258
259#endif
Note: See TracBrowser for help on using the repository browser.