[Orxonox-commit 5739] r10399 - code/branches/core7/src/libraries/core/class

landauf at orxonox.net landauf at orxonox.net
Sun Apr 26 15:10:58 CEST 2015


Author: landauf
Date: 2015-04-26 15:10:58 +0200 (Sun, 26 Apr 2015)
New Revision: 10399

Modified:
   code/branches/core7/src/libraries/core/class/Identifier.cc
   code/branches/core7/src/libraries/core/class/Identifier.h
   code/branches/core7/src/libraries/core/class/IdentifierManager.cc
   code/branches/core7/src/libraries/core/class/IdentifierManager.h
Log:
use typeid(T) instead of typeid(T).name() to identify a class. this avoids ambiguity if two classes in different anonymous namespaces use the same name.

Modified: code/branches/core7/src/libraries/core/class/Identifier.cc
===================================================================
--- code/branches/core7/src/libraries/core/class/Identifier.cc	2015-04-26 11:34:31 UTC (rev 10398)
+++ code/branches/core7/src/libraries/core/class/Identifier.cc	2015-04-26 13:10:58 UTC (rev 10399)
@@ -196,7 +196,7 @@
         else if (!this->isExactlyA(Class(Identifiable)))
         {
             // only Identifiable is allowed to have no parents (even tough it's currently not abstract)
-            orxout(internal_error) << "Identifier " << this->getName() << " / " << this->getTypeidName() << " is marked as abstract but has no direct parents defined" << endl;
+            orxout(internal_error) << "Identifier " << this->getName() << " / " << this->getTypeInfo().name() << " is marked as abstract but has no direct parents defined" << endl;
             orxout(internal_error) << "  If this class is not abstract, use RegisterClass(ThisClass);" << endl;
             orxout(internal_error) << "  If this class is abstract, use RegisterAbstractClass(ThisClass).inheritsFrom(Class(BaseClass));" << endl;
         }

Modified: code/branches/core7/src/libraries/core/class/Identifier.h
===================================================================
--- code/branches/core7/src/libraries/core/class/Identifier.h	2015-04-26 11:34:31 UTC (rev 10398)
+++ code/branches/core7/src/libraries/core/class/Identifier.h	2015-04-26 13:10:58 UTC (rev 10399)
@@ -116,8 +116,8 @@
             /// Returns the name of the class the Identifier belongs to.
             inline const std::string& getName() const { return this->name_; }
 
-            /// Returns the name of the class as it is returned by typeid(T).name()
-            virtual const std::string& getTypeidName() = 0;
+            /// Returns the type_info of the class as it is returned by typeid(T)
+            virtual const std::type_info& getTypeInfo() = 0;
 
             /// Returns the network ID to identify a class through the network.
             inline uint32_t getNetworkID() const { return this->networkID_; }
@@ -264,7 +264,6 @@
                 OrxVerify(ClassIdentifier<T>::classIdentifier_s == NULL, "Assertion failed in ClassIdentifier of type " << typeid(T).name());
                 ClassIdentifier<T>::classIdentifier_s = this;
 
-                this->typeidName_ = typeid(T).name();
                 SuperFunctionInitialization<0, T>::initialize(this);
             }
             ~ClassIdentifier()
@@ -282,8 +281,8 @@
 
             virtual void updateConfigValues(bool updateChildren = true) const;
 
-            virtual const std::string& getTypeidName()
-                { return this->typeidName_; }
+            virtual const std::type_info& getTypeInfo()
+                { return typeid(T); }
 
             virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) const
                 { return dynamic_cast<T*>(object) != 0; }
@@ -296,7 +295,6 @@
             void updateConfigValues(bool updateChildren, Listable*) const;
             void updateConfigValues(bool updateChildren, Identifiable*) const;
 
-            std::string typeidName_;
             static WeakPtr<ClassIdentifier<T> > classIdentifier_s;
     };
 
@@ -311,7 +309,7 @@
     /*static*/ inline ClassIdentifier<T>* ClassIdentifier<T>::getIdentifier()
     {
         if (ClassIdentifier<T>::classIdentifier_s == NULL)
-            ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*) IdentifierManager::getInstance().getIdentifierByTypeidName(typeid(T).name());
+            ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*) IdentifierManager::getInstance().getIdentifierByTypeInfo(typeid(T));
 
         OrxVerify(ClassIdentifier<T>::classIdentifier_s != NULL, "Assertion failed in ClassIdentifier of type " << typeid(T).name());
         return ClassIdentifier<T>::classIdentifier_s;

