Changeset 384 for code/branches/FICN/src/orxonox/core/Identifier.h
- Timestamp:
- Dec 4, 2007, 11:48:28 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/FICN/src/orxonox/core/Identifier.h
r367 r384 1 /*! 2 @file Identifier.h 3 @brief Definition of the Identifier, ClassIdentifier and SubclassIdentifier classes. 4 5 The Identifier contains all needed informations about the class it belongs to: 6 - the name 7 - a list with all objects 8 - parents and childs 9 - the factory, if available 10 - the networkID that can be synchronised with the server 11 12 Every object has a pointer to the Identifier of its class. This allows the use isA(...), 13 isDirectlyA(...), isChildOf(...) and isParentOf(...). 14 15 To create the class-hierarchy, the Identifier has some intern functions and variables. 16 17 Every Identifier is in fact a ClassIdentifier, but they are derived from Identifier. 18 19 SubclassIdentifier is a separated class, acting like an Identifier, but has a given class. 20 You can only assign Identifiers of the given class or a derivative to a SubclassIdentifier. 21 */ 22 1 23 #ifndef _Identifier_H__ 2 24 #define _Identifier_H__ … … 8 30 #include "Factory.h" 9 31 10 #ifdef WIN3211 #define HIERARCHY_VERBOSE 012 #else13 32 #define HIERARCHY_VERBOSE false 14 #endif15 33 16 34 17 35 namespace orxonox 18 36 { 19 class BaseObject; 37 class BaseObject; // Forward declaration 20 38 21 39 // ############################### 22 40 // ### Identifier ### 23 41 // ############################### 42 //! The Identifier is used to identify the class of an object and to store informations about the class. 43 /** 44 The Identifier contains all needed informations about the class it belongs to: 45 - the name 46 - a list with all objects 47 - parents and childs 48 - the factory, if available 49 - the networkID that can be synchronised with the server 50 51 Every object has a pointer to the Identifier of its class. This allows the use isA(...), 52 isDirectlyA(...), isChildOf(...) and isParentOf(...). 53 54 You can't directly create an Identifier, it's just the base-class for ClassIdentifier. 55 */ 24 56 class Identifier 25 57 { 26 58 template <class T> 27 friend class ClassIdentifier; 59 friend class ClassIdentifier; // Forward declaration 28 60 29 61 template <class T> 30 friend class SubclassIdentifier; 62 friend class SubclassIdentifier; // Forward declaration 31 63 32 64 template <class T> 33 friend class ClassFactory; 65 friend class ClassFactory; // Forward declaration 34 66 35 67 public: 68 /** @brief Sets the Factory. @param facotry The factory to assign */ 36 69 inline void addFactory(BaseFactory* factory) { this->factory_ = factory; } 70 37 71 BaseObject* fabricate(); 38 72 … … 42 76 bool isParentOf(const Identifier* identifier) const; 43 77 78 /** @returns the name of the class the Identifier belongs to. */ 44 79 inline const std::string& getName() const { return this->name_; } 80 81 /** @returns the parents of the class the Identifier belongs to. */ 45 82 inline const IdentifierList& getParents() const { return this->parents_; } 83 84 /** @returns the children of the class the Identifier belongs to. */ 46 85 inline IdentifierList& getChildren() const { return *this->children_; } 47 86 87 /** @returns true, if a branch of the class-hierarchy is getting created, causing all new objects to store their parents. */ 48 88 inline static bool isCreatingHierarchy() { return (hierarchyCreatingCounter_s > 0); } 49 89 90 /** @returns the NetworkID to identify a class through the network. */ 50 91 inline const unsigned int getNetworkID() const { return this->classID_; } 92 51 93 void setNetworkID(unsigned int id); 52 94 53 95 private: 54 96 Identifier(); 55 Identifier(const Identifier& identifier) {} 97 Identifier(const Identifier& identifier) {} // don't copy 56 98 virtual ~Identifier(); 57 99 void initialize(const IdentifierList* parents); 58 100 101 /** 102 @brief Increases the hierarchyCreatingCounter_s variable, causing all new objects to store their parents. 103 */ 59 104 inline static void startCreatingHierarchy() 60 105 { … … 65 110 } 66 111 112 /** 113 @brief Decreases the hierarchyCreatingCounter_s variable, causing the objects to stop storing their parents. 114 */ 67 115 inline static void stopCreatingHierarchy() 68 116 { … … 73 121 } 74 122 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_; 123 IdentifierList parents_; //!< The Parents of the class the Identifier belongs to 124 IdentifierList* children_; //!< The Children of the class the Identifier belongs to 125 126 std::string name_; //!< The name of the class the Identifier belongs to 127 128 BaseFactory* factory_; //!< The Factory, able to create new objects of the given class 129 bool bCreatedOneObject_; //!< True if at least one object of the given type was created (used to determine the need of storing the parents) 130 static int hierarchyCreatingCounter_s; //!< Bigger than zero if at least one Identifier stores its parents (its an int instead of a bool to avoid conflicts with multithreading) 131 static unsigned int classIDcounter_s; //!< The number of unique Identifiers 132 unsigned int classID_; //!< The networkID to identify a class through the network 85 133 }; 86 134 … … 89 137 // ### ClassIdentifier ### 90 138 // ############################### 139 //! The ClassIdentifier is derived from Identifier and holds all class-specific functions and variables the Identifier cannot have. 140 /** 141 ClassIdentifier is a Singleton, which means that only one object of a given type T exists. 142 This makes it possible to store informations about a class, sharing them with all 143 objects of that class without defining static variables in every class. 144 */ 91 145 template <class T> 92 146 class ClassIdentifier : public Identifier … … 99 153 private: 100 154 ClassIdentifier(); 101 ClassIdentifier(const ClassIdentifier<T>& identifier) {} 155 ClassIdentifier(const ClassIdentifier<T>& identifier) {} // don't copy 102 156 ~ClassIdentifier(); 103 157 104 static ClassIdentifier<T>* pointer_s; 105 ObjectList<T>* objects_; 158 static ClassIdentifier<T>* pointer_s; //!< A pointer to the singleton-object 159 ObjectList<T>* objects_; //!< The ObjectList, containing all objects of type T 106 160 }; 107 161 108 162 template <class T> 109 ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL; 110 163 ClassIdentifier<T>* ClassIdentifier<T>::pointer_s = NULL; // Set the static member variable pointer_s to zero 164 165 /** 166 @brief Constructor: Create the ObjectList. 167 */ 111 168 template <class T> 112 169 ClassIdentifier<T>::ClassIdentifier() … … 115 172 } 116 173 174 /** 175 @brief Destructor: Delete the ObjectList, set the singleton-pointer to zero. 176 */ 117 177 template <class T> 118 178 ClassIdentifier<T>::~ClassIdentifier() … … 122 182 } 123 183 184 /** 185 @brief Registers a class, which means that the name and the parents get stored. 186 @param parents An IdentifierList, containing the Identifiers of all parents of the class 187 @param name A string, containing exactly the name of the class 188 @param bRootClass True if the class is either an Interface or BaseObject itself 189 @return The ClassIdentifier itself 190 */ 124 191 template <class T> 125 192 ClassIdentifier<T>* ClassIdentifier<T>::registerClass(const IdentifierList* parents, const std::string& name, bool bRootClass) … … 128 195 std::cout << "*** Register Class in " << name << "-Singleton.\n"; 129 196 #endif 197 198 // It's a singleton, so maybe we have to create it first 130 199 if (!pointer_s) 131 200 { … … 136 205 } 137 206 207 // Check if at least one object of the given type was created 138 208 if (!pointer_s->bCreatedOneObject_) 139 209 { 210 // If no: We have to store the informations and initialize the Identifier 211 140 212 #if HIERARCHY_VERBOSE 141 213 std::cout << "*** Register Class in " << name << "-Singleton -> Initialize Singleton.\n"; 142 214 #endif 143 215 pointer_s->name_ = name; 144 Factory::add(name, pointer_s); 216 Factory::add(name, pointer_s); // Add the Identifier to the Factory 145 217 146 218 if (bRootClass) 147 pointer_s->initialize(NULL); 219 pointer_s->initialize(NULL); // If a class is derived from two interfaces, the second interface might think it's derived from the first because of the order of constructor-calls. Thats why we set parents to zero in that case. 148 220 else 149 221 pointer_s->initialize(parents); … … 153 225 } 154 226 227 /** 228 @returns the Identifier itself 229 */ 155 230 template <class T> 156 231 ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier() … … 167 242 } 168 243 244 /** 245 @brief Adds an object of the given type to the ObjectList. 246 @param object The object to add 247 */ 169 248 template <class T> 170 249 void ClassIdentifier<T>::addObject(T* object) … … 173 252 std::cout << "*** Added object to " << ClassIdentifier<T>::getIdentifier()->getName() << "-list.\n"; 174 253 #endif 175 object->getMetaList() ->add(ClassIdentifier<T>::getIdentifier()->objects_, ClassIdentifier<T>::getIdentifier()->objects_->add(object));254 object->getMetaList().add(ClassIdentifier<T>::getIdentifier()->objects_, ClassIdentifier<T>::getIdentifier()->objects_->add(object)); 176 255 } 177 256 … … 180 259 // ### SubclassIdentifier ### 181 260 // ############################### 182 template <class B> 261 //! The SubclassIdentifier acts almost like an Identifier, but has some prerequisites. 262 /** 263 You can only assign Identifiers that belong to a class of at least B (or derived) to a SubclassIdentifier<T>. 264 If you assign something else, the program aborts. 265 Because we know the minimal type, a dynamic_cast is done, which makes it easier to create a new object. 266 */ 267 template <class T> 183 268 class SubclassIdentifier 184 269 { 185 270 public: 186 SubclassIdentifier(); 187 188 SubclassIdentifier<B>& operator=(Identifier* identifier) 189 { 190 if (!identifier->isA(ClassIdentifier<B>::getIdentifier())) 271 /** 272 @brief Constructor: Automaticaly assigns the Identifier of the given class. 273 */ 274 SubclassIdentifier() 275 { 276 this->identifier_ = ClassIdentifier<T>::getIdentifier(); 277 } 278 279 /** 280 @brief Overloading of the = operator: assigns the identifier and checks its type. 281 @param identifier The Identifier to assign 282 @return The SubclassIdentifier itself 283 */ 284 SubclassIdentifier<T>& operator=(Identifier* identifier) 285 { 286 if (!identifier->isA(ClassIdentifier<T>::getIdentifier())) 191 287 { 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";288 std::cout << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << "!\n"; 289 std::cout << "Error: SubclassIdentifier<" << ClassIdentifier<T>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden.\n"; 194 290 std::cout << "Aborting...\n"; 195 291 abort(); … … 199 295 } 200 296 297 /** 298 @brief Overloading of the * operator: returns the assigned identifier. 299 @return The assigned identifier 300 */ 201 301 Identifier* operator*() 202 302 { … … 204 304 } 205 305 306 /** 307 @brief Overloading of the -> operator: returns the assigned identifier. 308 @return The assigned identifier 309 */ 206 310 Identifier* operator->() const 207 311 { … … 209 313 } 210 314 211 B* fabricate() 315 /** 316 @brief Creates a new object of the type of the assigned identifier and dynamic_casts it to the minimal type given by the SubclassIdentifier. 317 @return The new object 318 */ 319 T* fabricate() 212 320 { 213 321 BaseObject* newObject = this->identifier_->fabricate(); 322 323 // Check if the creation worked 214 324 if (newObject) 215 325 { 216 return dynamic_cast<B*>(newObject); 326 // Do a dynamic_cast, because an object of type T is much better than of type BaseObject 327 return dynamic_cast<T*>(newObject); 217 328 } 218 329 else 219 330 { 331 // Something went terribly wrong 220 332 if (this->identifier_) 221 333 { 222 std::cout << "Error: Class " << this->identifier_->getName() << " is not a " << ClassIdentifier< B>::getIdentifier()->getName() << "!\n";334 std::cout << "Error: Class " << this->identifier_->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << "!\n"; 223 335 std::cout << "Error: Couldn't fabricate a new Object.\n"; 224 336 std::cout << "Aborting...\n"; … … 234 346 } 235 347 348 /** @returns the assigned identifier. */ 236 349 inline const Identifier* getIdentifier() const 237 350 { return this->identifier_; } 351 352 /** @returns true, if the assigned identifier is at least of the given type. @param identifier The identifier to compare with */ 238 353 inline bool isA(const Identifier* identifier) const 239 354 { return this->identifier_->isA(identifier); } 355 356 /** @returns true, if the assigned identifier is exactly of the given type. @param identifier The identifier to compare with */ 240 357 inline bool isDirectlyA(const Identifier* identifier) const 241 358 { return this->identifier_->isDirectlyA(identifier); } 359 360 /** @returns true, if the assigned identifier is a child of the given identifier. @param identifier The identifier to compare with */ 242 361 inline bool isChildOf(const Identifier* identifier) const 243 362 { return this->identifier_->isChildOf(identifier); } 363 364 /** @returns true, if the assigned identifier is a parent of the given identifier. @param identifier The identifier to compare with */ 244 365 inline bool isParentOf(const Identifier* identifier) const 245 366 { return this->identifier_->isParentOf(identifier); } 246 367 247 368 private: 248 Identifier* identifier_; 369 Identifier* identifier_; //!< The assigned identifier 249 370 }; 250 251 template <class B>252 SubclassIdentifier<B>::SubclassIdentifier()253 {254 this->identifier_ = ClassIdentifier<B>::getIdentifier();255 }256 371 } 257 372
Note: See TracChangeset
for help on using the changeset viewer.