Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 220 was 220, checked in by landauf, 16 years ago
  • fixed a small bug in the object hierarchy
  • new objects are now added to all class-lists they're derived from (until now they were only added to the list of their class). this means: i'm replacing the tree-structure by a mountain-one, which costs more memory but allows faster iteration.
File size: 8.4 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                if (!bRootClass)
152                    pointer_s->initialize(parents);
153                else
154                    pointer_s->initialize(NULL);
155            }
156            else
157            {
158                pointer_s = getIdentifier();
159            }
160        }
161
162        return pointer_s;
163    }
164
165    template <class T>
166    ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
167    {
168//        std::cout << "*** Get Identifier.\n";
169        if (!pointer_s)
170        {
171            std::cout << "*** Get Identifier -> Create Class\n";
172            Identifier::startCreatingHierarchy();
173            T* temp = new T();
174            Identifier::stopCreatingHierarchy();
175            delete temp;
176        }
177
178        return pointer_s;
179    }
180
181    // ##### BaseIdentifier #####
182    template <class B>
183    class BaseIdentifier
184    {
185        public:
186            BaseIdentifier();
187
188            BaseIdentifier<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: BaseIdentifier<" << 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 Identifier* getIdentifier()
237                { return this->identifier_; }
238            inline bool isA(Identifier* identifier)
239                { return this->identifier_->isA(identifier); }
240            inline bool isDirectlyA(Identifier* identifier)
241                { return this->identifier_->isDirectlyA(identifier); }
242            inline bool isChildOf(Identifier* identifier)
243                { return this->identifier_->isChildOf(identifier); }
244            inline bool isDirectChildOf(Identifier* identifier)
245                { return this->identifier_->isDirectChildOf(identifier); }
246            inline bool isParentOf(Identifier* identifier)
247                { return this->identifier_->isParentOf(identifier); }
248            inline bool isDirectParentOf(Identifier* identifier)
249                { return this->identifier_->isDirectParentOf(identifier); }
250
251        private:
252            Identifier* identifier_;
253    };
254
255    template <class B>
256    BaseIdentifier<B>::BaseIdentifier()
257    {
258        this->identifier_ = ClassIdentifier<B>::getIdentifier();
259    }
260}
261
262#endif
Note: See TracBrowser for help on using the repository browser.