Modified: code/branches/core7/src/libraries/core/class/IdentifierManager.cc
===================================================================
--- code/branches/core7/src/libraries/core/class/IdentifierManager.cc	2015-04-26 11:34:31 UTC (rev 10398)
+++ code/branches/core7/src/libraries/core/class/IdentifierManager.cc	2015-04-26 13:10:58 UTC (rev 10399)
@@ -61,9 +61,9 @@
      */
     void IdentifierManager::addIdentifier(Identifier* identifier)
     {
-        orxout(verbose, context::identifier) << "Adding identifier for " << identifier->getName() << " / " << identifier->getTypeidName() << endl;
+        orxout(verbose, context::identifier) << "Adding identifier for " << identifier->getName() << " / " << identifier->getTypeInfo().name() << endl;
 
-        this->identifierByTypeidName_[identifier->getTypeidName()] = identifier;
+        this->identifiers_.insert(identifier);
         this->identifierByString_[identifier->getName()] = identifier;
         this->identifierByLowercaseString_[getLowercase(identifier->getName())] = identifier;
         this->identifierByNetworkId_[identifier->getNetworkID()] = identifier;
@@ -86,28 +86,30 @@
         // iterate over all identifiers, create one instance of each class and initialize the identifiers
         {
             Context temporaryContext(NULL);
-            for (std::map<std::string, Identifier*>::const_iterator it = this->identifierByTypeidName_.begin(); it != this->identifierByTypeidName_.end(); ++it)
+            for (std::set<Identifier*>::const_iterator it = this->identifiers_.begin(); it != this->identifiers_.end(); ++it)
             {
-                orxout(verbose, context::identifier) << "Initialize ClassIdentifier<" << it->second->getName() << ">-Singleton." << endl;
+                Identifier* identifier = (*it);
+
+                orxout(verbose, context::identifier) << "Initialize ClassIdentifier<" << identifier->getName() << ">-Singleton." << endl;
                 // To initialize the identifier, we create a new object and delete it afterwards.
-                if (it->second->hasFactory())
+                if (identifier->hasFactory())
                 {
                     this->identifierTraceOfNewObject_.clear();
-                    this->recordTraceForIdentifier_ = it->second;
+                    this->recordTraceForIdentifier_ = identifier;
 
-                    Identifiable* temp = it->second->fabricate(&temporaryContext);
+                    Identifiable* temp = identifier->fabricate(&temporaryContext);
 
                     this->recordTraceForIdentifier_ = NULL;
 
-                    if (temp->getIdentifier() != it->second)
-                        orxout(internal_error) << "Newly created object of type " << it->second->getName() << " has unexpected identifier. Did you forget to use RegisterObject(classname)?" << endl;
+                    if (temp->getIdentifier() != identifier)
+                        orxout(internal_error) << "Newly created object of type " << identifier->getName() << " has unexpected identifier. Did you forget to use RegisterObject(classname)?" << endl;
 
-                    it->second->initializeParents(this->identifierTraceOfNewObject_[temp]);
+                    identifier->initializeParents(this->identifierTraceOfNewObject_[temp]);
 
                     delete temp;
                 }
 
-                initializedIdentifiers.insert(it->second);
+                initializedIdentifiers.insert(identifier);
             }
 
             size_t numberOfObjects = temporaryContext.getObjectList<Listable>()->size();
@@ -116,12 +118,14 @@
         }
 
         // finish the initialization of all identifiers
-        for (std::map<std::string, Identifier*>::const_iterator it = this->identifierByTypeidName_.begin(); it != this->identifierByTypeidName_.end(); ++it)
+        for (std::set<Identifier*>::const_iterator it = this->identifiers_.begin(); it != this->identifiers_.end(); ++it)
         {
-            if (initializedIdentifiers.find(it->second) != initializedIdentifiers.end())
-                it->second->finishInitialization();
+            Identifier* identifier = (*it);
+
+            if (initializedIdentifiers.find(identifier) != initializedIdentifiers.end())
+                identifier->finishInitialization();
             else
-                orxout(internal_error) << "Identifier was registered late and is not initialized: " << it->second->getName() << " / " << it->second->getTypeidName() << endl;
+                orxout(internal_error) << "Identifier was registered late and is not initialized: " << identifier->getName() << " / " << identifier->getTypeInfo().name() << endl;
         }
 
         // only check class hierarchy in dev mode because it's an expensive operation and it requires a developer to fix detected problems anyway.
@@ -138,22 +142,22 @@
     void IdentifierManager::verifyClassHierarchy()
     {
         Context temporaryContext(NULL);
-        for (std::map<std::string, Identifier*>::const_iterator it1 = this->identifierByTypeidName_.begin(); it1 != this->identifierByTypeidName_.end(); ++it1)
+        for (std::set<Identifier*>::const_iterator it1 = this->identifiers_.begin(); it1 != this->identifiers_.end(); ++it1)
         {
-            if (!it1->second->hasFactory())
+            if (!(*it1)->hasFactory())
                 continue;
 
-            Identifiable* temp = it1->second->fabricate(&temporaryContext);
+            Identifiable* temp = (*it1)->fabricate(&temporaryContext);
 
-            for (std::map<std::string, Identifier*>::const_iterator it2 = this->identifierByTypeidName_.begin(); it2 != this->identifierByTypeidName_.end(); ++it2)
+            for (std::set<Identifier*>::const_iterator it2 = this->identifiers_.begin(); it2 != this->identifiers_.end(); ++it2)
             {
-                bool isA_AccordingToRtti = it2->second->canDynamicCastObjectToIdentifierClass(temp);
-                bool isA_AccordingToClassHierarchy = temp->isA(it2->second);
+                bool isA_AccordingToRtti = (*it2)->canDynamicCastObjectToIdentifierClass(temp);
+                bool isA_AccordingToClassHierarchy = temp->isA((*it2));
 
                 if (isA_AccordingToRtti != isA_AccordingToClassHierarchy)
                 {
-                    orxout(internal_error) << "Class hierarchy does not match RTTI: Class hierarchy claims that " << it1->second->getName() <<
-                        (isA_AccordingToClassHierarchy ? " is a " : " is not a ") << it2->second->getName() << " but RTTI says the opposite." << endl;
+                    orxout(internal_error) << "Class hierarchy does not match RTTI: Class hierarchy claims that " << (*it1)->getName() <<
+                        (isA_AccordingToClassHierarchy ? " is a " : " is not a ") << (*it2)->getName() << " but RTTI says the opposite." << endl;
                 }
             }
 
@@ -171,10 +175,10 @@
     */
     void IdentifierManager::destroyAllIdentifiers()
     {
-        for (std::map<std::string, Identifier*>::iterator it = this->identifierByTypeidName_.begin(); it != this->identifierByTypeidName_.end(); ++it)
-            delete (it->second);
+        for (std::set<Identifier*>::iterator it = this->identifiers_.begin(); it != this->identifiers_.end(); ++it)
+            delete (*it);
 
-        this->identifierByTypeidName_.clear();
+        this->identifiers_.clear();
         this->identifierByString_.clear();
         this->identifierByLowercaseString_.clear();
         this->identifierByNetworkId_.clear();
@@ -249,13 +253,13 @@
         @param name The typeid-name of the wanted Identifier
         @return The Identifier
     */
-    Identifier* IdentifierManager::getIdentifierByTypeidName(const std::string& typeidName)
+    Identifier* IdentifierManager::getIdentifierByTypeInfo(const std::type_info& typeInfo)
     {
-        std::map<std::string, Identifier*>::const_iterator it = this->identifierByTypeidName_.find(typeidName);
-        if (it != this->identifierByTypeidName_.end())
-            return it->second;
-        else
-            return 0;
+        // TODO: use std::type_index and a map to find identifiers by type_info (only with c++11)
+        for (std::set<Identifier*>::iterator it = this->identifiers_.begin(); it != this->identifiers_.end(); ++it)
+            if ((*it)->getTypeInfo() == typeInfo)
+                return (*it);
+        return 0;
     }
 
     /**

Modified: code/branches/core7/src/libraries/core/class/IdentifierManager.h
===================================================================
--- code/branches/core7/src/libraries/core/class/IdentifierManager.h	2015-04-26 11:34:31 UTC (rev 10398)
+++ code/branches/core7/src/libraries/core/class/IdentifierManager.h	2015-04-26 13:10:58 UTC (rev 10399)
@@ -37,6 +37,7 @@
 #include "core/CorePrereqs.h"
 
 #include <map>
+#include <set>
 #include <list>
 #include <string>
 
@@ -73,7 +74,7 @@
             Identifier* getIdentifierByString(const std::string& name);
             Identifier* getIdentifierByLowercaseString(const std::string& name);
             Identifier* getIdentifierByID(uint32_t id);
-            Identifier* getIdentifierByTypeidName(const std::string& typeidName);
+            Identifier* getIdentifierByTypeInfo(const std::type_info& typeInfo);
 
             void clearNetworkIDs();
 
@@ -99,8 +100,7 @@
             inline void stopCreatingHierarchy()
                 { hierarchyCreatingCounter_s--; }
 
-            std::map<std::string, Identifier*> identifierByTypeidName_;      //!< Map with the names as received by typeid(). This is only used internally.
-
+            std::set<Identifier*> identifiers_;                              //!< All identifiers. This is only used internally.
             std::map<std::string, Identifier*> identifierByString_;          //!< Map that stores all Identifiers with their names.
             std::map<std::string, Identifier*> identifierByLowercaseString_; //!< Map that stores all Identifiers with their names in lowercase.
             std::map<uint32_t, Identifier*> identifierByNetworkId_;          //!< Returns the map that stores all Identifiers with their network IDs.




More information about the Orxonox-commit mailing list