| 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 |  | 
|---|
| 13 | namespace 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 BaseIdentifier; | 
|---|
| 27 |  | 
|---|
| 28 |         public: | 
|---|
| 29 |             virtual void removeObject(OrxonoxClass* object) {}; | 
|---|
| 30 |  | 
|---|
| 31 |             virtual BaseObject* fabricate() {}; | 
|---|
| 32 |  | 
|---|
| 33 |             bool isA(Identifier* identifier); | 
|---|
| 34 |             bool isDirectlyA(Identifier* identifier); | 
|---|
| 35 |             bool isChildOf(Identifier* identifier); | 
|---|
| 36 |             bool isDirectChildOf(Identifier* identifier); | 
|---|
| 37 |             bool isParentOf(Identifier* identifier); | 
|---|
| 38 |             bool isDirectParentOf(Identifier* identifier); | 
|---|
| 39 |  | 
|---|
| 40 |             std::string getName() { return this->name_; } | 
|---|
| 41 |             IdentifierList* getDirectParents() { return &(this->directParents_); } | 
|---|
| 42 |             IdentifierList* getAllParents() { return &(this->allParents_); } | 
|---|
| 43 |             IdentifierList* getDirectChildren() { return &(this->directChildren_); } | 
|---|
| 44 |             IdentifierList* getAllChildren() { return &(this->allChildren_); } | 
|---|
| 45 |  | 
|---|
| 46 |             static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); } | 
|---|
| 47 |  | 
|---|
| 48 |         private: | 
|---|
| 49 |             Identifier(); | 
|---|
| 50 |             Identifier(const Identifier& identifier) {} | 
|---|
| 51 |             virtual ~Identifier(); | 
|---|
| 52 |             void initialize(IdentifierList* parents); | 
|---|
| 53 |  | 
|---|
| 54 |             static void startCreatingHierarchy() | 
|---|
| 55 |             { | 
|---|
| 56 |                 hierarchyCreatingCounter_s++; | 
|---|
| 57 | #if HIERARCHY_VERBOSE | 
|---|
| 58 |                 std::cout << "*** Increased Hierarchy-Creating-Counter to " << hierarchyCreatingCounter_s << "\n"; | 
|---|
| 59 | #endif | 
|---|
| 60 |             } | 
|---|
| 61 |  | 
|---|
| 62 |             static void stopCreatingHierarchy() | 
|---|
| 63 |             { | 
|---|
| 64 |                 hierarchyCreatingCounter_s--; | 
|---|
| 65 | #if HIERARCHY_VERBOSE | 
|---|
| 66 |                 std::cout << "*** Decreased Hierarchy-Creating-Counter to " << hierarchyCreatingCounter_s << "\n"; | 
|---|
| 67 | #endif | 
|---|
| 68 |             } | 
|---|
| 69 |  | 
|---|
| 70 |             IdentifierList directParents_; | 
|---|
| 71 |             IdentifierList allParents_; | 
|---|
| 72 |             IdentifierList directChildren_; | 
|---|
| 73 |             IdentifierList allChildren_; | 
|---|
| 74 |  | 
|---|
| 75 |             std::string name_; | 
|---|
| 76 |  | 
|---|
| 77 |             bool bIsAbstractClass_; | 
|---|
| 78 |             bool bCreatedOneObject_; | 
|---|
| 79 |  | 
|---|
| 80 |             static int hierarchyCreatingCounter_s; | 
|---|
| 81 |     }; | 
|---|
| 82 |  | 
|---|
| 83 |  | 
|---|
| 84 |     // ############################### | 
|---|
| 85 |     // ###     ClassIdentifier     ### | 
|---|
| 86 |     // ############################### | 
|---|
| 87 |     template <class T> | 
|---|
| 88 |     class ClassIdentifier : public Identifier | 
|---|
| 89 |     { | 
|---|
| 90 |         template <class U> | 
|---|
| 91 |         friend class Iterator; | 
|---|
| 92 |  | 
|---|
| 93 |         public: | 
|---|
| 94 |             static ClassIdentifier<T>* registerClass(IdentifierList* parents, std::string name, bool bRootClass, bool bIsAbstractClass); | 
|---|
| 95 |             static ClassIdentifier<T>* getIdentifier(); | 
|---|
| 96 |             BaseObject* fabricate(); | 
|---|
| 97 |             T* fabricateClass(); | 
|---|
| 98 |             static void addObject(T* object); | 
|---|
| 99 |             void removeObject(OrxonoxClass* object); | 
|---|
| 100 |  | 
|---|
| 101 |         private: | 
|---|
| 102 |             ClassIdentifier(); | 
|---|
| 103 |             ClassIdentifier(const ClassIdentifier<T>& identifier) {} | 
|---|
| 104 |             ~ClassIdentifier(); | 
|---|
| 105 |  | 
|---|
| 106 |             static ClassIdentifier<T>* pointer_s; | 
|---|
| 107 |             ObjectList<T> objects_s; | 
|---|
| 108 |     }; | 
|---|
| 109 |  | 
|---|
| 110 |     template <class T> | 
|---|
| 111 |     ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL; | 
|---|
| 112 |  | 
|---|
| 113 |     template <class T> | 
|---|
| 114 |     ClassIdentifier<T>::ClassIdentifier() | 
|---|
| 115 |     { | 
|---|
| 116 |     } | 
|---|
| 117 |  | 
|---|
| 118 |     template <class T> | 
|---|
| 119 |     ClassIdentifier<T>::~ClassIdentifier() | 
|---|
| 120 |     { | 
|---|
| 121 |         this->pointer_s = NULL; | 
|---|
| 122 |     } | 
|---|
| 123 |  | 
|---|
| 124 |     template <class T> | 
|---|
| 125 |     BaseObject* ClassIdentifier<T>::fabricate() | 
|---|
| 126 |     { | 
|---|
| 127 |         return dynamic_cast<BaseObject*>(this->fabricateClass()); | 
|---|
| 128 |     } | 
|---|
| 129 |  | 
|---|
| 130 |     template <class T> | 
|---|
| 131 |     T* ClassIdentifier<T>::fabricateClass() | 
|---|
| 132 |     { | 
|---|
| 133 |         if (!this->bIsAbstractClass_) | 
|---|
| 134 |         { | 
|---|
| 135 |             return new T; | 
|---|
| 136 |         } | 
|---|
| 137 |         else | 
|---|
| 138 |         { | 
|---|
| 139 |             std::cout << "Error: Couldn't create a new Object - Class " << this->name_ << " is abstract!\n"; | 
|---|
| 140 |             std::cout << "Aborting...\n"; | 
|---|
| 141 |             abort(); | 
|---|
| 142 |         } | 
|---|
| 143 |     } | 
|---|
| 144 |  | 
|---|
| 145 |     template <class T> | 
|---|
| 146 |     ClassIdentifier<T>* ClassIdentifier<T>::registerClass(IdentifierList* parents, std::string name, bool bRootClass, bool bIsAbstractClass) | 
|---|
| 147 |     { | 
|---|
| 148 | #if HIERARCHY_VERBOSE | 
|---|
| 149 |         std::cout << "*** Register Class in " << name << "-Singleton.\n"; | 
|---|
| 150 | #endif | 
|---|
| 151 |         if (!pointer_s) | 
|---|
| 152 |         { | 
|---|
| 153 | #if HIERARCHY_VERBOSE | 
|---|
| 154 |             std::cout << "*** Register Class in " << name << "-Singleton -> Create Singleton.\n"; | 
|---|
| 155 | #endif | 
|---|
| 156 |             if (parents || bRootClass) | 
|---|
| 157 |             { | 
|---|
| 158 |                 pointer_s = new ClassIdentifier(); | 
|---|
| 159 |                 pointer_s->name_ = name; | 
|---|
| 160 |                 pointer_s->bIsAbstractClass_ = bIsAbstractClass; | 
|---|
| 161 |  | 
|---|
| 162 |                 ClassFactory::add(name, pointer_s); | 
|---|
| 163 |  | 
|---|
| 164 |                 if (!bRootClass) | 
|---|
| 165 |                     pointer_s->initialize(parents); | 
|---|
| 166 |                 else | 
|---|
| 167 |                     pointer_s->initialize(NULL); | 
|---|
| 168 |             } | 
|---|
| 169 |             else | 
|---|
| 170 |             { | 
|---|
| 171 |                 pointer_s = getIdentifier(); | 
|---|
| 172 |             } | 
|---|
| 173 |         } | 
|---|
| 174 |  | 
|---|
| 175 |         return pointer_s; | 
|---|
| 176 |     } | 
|---|
| 177 |  | 
|---|
| 178 |     template <class T> | 
|---|
| 179 |     ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier() | 
|---|
| 180 |     { | 
|---|
| 181 | #if HIERARCHY_VERBOSE | 
|---|
| 182 | //        std::cout << "*** Get Identifier.\n"; | 
|---|
| 183 | #endif | 
|---|
| 184 |         if (!pointer_s) | 
|---|
| 185 |         { | 
|---|
| 186 | #if HIERARCHY_VERBOSE | 
|---|
| 187 |             std::cout << "*** Get Identifier -> Create Class\n"; | 
|---|
| 188 | #endif | 
|---|
| 189 |             Identifier::startCreatingHierarchy(); | 
|---|
| 190 |             T* temp = new T(); | 
|---|
| 191 |             delete temp; | 
|---|
| 192 |             Identifier::stopCreatingHierarchy(); | 
|---|
| 193 |         } | 
|---|
| 194 |  | 
|---|
| 195 |         return pointer_s; | 
|---|
| 196 |     } | 
|---|
| 197 |  | 
|---|
| 198 |     template <class T> | 
|---|
| 199 |     void ClassIdentifier<T>::addObject(T* object) | 
|---|
| 200 |     { | 
|---|
| 201 | #if HIERARCHY_VERBOSE | 
|---|
| 202 |         std::cout << "*** Added object to " << ClassIdentifier<T>::getIdentifier()->getName() << "-list.\n"; | 
|---|
| 203 | #endif | 
|---|
| 204 |         ClassIdentifier<T>::getIdentifier()->objects_s.add(object); | 
|---|
| 205 |     } | 
|---|
| 206 |  | 
|---|
| 207 |     template <class T> | 
|---|
| 208 |     void ClassIdentifier<T>::removeObject(OrxonoxClass* object) | 
|---|
| 209 |     { | 
|---|
| 210 |         bool bIterateForwards = !Identifier::isCreatingHierarchy(); | 
|---|
| 211 |  | 
|---|
| 212 | #if HIERARCHY_VERBOSE | 
|---|
| 213 |         if (bIterateForwards) | 
|---|
| 214 |             std::cout << "*** Removed object from " << this->name_ << "-list, iterating forwards.\n"; | 
|---|
| 215 |         else | 
|---|
| 216 |             std::cout << "*** Removed object from " << this->name_ << "-list, iterating backwards.\n"; | 
|---|
| 217 | #endif | 
|---|
| 218 |  | 
|---|
| 219 |         this->objects_s.remove(object, bIterateForwards); | 
|---|
| 220 |  | 
|---|
| 221 |         IdentifierListElement* temp = this->directParents_.first_; | 
|---|
| 222 |         while (temp) | 
|---|
| 223 |         { | 
|---|
| 224 |             temp->identifier_->removeObject(object); | 
|---|
| 225 |             temp = temp->next_; | 
|---|
| 226 |         } | 
|---|
| 227 |     } | 
|---|
| 228 |  | 
|---|
| 229 |  | 
|---|
| 230 |     // ############################### | 
|---|
| 231 |     // ###     BaseIdentifier      ### | 
|---|
| 232 |     // ############################### | 
|---|
| 233 |     template <class B> | 
|---|
| 234 |     class BaseIdentifier | 
|---|
| 235 |     { | 
|---|
| 236 |         public: | 
|---|
| 237 |             BaseIdentifier(); | 
|---|
| 238 |  | 
|---|
| 239 |             BaseIdentifier<B>& operator=(Identifier* identifier) | 
|---|
| 240 |             { | 
|---|
| 241 |                 if (!identifier->isA(ClassIdentifier<B>::getIdentifier())) | 
|---|
| 242 |                 { | 
|---|
| 243 |                     std::cout << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n"; | 
|---|
| 244 |                     std::cout << "Error: BaseIdentifier<" << ClassIdentifier<B>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden.\n"; | 
|---|
| 245 |                     std::cout << "Aborting...\n"; | 
|---|
| 246 |                     abort(); | 
|---|
| 247 |                 } | 
|---|
| 248 |                 this->identifier_ = identifier; | 
|---|
| 249 |                 return *this; | 
|---|
| 250 |             } | 
|---|
| 251 |  | 
|---|
| 252 |             Identifier* operator*() | 
|---|
| 253 |             { | 
|---|
| 254 |                 return this->identifier_; | 
|---|
| 255 |             } | 
|---|
| 256 |  | 
|---|
| 257 |             Identifier* operator->() const | 
|---|
| 258 |             { | 
|---|
| 259 |                 return this->identifier_; | 
|---|
| 260 |             } | 
|---|
| 261 |  | 
|---|
| 262 |             B* fabricate() | 
|---|
| 263 |             { | 
|---|
| 264 |                 BaseObject* newObject = this->identifier_->fabricate(); | 
|---|
| 265 |                 if (newObject) | 
|---|
| 266 |                 { | 
|---|
| 267 |                     return dynamic_cast<B*>(newObject); | 
|---|
| 268 |                 } | 
|---|
| 269 |                 else | 
|---|
| 270 |                 { | 
|---|
| 271 |                     if (this->identifier_) | 
|---|
| 272 |                     { | 
|---|
| 273 |                         std::cout << "Error: Class " << this->identifier_->getName() << " is not a " << ClassIdentifier<B>::getIdentifier()->getName() << "!\n"; | 
|---|
| 274 |                         std::cout << "Error: Couldn't fabricate a new Object.\n"; | 
|---|
| 275 |                         std::cout << "Aborting...\n"; | 
|---|
| 276 |                     } | 
|---|
| 277 |                     else | 
|---|
| 278 |                     { | 
|---|
| 279 |                         std::cout << "Error: Couldn't fabricate a new Object - Identifier is undefined.\n"; | 
|---|
| 280 |                         std::cout << "Aborting...\n"; | 
|---|
| 281 |                     } | 
|---|
| 282 |  | 
|---|
| 283 |                     abort(); | 
|---|
| 284 |                 } | 
|---|
| 285 |             } | 
|---|
| 286 |  | 
|---|
| 287 |             inline Identifier* getIdentifier() | 
|---|
| 288 |                 { return this->identifier_; } | 
|---|
| 289 |             inline bool isA(Identifier* identifier) | 
|---|
| 290 |                 { return this->identifier_->isA(identifier); } | 
|---|
| 291 |             inline bool isDirectlyA(Identifier* identifier) | 
|---|
| 292 |                 { return this->identifier_->isDirectlyA(identifier); } | 
|---|
| 293 |             inline bool isChildOf(Identifier* identifier) | 
|---|
| 294 |                 { return this->identifier_->isChildOf(identifier); } | 
|---|
| 295 |             inline bool isDirectChildOf(Identifier* identifier) | 
|---|
| 296 |                 { return this->identifier_->isDirectChildOf(identifier); } | 
|---|
| 297 |             inline bool isParentOf(Identifier* identifier) | 
|---|
| 298 |                 { return this->identifier_->isParentOf(identifier); } | 
|---|
| 299 |             inline bool isDirectParentOf(Identifier* identifier) | 
|---|
| 300 |                 { return this->identifier_->isDirectParentOf(identifier); } | 
|---|
| 301 |  | 
|---|
| 302 |         private: | 
|---|
| 303 |             Identifier* identifier_; | 
|---|
| 304 |     }; | 
|---|
| 305 |  | 
|---|
| 306 |     template <class B> | 
|---|
| 307 |     BaseIdentifier<B>::BaseIdentifier() | 
|---|
| 308 |     { | 
|---|
| 309 |         this->identifier_ = ClassIdentifier<B>::getIdentifier(); | 
|---|
| 310 |     } | 
|---|
| 311 | } | 
|---|
| 312 |  | 
|---|
| 313 | #endif | 
|---|