Index: code/trunk/src/libraries/core/class/IdentifierManager.cc
===================================================================
--- code/branches/core6/src/libraries/core/class/IdentifierManager.cc	(revision 9564)
+++ code/trunk/src/libraries/core/class/IdentifierManager.cc	(revision 9667)
@@ -37,4 +37,5 @@
 
 #include "util/StringUtils.h"
+#include "core/CoreIncludes.h"
 #include "core/config/ConfigValueContainer.h"
 #include "core/XMLPort.h"
@@ -43,30 +44,29 @@
 namespace orxonox
 {
-    int IdentifierManager::hierarchyCreatingCounter_s = 0;
-    unsigned int IdentifierManager::classIDCounter_s = 0;
-
-    /**
-        @brief Returns the identifier map with the names as received by typeid(). This is only used internally.
-    */
-    std::map<std::string, Identifier*>& IdentifierManager::getTypeIDIdentifierMap()
-    {
-        static std::map<std::string, Identifier*> identifiers;    //!< The map to store all Identifiers.
-        return identifiers;
+    /* static */ IdentifierManager& IdentifierManager::getInstance()
+    {
+        static IdentifierManager instance;
+        return instance;
+    }
+
+    IdentifierManager::IdentifierManager()
+    {
+        this->hierarchyCreatingCounter_s = 0;
+        this->classIDCounter_s = 0;
     }
 
     /**
         @brief Returns an identifier by name and adds it if not available
-        @param name The name of the identifier as typeid().name() suggests
         @param proposal A pointer to a newly created identifier for the case of non existence in the map
         @return The identifier (unique instance)
     */
-    Identifier* IdentifierManager::getIdentifierSingleton(const std::string& name, Identifier* proposal)
-    {
-        std::map<std::string, Identifier*>::const_iterator it = getTypeIDIdentifierMap().find(name);
-
-        if (it != getTypeIDIdentifierMap().end())
-        {
-            // There is already an entry: return it and delete the proposal
-            delete proposal;
+    Identifier* IdentifierManager::getGloballyUniqueIdentifier(Identifier* proposal)
+    {
+        const std::string& typeidName = proposal->getTypeidName();
+        std::map<std::string, Identifier*>::const_iterator it = this->identifierByTypeidName_.find(typeidName);
+
+        if (it != this->identifierByTypeidName_.end())
+        {
+            // There is already an entry: return it
             return it->second;
         }
@@ -74,5 +74,5 @@
         {
             // There is no entry: put the proposal into the map and return it
-            getTypeIDIdentifierMap()[name] = proposal;
+            this->identifierByTypeidName_[typeidName] = proposal;
             return proposal;
         }
@@ -80,4 +80,20 @@
 
     /**
+     * Registers the identifier in all maps of the IdentifierManager.
+     */
+    void IdentifierManager::addIdentifierToLookupMaps(Identifier* identifier)
+    {
+        const std::string& typeidName = identifier->getTypeidName();
+        if (this->identifierByTypeidName_.find(typeidName) != this->identifierByTypeidName_.end())
+        {
+            this->identifierByString_[identifier->getName()] = identifier;
+            this->identifierByLowercaseString_[getLowercase(identifier->getName())] = identifier;
+            this->identifierByNetworkId_[identifier->getNetworkID()] = identifier;
+        }
+        else
+            orxout(internal_warning) << "Trying to add an identifier to lookup maps which is not known to IdentifierManager" << endl;
+    }
+
+    /**
         @brief Creates the class-hierarchy by creating and destroying one object of each type.
     */
@@ -85,15 +101,50 @@
     {
         orxout(internal_status) << "Create class-hierarchy" << endl;
-        IdentifierManager::startCreatingHierarchy();
-        for (std::map<std::string, Identifier*>::const_iterator it = IdentifierManager::getStringIdentifierMap().begin(); it != IdentifierManager::getStringIdentifierMap().end(); ++it)
-        {
-            // To create the new branch of the class-hierarchy, we create a new object and delete it afterwards.
-            if (it->second->hasFactory())
+        this->startCreatingHierarchy();
+
+        std::set<Identifier*> initializedIdentifiers;
+
+        // ensure root context exists before starting to create objects. if the root context is dynamically created while creating the class hierarchy, we
+        // would mistakenly assume the class of the currently created object inherits from Context
+        Context::getRootContext();
+
+        // 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)
             {
-                OrxonoxClass* temp = it->second->fabricate(0);
-                temp->destroy();
+                orxout(verbose, context::identifier) << "Initialize ClassIdentifier<" << it->second->getName() << ">-Singleton." << endl;
+                // To initialize the identifier, we create a new object and delete it afterwards.
+                if (it->second->hasFactory())
+                {
+                    this->identifiersOfNewObject_.clear();
+                    Identifiable* temp = it->second->fabricate(&temporaryContext);
+                    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;
+                    delete temp;
+
+                    it->second->initializeParents(this->identifiersOfNewObject_);
+                }
+                else
+                    it->second->initializeDirectParentsOfAbstractClass();
+
+                initializedIdentifiers.insert(it->second);
             }
-        }
-        IdentifierManager::stopCreatingHierarchy();
+
+            size_t numberOfObjects = temporaryContext.getObjectList<Listable>()->size();
+            if (numberOfObjects > 0)
+                orxout(internal_warning) << "There are still " << numberOfObjects << " listables left after creating the class hierarchy" << endl;
+        }
+
+        // finish the initialization of all identifiers
+        for (std::map<std::string, Identifier*>::const_iterator it = this->identifierByTypeidName_.begin(); it != this->identifierByTypeidName_.end(); ++it)
+        {
+            if (initializedIdentifiers.find(it->second) != initializedIdentifiers.end())
+                it->second->finishInitialization();
+            else
+                orxout(internal_error) << "Identifier was registered late and is not initialized: " << it->second->getName() << " / " << it->second->getTypeidName() << endl;
+        }
+
+        this->stopCreatingHierarchy();
         orxout(internal_status) << "Finished class-hierarchy creation" << endl;
     }
@@ -104,36 +155,22 @@
     void IdentifierManager::destroyAllIdentifiers()
     {
-        for (std::map<std::string, Identifier*>::iterator it = IdentifierManager::getTypeIDIdentifierMap().begin(); it != IdentifierManager::getTypeIDIdentifierMap().end(); ++it)
+        for (std::map<std::string, Identifier*>::iterator it = this->identifierByTypeidName_.begin(); it != this->identifierByTypeidName_.end(); ++it)
             delete (it->second);
-    }
-
-    /**
-        @brief Returns the map that stores all Identifiers with their names.
-        @return The map
-    */
-    std::map<std::string, Identifier*>& IdentifierManager::getStringIdentifierMapIntern()
-    {
-        static std::map<std::string, Identifier*> identifierMap;
-        return identifierMap;
-    }
-
-    /**
-        @brief Returns the map that stores all Identifiers with their names in lowercase.
-        @return The map
-    */
-    std::map<std::string, Identifier*>& IdentifierManager::getLowercaseStringIdentifierMapIntern()
-    {
-        static std::map<std::string, Identifier*> lowercaseIdentifierMap;
-        return lowercaseIdentifierMap;
-    }
-
-    /**
-        @brief Returns the map that stores all Identifiers with their network IDs.
-        @return The map
-    */
-    std::map<uint32_t, Identifier*>& IdentifierManager::getIDIdentifierMapIntern()
-    {
-        static std::map<uint32_t, Identifier*> identifierMap;
-        return identifierMap;
+
+        this->identifierByTypeidName_.clear();
+        this->identifierByString_.clear();
+        this->identifierByLowercaseString_.clear();
+        this->identifierByNetworkId_.clear();
+    }
+
+    /**
+     * @brief Notifies the IdentifierManager about a newly created object while creating the class hierarchy.
+     */
+    void IdentifierManager::createdObject(Identifiable* identifiable)
+    {
+        if (this->isCreatingHierarchy())
+            this->identifiersOfNewObject_.insert(identifiable->getIdentifier());
+        else
+            orxout(internal_warning) << "createdObject() called outside of class hierarchy creation" << endl;
     }
 
@@ -145,6 +182,6 @@
     Identifier* IdentifierManager::getIdentifierByString(const std::string& name)
     {
-        std::map<std::string, Identifier*>::const_iterator it = IdentifierManager::getStringIdentifierMapIntern().find(name);
-        if (it != IdentifierManager::getStringIdentifierMapIntern().end())
+        std::map<std::string, Identifier*>::const_iterator it = this->identifierByString_.find(name);
+        if (it != this->identifierByString_.end())
             return it->second;
         else
@@ -159,6 +196,6 @@
     Identifier* IdentifierManager::getIdentifierByLowercaseString(const std::string& name)
     {
-        std::map<std::string, Identifier*>::const_iterator it = IdentifierManager::getLowercaseStringIdentifierMapIntern().find(name);
-        if (it != IdentifierManager::getLowercaseStringIdentifierMapIntern().end())
+        std::map<std::string, Identifier*>::const_iterator it = this->identifierByLowercaseString_.find(name);
+        if (it != this->identifierByLowercaseString_.end())
             return it->second;
         else
@@ -173,6 +210,6 @@
     Identifier* IdentifierManager::getIdentifierByID(const uint32_t id)
     {
-        std::map<uint32_t, Identifier*>::const_iterator it = IdentifierManager::getIDIdentifierMapIntern().find(id);
-        if (it != IdentifierManager::getIDIdentifierMapIntern().end())
+        std::map<uint32_t, Identifier*>::const_iterator it = this->identifierByNetworkId_.find(id);
+        if (it != this->identifierByNetworkId_.end())
             return it->second;
         else
@@ -185,5 +222,5 @@
     void IdentifierManager::clearNetworkIDs()
     {
-        IdentifierManager::getIDIdentifierMapIntern().clear();
+        this->identifierByNetworkId_.clear();
     }
 }
