Changeset 10624 for code/trunk/src/libraries/core/class/Identifier.cc
- Timestamp:
- Oct 4, 2015, 9:12:21 PM (10 years ago)
- Location:
- code/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
-
code/trunk/src/libraries/core/class/Identifier.cc
r9667 r10624 44 44 namespace orxonox 45 45 { 46 bool Identifier::initConfigValues_s = true; 47 46 48 // ############################### 47 49 // ### Identifier ### … … 50 52 @brief Constructor: No factory, no object created, new ObjectList and a unique networkID. 51 53 */ 52 Identifier::Identifier() 53 : classID_(IdentifierManager::getInstance().getUniqueClassId()) 54 { 55 this->factory_ = 0; 54 Identifier::Identifier(const std::string& name, Factory* factory, bool bLoadable) 55 { 56 orxout(verbose, context::identifier) << "Create identifier for " << name << endl; 57 58 static unsigned int classIDCounter = 0; 59 60 this->classID_ = classIDCounter++; 61 this->name_ = name; 62 this->factory_ = factory; 63 this->bLoadable_ = bLoadable; 56 64 this->bInitialized_ = false; 57 this->b Loadable_ = false;65 this->bIsVirtualBase_ = false; 58 66 59 67 this->bHasConfigValues_ = false; … … 71 79 delete this->factory_; 72 80 81 for (std::list<const InheritsFrom*>::const_iterator it = this->manualDirectParents_.begin(); it != this->manualDirectParents_.end(); ++it) 82 delete (*it); 83 84 // erase this Identifier from all related identifiers 85 for (std::list<const Identifier*>::const_iterator it = this->parents_.begin(); it != this->parents_.end(); ++it) 86 const_cast<Identifier*>(*it)->children_.erase(this); 87 for (std::list<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it) 88 const_cast<Identifier*>(*it)->directChildren_.erase(this); 89 for (std::set<const Identifier*>::const_iterator it = this->children_.begin(); it != this->children_.end(); ++it) 90 const_cast<Identifier*>(*it)->parents_.remove(this); 91 for (std::set<const Identifier*>::const_iterator it = this->directChildren_.begin(); it != this->directChildren_.end(); ++it) 92 const_cast<Identifier*>(*it)->directParents_.remove(this); 93 73 94 for (std::map<std::string, ConfigValueContainer*>::iterator it = this->configValues_.begin(); it != this->configValues_.end(); ++it) 74 95 delete (it->second); … … 77 98 for (std::map<std::string, XMLPortObjectContainer*>::iterator it = this->xmlportObjectContainers_.begin(); it != this->xmlportObjectContainers_.end(); ++it) 78 99 delete (it->second); 79 }80 81 /**82 @brief Sets the name of the class.83 */84 void Identifier::setName(const std::string& name)85 {86 if (name != this->name_)87 {88 this->name_ = name;89 IdentifierManager::getInstance().addIdentifierToLookupMaps(this);90 }91 }92 93 void Identifier::setFactory(Factory* factory)94 {95 if (this->factory_)96 delete this->factory_;97 98 this->factory_ = factory;99 100 } 100 101 … … 126 127 { 127 128 this->networkID_ = id; 128 IdentifierManager::getInstance().addIdentifier ToLookupMaps(this);129 IdentifierManager::getInstance().addIdentifier(this); // add with new id 129 130 } 130 131 … … 132 133 * @brief Used to define the direct parents of an Identifier of an abstract class. 133 134 */ 134 Identifier& Identifier::inheritsFrom(I dentifier* directParent)135 { 136 if (this-> parents_.empty())137 this-> directParents_.insert(directParent);138 else 139 orxout(internal_error) << "Trying to add " << directParent->getName() << " as adirect parent of " << this->getName() << " after the latter was already initialized" << endl;135 Identifier& Identifier::inheritsFrom(InheritsFrom* directParent) 136 { 137 if (this->directParents_.empty()) 138 this->manualDirectParents_.push_back(directParent); 139 else 140 orxout(internal_error) << "Trying to manually add direct parent of " << this->getName() << " after the latter was already initialized" << endl; 140 141 141 142 return *this; … … 144 145 /** 145 146 * @brief Initializes the parents of this Identifier while creating the class hierarchy. 146 * @param i dentifiers All identifiers that were used to create an instance of this class (includingthis identifier itself)147 */ 148 void Identifier::initializeParents(const std:: set<const Identifier*>& identifiers)147 * @param initializationTrace All identifiers that were recorded while creating an instance of this class (including nested classes and this identifier itself) 148 */ 149 void Identifier::initializeParents(const std::list<const Identifier*>& initializationTrace) 149 150 { 150 151 if (!IdentifierManager::getInstance().isCreatingHierarchy()) … … 154 155 } 155 156 156 for (std::set<const Identifier*>::const_iterator it = identifiers.begin(); it != identifiers.end(); ++it) 157 if (*it != this) 158 this->parents_.insert(*it); 159 } 160 161 /** 162 * @brief Initializes the direct parents of this Identifier while creating the class hierarchy. This is only intended for abstract classes. 163 */ 164 void Identifier::initializeDirectParentsOfAbstractClass() 157 if (this->directParents_.empty()) 158 { 159 for (std::list<const Identifier*>::const_iterator it = initializationTrace.begin(); it != initializationTrace.end(); ++it) 160 if (*it != this) 161 this->parents_.push_back(*it); 162 } 163 else 164 orxout(internal_error) << "Trying to add parents to " << this->getName() << " after it was already initialized with manual calls to inheritsFrom<Class>()." << endl; 165 } 166 167 /** 168 * @brief Finishes the initialization of this Identifier after creating the class hierarchy by wiring the (direct) parent/child references correctly. 169 */ 170 void Identifier::finishInitialization() 165 171 { 166 172 if (!IdentifierManager::getInstance().isCreatingHierarchy()) 167 173 { 168 orxout(internal_warning) << "Identifier:: initializeDirectParentsOfAbstractClass() created outside of class hierarchy creation" << endl;174 orxout(internal_warning) << "Identifier::finishInitialization() created outside of class hierarchy creation" << endl; 169 175 return; 170 176 } 171 177 172 // only Identifiable is allowed to have no parents (even tough it's currently not abstract) 173 if (this->directParents_.empty() && !this->isExactlyA(Class(Identifiable))) 174 { 175 orxout(internal_error) << "Identifier " << this->getName() << " / " << this->getTypeidName() << " is marked as abstract but has no direct parents defined" << endl; 178 if (this->isInitialized()) 179 return; 180 181 if (!this->parents_.empty()) 182 { 183 // parents defined -> this class was initialized by creating a sample instance and recording the trace of identifiers 184 185 // initialize all parents 186 for (std::list<const Identifier*>::const_iterator it = this->parents_.begin(); it != this->parents_.end(); ++it) 187 const_cast<Identifier*>(*it)->finishInitialization(); // initialize parent 188 189 // parents of parents are no direct parents of this identifier 190 this->directParents_ = this->parents_; 191 for (std::list<const Identifier*>::const_iterator it_parent = this->parents_.begin(); it_parent != this->parents_.end(); ++it_parent) 192 for (std::list<const Identifier*>::const_iterator it_parent_parent = const_cast<Identifier*>(*it_parent)->parents_.begin(); it_parent_parent != const_cast<Identifier*>(*it_parent)->parents_.end(); ++it_parent_parent) 193 this->directParents_.remove(*it_parent_parent); 194 195 this->verifyIdentifierTrace(); 196 } 197 else if (!this->manualDirectParents_.empty()) 198 { 199 // no parents defined -> this class was manually initialized by calling inheritsFrom<Class>() 200 201 // initialize all direct parents 202 for (std::list<const InheritsFrom*>::const_iterator it = this->manualDirectParents_.begin(); it != this->manualDirectParents_.end(); ++it) 203 { 204 Identifier* directParent = (*it)->getParent(); 205 this->directParents_.push_back(directParent); 206 directParent->finishInitialization(); // initialize parent 207 } 208 209 // direct parents and their parents are also parents of this identifier (but only add them once) 210 for (std::list<const Identifier*>::const_iterator it_parent = this->directParents_.begin(); it_parent != this->directParents_.end(); ++it_parent) 211 { 212 for (std::list<const Identifier*>::const_iterator it_parent_parent = const_cast<Identifier*>(*it_parent)->parents_.begin(); it_parent_parent != const_cast<Identifier*>(*it_parent)->parents_.end(); ++it_parent_parent) 213 this->addIfNotExists(this->parents_, *it_parent_parent); 214 this->addIfNotExists(this->parents_, *it_parent); 215 } 216 } 217 else if (!this->isExactlyA(Class(Identifiable))) 218 { 219 // only Identifiable is allowed to have no parents (even tough it's currently not abstract) 220 orxout(internal_error) << "Identifier " << this->getName() << " / " << this->getTypeInfo().name() << " is marked as abstract but has no direct parents defined" << endl; 176 221 orxout(internal_error) << " If this class is not abstract, use RegisterClass(ThisClass);" << endl; 177 222 orxout(internal_error) << " If this class is abstract, use RegisterAbstractClass(ThisClass).inheritsFrom(Class(BaseClass));" << endl; 178 223 } 179 }180 181 /**182 * @brief Finishes the initialization of this Identifier after creating the class hierarchy by wiring the (direct) parent/child references correctly.183 */184 void Identifier::finishInitialization()185 {186 if (!IdentifierManager::getInstance().isCreatingHierarchy())187 {188 orxout(internal_warning) << "Identifier::finishInitialization() created outside of class hierarchy creation" << endl;189 return;190 }191 192 if (this->isInitialized())193 return;194 195 // if no direct parents were defined, initialize them with the set of all parents196 if (this->directParents_.empty())197 this->directParents_ = this->parents_;198 199 // initialize all parents before continuing to initialize this identifier200 for (std::set<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)201 {202 Identifier* directParent = const_cast<Identifier*>(*it);203 directParent->finishInitialization(); // initialize parent204 this->parents_.insert(directParent); // direct parent is also a parent205 this->parents_.insert(directParent->parents_.begin(), directParent->parents_.end()); // parents of direct parent are also parents206 }207 208 // parents of parents are no direct parents of this identifier209 for (std::set<const Identifier*>::const_iterator it_parent = this->parents_.begin(); it_parent != this->parents_.end(); ++it_parent)210 for (std::set<const Identifier*>::const_iterator it_parent_parent = const_cast<Identifier*>(*it_parent)->parents_.begin(); it_parent_parent != const_cast<Identifier*>(*it_parent)->parents_.end(); ++it_parent_parent)211 this->directParents_.erase(*it_parent_parent);212 224 213 225 // tell all parents that this identifier is a child 214 for (std:: set<const Identifier*>::const_iterator it = this->parents_.begin(); it != this->parents_.end(); ++it)226 for (std::list<const Identifier*>::const_iterator it = this->parents_.begin(); it != this->parents_.end(); ++it) 215 227 const_cast<Identifier*>(*it)->children_.insert(this); 216 228 217 229 // tell all direct parents that this identifier is a direct child 218 for (std:: set<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)230 for (std::list<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it) 219 231 { 220 232 const_cast<Identifier*>(*it)->directChildren_.insert(this); … … 228 240 229 241 /** 242 * Resets all information about the class hierarchy. The identifier is considered uninitialized afterwards. 243 */ 244 void Identifier::reset() 245 { 246 this->directParents_.clear(); 247 this->parents_.clear(); 248 this->directChildren_.clear(); 249 this->children_.clear(); 250 this->bInitialized_ = false; 251 } 252 253 /** 254 * Verifies if the recorded trace of parent identifiers matches the expected trace according to the class hierarchy. If it doesn't match, the class 255 * hierarchy is likely wrong, e.g. due to wrong inheritsFrom<>() definitions in abstract classes. 256 */ 257 void Identifier::verifyIdentifierTrace() const 258 { 259 260 std::list<const Identifier*> expectedIdentifierTrace; 261 262 // if any parent class is virtual, it will be instantiated first, so we need to add them first. 263 for (std::list<const Identifier*>::const_iterator it_parent = this->parents_.begin(); it_parent != this->parents_.end(); ++it_parent) 264 { 265 if ((*it_parent)->isVirtualBase()) 266 { 267 for (std::list<const Identifier*>::const_iterator it_parent_parent = const_cast<Identifier*>(*it_parent)->parents_.begin(); it_parent_parent != const_cast<Identifier*>(*it_parent)->parents_.end(); ++it_parent_parent) 268 this->addIfNotExists(expectedIdentifierTrace, *it_parent_parent); 269 this->addIfNotExists(expectedIdentifierTrace, *it_parent); 270 } 271 } 272 273 // now all direct parents get created recursively. already added identifiers (e.g. virtual base classes) are not added again. 274 for (std::list<const Identifier*>::const_iterator it_parent = this->directParents_.begin(); it_parent != this->directParents_.end(); ++it_parent) 275 { 276 for (std::list<const Identifier*>::const_iterator it_parent_parent = const_cast<Identifier*>(*it_parent)->parents_.begin(); it_parent_parent != const_cast<Identifier*>(*it_parent)->parents_.end(); ++it_parent_parent) 277 this->addIfNotExists(expectedIdentifierTrace, *it_parent_parent); 278 this->addIfNotExists(expectedIdentifierTrace, *it_parent); 279 } 280 281 // check if the expected trace matches the actual trace (which was defined by creating a sample instance) 282 if (expectedIdentifierTrace != this->parents_) 283 { 284 orxout(internal_warning) << this->getName() << " has an unexpected initialization trace:" << endl; 285 286 orxout(internal_warning) << " Actual trace (after creating a sample instance):" << endl << " "; 287 for (std::list<const Identifier*>::const_iterator it_parent = this->parents_.begin(); it_parent != this->parents_.end(); ++it_parent) 288 orxout(internal_warning) << " " << (*it_parent)->getName(); 289 orxout(internal_warning) << endl; 290 291 orxout(internal_warning) << " Expected trace (according to class hierarchy definitions):" << endl << " "; 292 for (std::list<const Identifier*>::const_iterator it_parent = expectedIdentifierTrace.begin(); it_parent != expectedIdentifierTrace.end(); ++it_parent) 293 orxout(internal_warning) << " " << (*it_parent)->getName(); 294 orxout(internal_warning) << endl; 295 296 orxout(internal_warning) << " Direct parents (according to class hierarchy definitions):" << endl << " "; 297 for (std::list<const Identifier*>::const_iterator it_parent = this->directParents_.begin(); it_parent != this->directParents_.end(); ++it_parent) 298 orxout(internal_warning) << " " << (*it_parent)->getName(); 299 orxout(internal_warning) << endl; 300 } 301 } 302 303 /** 304 * Adds @param identifierToAdd to @param list if this identifier is not already contained in the list. 305 */ 306 void Identifier::addIfNotExists(std::list<const Identifier*>& list, const Identifier* identifierToAdd) const 307 { 308 if (std::find(list.begin(), list.end(), identifierToAdd) == list.end()) 309 list.push_back(identifierToAdd); 310 } 311 312 /** 230 313 @brief Returns true, if the Identifier is at least of the given type. 231 314 @param identifier The identifier to compare with … … 233 316 bool Identifier::isA(const Identifier* identifier) const 234 317 { 235 return (identifier == this || (this-> parents_.find(identifier) != this->parents_.end()));318 return (identifier == this || (this->isChildOf(identifier))); 236 319 } 237 320 … … 251 334 bool Identifier::isChildOf(const Identifier* identifier) const 252 335 { 253 return ( this->parents_.find(identifier) != this->parents_.end());336 return (std::find(this->parents_.begin(), this->parents_.end(), identifier) != this->parents_.end()); 254 337 } 255 338 … … 260 343 bool Identifier::isDirectChildOf(const Identifier* identifier) const 261 344 { 262 return ( this->directParents_.find(identifier) != this->directParents_.end());345 return (std::find(this->directParents_.begin(), this->directParents_.end(), identifier) != this->directParents_.end()); 263 346 } 264 347
Note: See TracChangeset
for help on using the changeset viewer.