[Orxonox-commit 4977] r9646 - in code/branches/core6: src/libraries/core src/libraries/core/class test/core/class
landauf at orxonox.net
landauf at orxonox.net
Tue Aug 13 23:35:26 CEST 2013
Author: landauf
Date: 2013-08-13 23:35:26 +0200 (Tue, 13 Aug 2013)
New Revision: 9646
Added:
code/branches/core6/src/libraries/core/class/OrxonoxClass.cc
code/branches/core6/src/libraries/core/class/OrxonoxInterface.cc
Modified:
code/branches/core6/src/libraries/core/CoreIncludes.h
code/branches/core6/src/libraries/core/class/CMakeLists.txt
code/branches/core6/src/libraries/core/class/Identifiable.cc
code/branches/core6/src/libraries/core/class/Identifiable.h
code/branches/core6/src/libraries/core/class/Identifier.cc
code/branches/core6/src/libraries/core/class/Identifier.h
code/branches/core6/src/libraries/core/class/IdentifierManager.cc
code/branches/core6/src/libraries/core/class/IdentifierManager.h
code/branches/core6/src/libraries/core/class/OrxonoxClass.h
code/branches/core6/src/libraries/core/class/OrxonoxInterface.h
code/branches/core6/src/libraries/core/class/Super.h
code/branches/core6/test/core/class/IdentifierClassHierarchyTest.cc
code/branches/core6/test/core/class/IdentifierExternalClassHierarchyTest.cc
code/branches/core6/test/core/class/IdentifierSimpleClassHierarchyTest.cc
Log:
implemented new concept to initialize the class hierarchy: each identifier is initialized individually by creating an object of the corresponding class. identifiers of abstract classes must be told explicitly about their direct parents. this allows to build the class tree correctly also for complicated setups like multiple inheritance of abstract classes.
Modified: code/branches/core6/src/libraries/core/CoreIncludes.h
===================================================================
--- code/branches/core6/src/libraries/core/CoreIncludes.h 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/src/libraries/core/CoreIncludes.h 2013-08-13 21:35:26 UTC (rev 9646)
@@ -89,55 +89,69 @@
/**
- @brief Intern macro, containing the common parts of @c RegisterObject and @c RegisterRootObject.
+ @brief Registers the class in the framework.
@param ClassName The name of the class
- @param bRootClass True if the class is directly derived from orxonox::OrxonoxClass
*/
-#define InternRegisterObject(ClassName, bRootClass) \
- if (ClassIdentifier<ClassName>::getIdentifier(#ClassName)->initializeObject(this, #ClassName, bRootClass)) \
- return; \
- else \
- ((void)0)
+#define RegisterClass(ClassName) \
+ RegisterClassWithFactory(ClassName, new orxonox::ClassFactoryWithContext<ClassName>(), true)
/**
- @brief Registers a newly created object in the framework. Has to be called at the beginning of the constructor of @a ClassName.
+ @brief Registers the class in the framework (for classes without arguments in their constructor).
@param ClassName The name of the class
*/
-#define RegisterObject(ClassName) \
- InternRegisterObject(ClassName, false)
+#define RegisterClassNoArgs(ClassName) \
+ RegisterClassWithFactory(ClassName, new orxonox::ClassFactoryNoArgs<ClassName>(), true)
/**
- @brief Registers a newly created object in the framework. Has to be called at the beginning of the constructor of @a ClassName.
+ @brief Registers the class in the framework (for classes which should not be loaded through XML).
@param ClassName The name of the class
+*/
+#define RegisterUnloadableClass(ClassName) \
+ RegisterClassWithFactory(ClassName, new orxonox::ClassFactoryWithContext<ClassName>(), false)
- In contrast to RegisterObject, this is used for classes that inherit directly from
- orxonox::OrxonoxClass, namely all interfaces and orxonox::BaseObject.
+/**
+ @brief Registers an abstract class in the framework.
+ @param ClassName The name of the class
*/
-#define RegisterRootObject(ClassName) \
- InternRegisterObject(ClassName, true)
+#define RegisterAbstractClass(ClassName) \
+ RegisterClassWithFactory(ClassName, static_cast<ClassFactory<ClassName>*>(NULL), false)
/**
- @brief Registers the class in the framework.
+ @brief Registers the class in the framework with a given Factory.
@param ClassName The name of the class
*/
-#define RegisterClass(ClassName) \
- RegisterClassWithFactory(ClassName, new orxonox::ClassFactoryWithContext<ClassName>(), true)
+#define RegisterClassWithFactory(ClassName, FactoryInstance, bLoadable) \
+ Identifier& _##ClassName##Identifier = orxonox::registerClass<ClassName>(#ClassName, FactoryInstance, bLoadable)
/**
- @brief Registers the class in the framework (for classes which should not be loaded through XML).
+ @brief Intern macro, containing the common parts of @c RegisterObject and @c RegisterRootObject.
@param ClassName The name of the class
+ @param bRootClass True if the class is directly derived from orxonox::OrxonoxClass
*/
-#define RegisterUnloadableClass(ClassName) \
- RegisterClassWithFactory(ClassName, new orxonox::ClassFactoryWithContext<ClassName>(), false)
+#define InternRegisterObject(ClassName) \
+ if (ClassIdentifier<ClassName>::getIdentifier(#ClassName)->initializeObject(this)) \
+ return; \
+ else \
+ ((void)0)
/**
- @brief Registers the class in the framework with a given Factory.
+ @brief Registers a newly created object in the framework. Has to be called at the beginning of the constructor of @a ClassName.
@param ClassName The name of the class
*/
-#define RegisterClassWithFactory(ClassName, FactoryInstance, bLoadable) \
- Identifier* _##ClassName##Identifier = orxonox::registerClass<ClassName>(#ClassName, FactoryInstance, bLoadable)
+#define RegisterObject(ClassName) \
+ InternRegisterObject(ClassName)
/**
+ @brief Registers a newly created object in the framework. Has to be called at the beginning of the constructor of @a ClassName.
+ @param ClassName The name of the class
+
+ In contrast to RegisterObject, this is used for classes that inherit directly from
+ orxonox::OrxonoxClass, namely all interfaces and orxonox::BaseObject.
+*/
+#define RegisterRootObject(ClassName) \
+ InternRegisterObject(ClassName)
+
+/**
@brief Returns the Identifier of the given class.
@param ClassName The name of the class
*/
@@ -151,7 +165,7 @@
* @brief Overload of registerClass() which determines T implicitly by the template argument of the ClassFactory.
*/
template <class T>
- inline Identifier* registerClass(const std::string& name, ClassFactory<T>* factory, bool bLoadable = true)
+ inline Identifier& registerClass(const std::string& name, ClassFactory<T>* factory, bool bLoadable = true)
{
return registerClass<T>(name, static_cast<Factory*>(factory), bLoadable);
}
@@ -163,13 +177,13 @@
* @param bLoadable Whether the class is allowed to be loaded through XML
*/
template <class T>
- inline Identifier* registerClass(const std::string& name, Factory* factory, bool bLoadable = true)
+ inline Identifier& registerClass(const std::string& name, Factory* factory, bool bLoadable = true)
{
orxout(verbose, context::misc::factory) << "Create entry for " << name << " in Factory." << endl;
Identifier* identifier = ClassIdentifier<T>::getIdentifier(name);
identifier->setFactory(factory);
identifier->setLoadable(bLoadable);
- return identifier;
+ return *identifier;
}
/**
Modified: code/branches/core6/src/libraries/core/class/CMakeLists.txt
===================================================================
--- code/branches/core6/src/libraries/core/class/CMakeLists.txt 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/src/libraries/core/class/CMakeLists.txt 2013-08-13 21:35:26 UTC (rev 9646)
@@ -2,4 +2,6 @@
Identifiable.cc
Identifier.cc
IdentifierManager.cc
+ OrxonoxClass.cc
+ OrxonoxInterface.cc
)
Modified: code/branches/core6/src/libraries/core/class/Identifiable.cc
===================================================================
--- code/branches/core6/src/libraries/core/class/Identifiable.cc 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/src/libraries/core/class/Identifiable.cc 2013-08-13 21:35:26 UTC (rev 9646)
@@ -34,30 +34,23 @@
#include "Identifiable.h"
#include <cassert>
+#include "core/CoreIncludes.h"
#include "core/object/Context.h"
#include "Identifier.h"
namespace orxonox
{
+ RegisterClassNoArgs(Identifiable);
+
/**
@brief Constructor: Sets the default values.
*/
Identifiable::Identifiable()
{
this->identifier_ = 0;
- this->parents_ = 0;
- // Optimisation
- this->objectPointers_.reserve(6);
- }
+ this->objectPointers_.reserve(6); // Optimisation
- /**
- @brief Destructor: Removes the object from the object-lists
- */
- Identifiable::~Identifiable()
- {
- // parents_ exists only if isCreatingHierarchy() of the associated Identifier returned true while creating the class
- if (this->parents_)
- delete this->parents_;
+ RegisterObject(Identifiable);
}
/// Returns true if the object's class is of the given type or a derivative.
Modified: code/branches/core6/src/libraries/core/class/Identifiable.h
===================================================================
--- code/branches/core6/src/libraries/core/class/Identifiable.h 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/src/libraries/core/class/Identifiable.h 2013-08-13 21:35:26 UTC (rev 9646)
@@ -54,7 +54,7 @@
public:
Identifiable();
- virtual ~Identifiable();
+ virtual ~Identifiable() {}
/// Returns the Identifier of the object.
inline Identifier* getIdentifier() const { return this->identifier_; }
@@ -118,7 +118,6 @@
private:
Identifier* identifier_; //!< The Identifier of the object
- std::set<const Identifier*>* parents_; //!< List of all parents of the object
/// 'Fast map' that holds this-pointers of all derived types
std::vector<std::pair<unsigned int, void*> > objectPointers_;
Modified: code/branches/core6/src/libraries/core/class/Identifier.cc
===================================================================
--- code/branches/core6/src/libraries/core/class/Identifier.cc 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/src/libraries/core/class/Identifier.cc 2013-08-13 21:35:26 UTC (rev 9646)
@@ -36,6 +36,7 @@
#include <ostream>
#include "util/StringUtils.h"
+#include "core/CoreIncludes.h"
#include "core/config/ConfigValueContainer.h"
#include "core/XMLPort.h"
#include "core/object/ClassFactory.h"
@@ -51,9 +52,8 @@
Identifier::Identifier()
: classID_(IdentifierManager::getInstance().getUniqueClassId())
{
- this->bCreatedOneObject_ = false;
- this->bSetName_ = false;
this->factory_ = 0;
+ this->bInitialized_ = false;
this->bLoadable_ = false;
this->bHasConfigValues_ = false;
@@ -79,82 +79,14 @@
}
/**
- @brief Registers a class, which means that the name and the parents get stored.
- @param parents A list, containing the Identifiers of all parents of the class
- @param bRootClass True if the class is either an Interface or the BaseObject itself
- */
- void Identifier::initializeClassHierarchy(std::set<const Identifier*>* parents, bool bRootClass)
- {
- // Check if at least one object of the given type was created
- if (!this->bCreatedOneObject_ && IdentifierManager::getInstance().isCreatingHierarchy())
- {
- // If no: We have to store the information and initialize the Identifier
- orxout(verbose, context::identifier) << "Register Class in ClassIdentifier<" << this->getName() << ">-Singleton -> Initialize Singleton." << endl;
- if (bRootClass)
- this->initialize(0); // 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.
- else
- this->initialize(parents);
- }
- }
-
- /**
- @brief Initializes the Identifier with a list containing all parents of the class the Identifier belongs to.
- @param parents A list containing all parents
- */
- void Identifier::initialize(std::set<const Identifier*>* parents)
- {
- orxout(verbose, context::identifier) << "Initialize ClassIdentifier<" << this->name_ << ">-Singleton." << endl;
- this->bCreatedOneObject_ = true;
-
- if (parents)
- {
- this->parents_ = (*parents);
- this->directParents_ = (*parents);
-
- // Iterate through all parents
- for (std::set<const Identifier*>::iterator it = parents->begin(); it != parents->end(); ++it)
- {
- // Tell the parent we're one of it's children
- (*it)->children_.insert((*it)->children_.end(), this);
-
- // Erase all parents of our parent from our direct-parent-list
- for (std::set<const Identifier*>::const_iterator it1 = (*it)->getParents().begin(); it1 != (*it)->getParents().end(); ++it1)
- {
- // Search for the parent's parent in our direct-parent-list
- for (std::set<const Identifier*>::iterator it2 = this->directParents_.begin(); it2 != this->directParents_.end(); ++it2)
- {
- if ((*it1) == (*it2))
- {
- // We've found a non-direct parent in our list: Erase it
- this->directParents_.erase(it2);
- break;
- }
- }
- }
- }
-
- // Now iterate through all direct parents
- for (std::set<const Identifier*>::iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)
- {
- // Tell the parent we're one of it's direct children
- (*it)->directChildren_.insert((*it)->directChildren_.end(), this);
-
- // Create the super-function dependencies
- (*it)->createSuperFunctionCaller();
- }
- }
- }
-
- /**
@brief Sets the name of the class.
*/
void Identifier::setName(const std::string& name)
{
- if (!this->bSetName_)
+ if (name != this->name_)
{
this->name_ = name;
- this->bSetName_ = true;
- IdentifierManager::getInstance().registerIdentifier(this);
+ IdentifierManager::getInstance().addIdentifierToLookupMaps(this);
}
}
@@ -193,10 +125,108 @@
void Identifier::setNetworkID(uint32_t id)
{
this->networkID_ = id;
- IdentifierManager::getInstance().registerIdentifier(this);
+ IdentifierManager::getInstance().addIdentifierToLookupMaps(this);
}
/**
+ * @brief Used to define the direct parents of an Identifier of an abstract class.
+ */
+ Identifier& Identifier::inheritsFrom(Identifier* directParent)
+ {
+ if (this->parents_.empty())
+ this->directParents_.insert(directParent);
+ else
+ orxout(internal_error) << "Trying to add " << directParent->getName() << " as a direct parent of " << this->getName() << " after the latter was already initialized" << endl;
+
+ return *this;
+ }
+
+ /**
+ * @brief Initializes the parents of this Identifier while creating the class hierarchy.
+ * @param identifiers All identifiers that were used to create an instance of this class (including this identifier itself)
+ */
+ void Identifier::initializeParents(const std::set<const Identifier*>& identifiers)
+ {
+ if (!IdentifierManager::getInstance().isCreatingHierarchy())
+ {
+ orxout(internal_warning) << "Identifier::initializeParents() created outside of class hierarchy creation" << endl;
+ return;
+ }
+
+ for (std::set<const Identifier*>::const_iterator it = identifiers.begin(); it != identifiers.end(); ++it)
+ if (*it != this)
+ this->parents_.insert(*it);
+ }
+
+ /**
+ * @brief Initializes the direct parents of this Identifier while creating the class hierarchy. This is only intended for abstract classes.
+ */
+ void Identifier::initializeDirectParentsOfAbstractClass()
+ {
+ if (!IdentifierManager::getInstance().isCreatingHierarchy())
+ {
+ orxout(internal_warning) << "Identifier::initializeDirectParentsOfAbstractClass() created outside of class hierarchy creation" << endl;
+ return;
+ }
+
+ // only Identifiable is allowed to have no parents (even tough it's currently not abstract)
+ if (this->directParents_.empty() && !this->isExactlyA(Class(Identifiable)))
+ {
+ orxout(internal_error) << "Identifier " << this->getName() << " / " << this->getTypeidName() << " 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;
+ }
+ }
+
+ /**
+ * @brief Finishes the initialization of this Identifier after creating the class hierarchy by wiring the (direct) parent/child references correctly.
+ */
+ void Identifier::finishInitialization()
+ {
+ if (!IdentifierManager::getInstance().isCreatingHierarchy())
+ {
+ orxout(internal_warning) << "Identifier::finishInitialization() created outside of class hierarchy creation" << endl;
+ return;
+ }
+
+ if (this->isInitialized())
+ return;
+
+ // if no direct parents were defined, initialize them with the set of all parents
+ if (this->directParents_.empty())
+ this->directParents_ = this->parents_;
+
+ // initialize all parents before continuing to initialize this identifier
+ for (std::set<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)
+ {
+ Identifier* directParent = const_cast<Identifier*>(*it);
+ directParent->finishInitialization(); // initialize parent
+ this->parents_.insert(directParent); // direct parent is also a parent
+ this->parents_.insert(directParent->parents_.begin(), directParent->parents_.end()); // parents of direct parent are also parents
+ }
+
+ // parents of parents are no direct parents of this identifier
+ for (std::set<const Identifier*>::const_iterator it_parent = this->parents_.begin(); it_parent != this->parents_.end(); ++it_parent)
+ 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)
+ this->directParents_.erase(*it_parent_parent);
+
+ // tell all parents that this identifier is a child
+ for (std::set<const Identifier*>::const_iterator it = this->parents_.begin(); it != this->parents_.end(); ++it)
+ const_cast<Identifier*>(*it)->children_.insert(this);
+
+ // tell all direct parents that this identifier is a direct child
+ for (std::set<const Identifier*>::const_iterator it = this->directParents_.begin(); it != this->directParents_.end(); ++it)
+ {
+ const_cast<Identifier*>(*it)->directChildren_.insert(this);
+
+ // Create the super-function dependencies
+ (*it)->createSuperFunctionCaller();
+ }
+
+ this->bInitialized_ = true;
+ }
+
+ /**
@brief Returns true, if the Identifier is at least of the given type.
@param identifier The identifier to compare with
*/
Modified: code/branches/core6/src/libraries/core/class/Identifier.h
===================================================================
--- code/branches/core6/src/libraries/core/class/Identifier.h 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/src/libraries/core/class/Identifier.h 2013-08-13 21:35:26 UTC (rev 9646)
@@ -138,6 +138,19 @@
/// Set the class to be loadable through XML or not.
inline void setLoadable(bool bLoadable) { this->bLoadable_ = bLoadable; }
+ /// Returns true if the Identifier was completely initialized.
+ inline bool isInitialized() const { return this->bInitialized_; }
+
+
+ /////////////////////////////
+ ////// Class Hierarchy //////
+ /////////////////////////////
+ Identifier& inheritsFrom(Identifier* directParent);
+
+ void initializeParents(const std::set<const Identifier*>& identifiers);
+ void initializeDirectParentsOfAbstractClass();
+ void finishInitialization();
+
bool isA(const Identifier* identifier) const;
bool isExactlyA(const Identifier* identifier) const;
bool isChildOf(const Identifier* identifier) const;
@@ -145,10 +158,6 @@
bool isParentOf(const Identifier* identifier) const;
bool isDirectParentOf(const Identifier* identifier) const;
-
- /////////////////////////////
- ////// Class Hierarchy //////
- /////////////////////////////
/// Returns the parents of the class the Identifier belongs to.
inline const std::set<const Identifier*>& getParents() const { return this->parents_; }
/// Returns the begin-iterator of the parents-list.
@@ -217,24 +226,14 @@
protected:
virtual void createSuperFunctionCaller() const = 0;
- void initializeClassHierarchy(std::set<const Identifier*>* parents, bool bRootClass);
-
- /// Returns the children of the class the Identifier belongs to.
- inline std::set<const Identifier*>& getChildrenIntern() const { return this->children_; }
- /// Returns the direct children of the class the Identifier belongs to.
- inline std::set<const Identifier*>& getDirectChildrenIntern() const { return this->directChildren_; }
-
private:
- void initialize(std::set<const Identifier*>* parents);
-
std::set<const Identifier*> parents_; //!< The parents of the class the Identifier belongs to
- mutable std::set<const Identifier*> children_; //!< The children of the class the Identifier belongs to
+ std::set<const Identifier*> children_; //!< The children of the class the Identifier belongs to
std::set<const Identifier*> directParents_; //!< The direct parents of the class the Identifier belongs to
- mutable std::set<const Identifier*> directChildren_; //!< The direct children of the class the Identifier belongs to
+ std::set<const Identifier*> directChildren_; //!< The direct children of the class the Identifier belongs to
- bool bCreatedOneObject_; //!< True if at least one object of the given type was created (used to determine the need of storing the parents)
- bool bSetName_; //!< True if the name is set
+ bool bInitialized_; //!< Is true if the Identifier was completely initialized
bool bLoadable_; //!< False = it's not permitted to load the object through XML
std::string name_; //!< The name of the class the Identifier belongs to
Factory* factory_; //!< The Factory, able to create new objects of the given class (if available)
@@ -276,7 +275,7 @@
static ClassIdentifier<T>* getIdentifier();
static ClassIdentifier<T>* getIdentifier(const std::string& name);
- bool initializeObject(T* object, const std::string& className, bool bRootClass);
+ bool initializeObject(T* object);
void setConfigValues(T* object, Configurable*) const;
void setConfigValues(T* object, Identifiable*) const;
@@ -350,7 +349,7 @@
ClassIdentifier<T>* proposal = new ClassIdentifier<T>();
// Get the entry from the map
- ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*)IdentifierManager::getInstance().getIdentifierSingleton(proposal);
+ ClassIdentifier<T>::classIdentifier_s = (ClassIdentifier<T>*)IdentifierManager::getInstance().getGloballyUniqueIdentifier(proposal);
if (ClassIdentifier<T>::classIdentifier_s == proposal)
orxout(verbose, context::identifier) << "Requested Identifier for " << proposal->getTypeidName() << " was not yet existing and got created." << endl;
@@ -364,29 +363,17 @@
/**
@brief Adds an object of the given type to the ObjectList.
@param object The object to add
- @param className The name of the class T
- @param bRootClass True if this is a root class (i.e. it inherits directly from OrxonoxClass)
*/
template <class T>
- bool ClassIdentifier<T>::initializeObject(T* object, const std::string& className, bool bRootClass)
+ bool ClassIdentifier<T>::initializeObject(T* object)
{
- if (bRootClass)
- orxout(verbose, context::object_list) << "Register Root-Object: " << className << endl;
- else
- orxout(verbose, context::object_list) << "Register Object: " << className << endl;
+ orxout(verbose, context::object_list) << "Register Object: " << this->getName() << endl;
object->identifier_ = this;
if (IdentifierManager::getInstance().isCreatingHierarchy())
{
- if (bRootClass && !object->parents_)
- object->parents_ = new std::set<const Identifier*>();
+ IdentifierManager::getInstance().createdObject(object);
- if (object->parents_)
- {
- this->initializeClassHierarchy(object->parents_, bRootClass);
- object->parents_->insert(object->parents_->end(), this);
- }
-
this->setConfigValues(object, object);
return true;
}
Modified: code/branches/core6/src/libraries/core/class/IdentifierManager.cc
===================================================================
--- code/branches/core6/src/libraries/core/class/IdentifierManager.cc 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/src/libraries/core/class/IdentifierManager.cc 2013-08-13 21:35:26 UTC (rev 9646)
@@ -36,6 +36,7 @@
#include <ostream>
#include "util/StringUtils.h"
+#include "core/CoreIncludes.h"
#include "core/config/ConfigValueContainer.h"
#include "core/XMLPort.h"
#include "core/object/ClassFactory.h"
@@ -59,7 +60,7 @@
@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(Identifier* proposal)
+ Identifier* IdentifierManager::getGloballyUniqueIdentifier(Identifier* proposal)
{
const std::string& typeidName = proposal->getTypeidName();
std::map<std::string, Identifier*>::const_iterator it = this->identifierByTypeidName_.find(typeidName);
@@ -80,11 +81,17 @@
/**
* Registers the identifier in all maps of the IdentifierManager.
*/
- void IdentifierManager::registerIdentifier(Identifier* identifier)
+ void IdentifierManager::addIdentifierToLookupMaps(Identifier* identifier)
{
- IdentifierManager::getInstance().identifierByString_[identifier->getName()] = identifier;
- IdentifierManager::getInstance().identifierByLowercaseString_[getLowercase(identifier->getName())] = identifier;
- IdentifierManager::getInstance().identifierByNetworkId_[identifier->getNetworkID()] = 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;
}
/**
@@ -94,15 +101,42 @@
{
orxout(internal_status) << "Create class-hierarchy" << endl;
this->startCreatingHierarchy();
- for (std::map<std::string, Identifier*>::const_iterator it = this->identifierByTypeidName_.begin(); it != this->identifierByTypeidName_.end(); ++it)
+
+ std::set<Identifier*> initializedIdentifiers;
+
+ // iterate over all identifiers, create one instance of each class and initialize the identifiers
{
- // To create the new branch of the class-hierarchy, we create a new object and delete it afterwards.
- if (it->second->hasFactory())
+ Context temporaryContext(NULL);
+ for (std::map<std::string, Identifier*>::const_iterator it = this->identifierByTypeidName_.begin(); it != this->identifierByTypeidName_.end(); ++it)
{
- Identifiable* temp = it->second->fabricate(0);
- delete temp;
+ 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 has unexpected identifier" << endl;
+ delete temp;
+
+ it->second->initializeParents(this->identifiersOfNewObject_);
+ }
+ else
+ it->second->initializeDirectParentsOfAbstractClass();
+
+ initializedIdentifiers.insert(it->second);
}
}
+
+ // 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;
}
@@ -122,6 +156,17 @@
}
/**
+ * @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;
+ }
+
+ /**
@brief Returns the Identifier with a given name.
@param name The name of the wanted Identifier
@return The Identifier
Modified: code/branches/core6/src/libraries/core/class/IdentifierManager.h
===================================================================
--- code/branches/core6/src/libraries/core/class/IdentifierManager.h 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/src/libraries/core/class/IdentifierManager.h 2013-08-13 21:35:26 UTC (rev 9646)
@@ -37,6 +37,7 @@
#include "core/CorePrereqs.h"
#include <map>
+#include <set>
#include <string>
namespace orxonox
@@ -46,8 +47,8 @@
public:
static IdentifierManager& getInstance();
- Identifier* getIdentifierSingleton(Identifier* proposal);
- void registerIdentifier(Identifier* identifier);
+ Identifier* getGloballyUniqueIdentifier(Identifier* proposal);
+ void addIdentifierToLookupMaps(Identifier* identifier);
unsigned int getUniqueClassId()
{ return this->classIDCounter_s++; }
@@ -59,6 +60,8 @@
void createClassHierarchy();
void destroyAllIdentifiers();
+ void createdObject(Identifiable* identifiable);
+
/// Returns true, if a branch of the class-hierarchy is being created, causing all new objects to store their parents.
inline bool isCreatingHierarchy()
{ return (hierarchyCreatingCounter_s > 0); }
@@ -102,6 +105,7 @@
std::map<uint32_t, Identifier*> identifierByNetworkId_; //!< Returns the map that stores all Identifiers with their network IDs.
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)
+ std::set<const Identifier*> identifiersOfNewObject_; //!< Used while creating the object hierarchy to keep track of the identifiers of a newly created object
unsigned int classIDCounter_s; //!< counter for the unique classIDs
};
}
Added: code/branches/core6/src/libraries/core/class/OrxonoxClass.cc
===================================================================
--- code/branches/core6/src/libraries/core/class/OrxonoxClass.cc (rev 0)
+++ code/branches/core6/src/libraries/core/class/OrxonoxClass.cc 2013-08-13 21:35:26 UTC (rev 9646)
@@ -0,0 +1,40 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Fabian 'x3n' Landau
+ * Co-authors:
+ * ...
+ *
+ */
+
+#include "OrxonoxClass.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+ RegisterClassNoArgs(OrxonoxClass);
+
+ OrxonoxClass::OrxonoxClass()
+ {
+ RegisterObject(OrxonoxClass);
+ }
+}
Property changes on: code/branches/core6/src/libraries/core/class/OrxonoxClass.cc
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: code/branches/core6/src/libraries/core/class/OrxonoxClass.h
===================================================================
--- code/branches/core6/src/libraries/core/class/OrxonoxClass.h 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/src/libraries/core/class/OrxonoxClass.h 2013-08-13 21:35:26 UTC (rev 9646)
@@ -52,6 +52,8 @@
*/
class _CoreExport OrxonoxClass : virtual public Configurable, virtual public Destroyable
{
+ public:
+ OrxonoxClass();
};
}
Added: code/branches/core6/src/libraries/core/class/OrxonoxInterface.cc
===================================================================
--- code/branches/core6/src/libraries/core/class/OrxonoxInterface.cc (rev 0)
+++ code/branches/core6/src/libraries/core/class/OrxonoxInterface.cc 2013-08-13 21:35:26 UTC (rev 9646)
@@ -0,0 +1,40 @@
+/*
+ * ORXONOX - the hottest 3D action shooter ever to exist
+ * > www.orxonox.net <
+ *
+ *
+ * License notice:
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Author:
+ * Fabian 'x3n' Landau
+ * Co-authors:
+ * ...
+ *
+ */
+
+#include "OrxonoxInterface.h"
+#include "core/CoreIncludes.h"
+
+namespace orxonox
+{
+ RegisterClassNoArgs(OrxonoxInterface);
+
+ OrxonoxInterface::OrxonoxInterface()
+ {
+ RegisterObject(OrxonoxInterface);
+ }
+}
Property changes on: code/branches/core6/src/libraries/core/class/OrxonoxInterface.cc
___________________________________________________________________
Added: svn:eol-style
+ native
Modified: code/branches/core6/src/libraries/core/class/OrxonoxInterface.h
===================================================================
--- code/branches/core6/src/libraries/core/class/OrxonoxInterface.h 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/src/libraries/core/class/OrxonoxInterface.h 2013-08-13 21:35:26 UTC (rev 9646)
@@ -49,6 +49,8 @@
*/
class _CoreExport OrxonoxInterface : virtual public Configurable, virtual public Destroyable
{
+ public:
+ OrxonoxInterface();
};
}
Modified: code/branches/core6/src/libraries/core/class/Super.h
===================================================================
--- code/branches/core6/src/libraries/core/class/Super.h 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/src/libraries/core/class/Super.h 2013-08-13 21:35:26 UTC (rev 9646)
@@ -102,7 +102,7 @@
static void apply(baseclass*) \
{ \
ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier(); \
- for (std::set<const Identifier*>::iterator it = identifier->getDirectChildrenIntern().begin(); it != identifier->getDirectChildrenIntern().end(); ++it) \
+ for (std::set<const Identifier*>::iterator it = identifier->getDirectChildren().begin(); it != identifier->getDirectChildren().end(); ++it) \
{ \
if (((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ && ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_) \
{ \
@@ -170,7 +170,7 @@
ClassIdentifier<T>* identifier = ClassIdentifier<T>::getIdentifier();
// Iterate through all children
- for (std::set<const Identifier*>::iterator it = identifier->getDirectChildrenIntern().begin(); it != identifier->getDirectChildrenIntern().end(); ++it)
+ for (std::set<const Identifier*>::iterator it = identifier->getDirectChildren().begin(); it != identifier->getDirectChildren().end(); ++it)
{
// Check if the caller is a fallback-caller
if (((ClassIdentifier<T>*)(*it))->bSuperFunctionCaller_##functionname##_isFallback_ && ((ClassIdentifier<T>*)(*it))->superFunctionCaller_##functionname##_)
Modified: code/branches/core6/test/core/class/IdentifierClassHierarchyTest.cc
===================================================================
--- code/branches/core6/test/core/class/IdentifierClassHierarchyTest.cc 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/test/core/class/IdentifierClassHierarchyTest.cc 2013-08-13 21:35:26 UTC (rev 9646)
@@ -19,45 +19,122 @@
namespace
{
class BaseInterface1 : public OrxonoxInterface
- { public: BaseInterface1() { RegisterRootObject(BaseInterface1); } };
+ {
+ public:
+ BaseInterface1()
+ {
+ RegisterRootObject(BaseInterface1);
+ }
+ virtual void test1() = 0;
+ };
+
class BaseInterface2 : public OrxonoxInterface
- { public: BaseInterface2() { RegisterRootObject(BaseInterface2); } };
+ {
+ public:
+ BaseInterface2()
+ {
+ RegisterRootObject(BaseInterface2);
+ }
+ virtual void test2() = 0;
+ };
+
class Interface1 : public BaseInterface1
- { public: Interface1() { RegisterObject(Interface1); } };
+ {
+ public:
+ Interface1()
+ {
+ RegisterObject(Interface1);
+ }
+ };
class Interface2 : public BaseInterface2
- { public: Interface2() { RegisterObject(Interface2); } };
+ {
+ public:
+ Interface2()
+ {
+ RegisterObject(Interface2);
+ }
+ };
class BaseClass : public OrxonoxClass
- { public: BaseClass() { RegisterRootObject(BaseClass); } };
+ {
+ public:
+ BaseClass()
+ {
+ RegisterRootObject(BaseClass);
+ }
+ };
class Class0 : public BaseClass
- { public: Class0() { RegisterObject(Class0); } };
+ {
+ public:
+ Class0()
+ {
+ RegisterObject(Class0);
+ }
+ };
class Class1 : public BaseClass, public Interface1
- { public: Class1() { RegisterObject(Class1); } };
+ {
+ public:
+ Class1()
+ {
+ RegisterObject(Class1);
+ }
+ virtual void test1() {}
+ };
+
class Class2a : public BaseClass, public Interface1, Interface2
- { public: Class2a() { RegisterObject(Class2a); } };
+ {
+ public:
+ Class2a()
+ {
+ RegisterObject(Class2a);
+ }
+ virtual void test1() {}
+ virtual void test2() {}
+ };
+
class Class2b : public BaseClass, public Interface2, Interface1
- { public: Class2b() { RegisterObject(Class2b); } };
+ {
+ public:
+ Class2b()
+ {
+ RegisterObject(Class2b);
+ }
+ virtual void test1() {}
+ virtual void test2() {}
+ };
+
class Class3 : public BaseClass, public BaseInterface1, BaseInterface2
- { public: Class3() { RegisterObject(Class3); } };
+ {
+ public:
+ Class3()
+ {
+ RegisterObject(Class3);
+ }
+ virtual void test1() {}
+ virtual void test2() {}
+ };
+
// Fixture
class IdentifierClassHierarchyTest : public ::testing::Test
{
public:
virtual void SetUp()
{
- registerClass("BaseInterface1", new ClassFactoryNoArgs<BaseInterface1>());
- registerClass("BaseInterface2", new ClassFactoryNoArgs<BaseInterface2>());
- registerClass("Interface1", new ClassFactoryNoArgs<Interface1>());
- registerClass("Interface2", new ClassFactoryNoArgs<Interface2>());
+ registerClass("OrxonoxInterface", new ClassFactoryNoArgs<OrxonoxInterface>());
+ registerClass("OrxonoxClass", new ClassFactoryNoArgs<OrxonoxClass>());
+ registerClass("BaseInterface1", static_cast<ClassFactory<BaseInterface1>*>(NULL), false).inheritsFrom(Class(OrxonoxInterface));
+ registerClass("BaseInterface2", static_cast<ClassFactory<BaseInterface2>*>(NULL), false).inheritsFrom(Class(OrxonoxInterface));
+ registerClass("Interface1", static_cast<ClassFactory<Interface1>*>(NULL), false).inheritsFrom(Class(BaseInterface1));
+ registerClass("Interface2", static_cast<ClassFactory<Interface2>*>(NULL), false).inheritsFrom(Class(BaseInterface2));
registerClass("BaseClass", new ClassFactoryNoArgs<BaseClass>());
registerClass("Class0", new ClassFactoryNoArgs<Class0>());
registerClass("Class1", new ClassFactoryNoArgs<Class1>());
@@ -73,6 +150,11 @@
IdentifierManager::getInstance().destroyAllIdentifiers();
}
};
+
+ bool contains(const std::set<const Identifier*> identifiers, Identifier* identifier)
+ {
+ return identifiers.find(identifier) != identifiers.end();
+ }
}
TEST(IdentifierClassHierarchyTest_NoFixture, NoInitialization)
@@ -134,9 +216,22 @@
Identifier* identifier = Class(BaseInterface1);
EXPECT_EQ(2u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Interface1)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class3)));
+
EXPECT_EQ(5u, identifier->getChildren().size());
- EXPECT_EQ(0u, identifier->getDirectParents().size());
- EXPECT_EQ(0u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Interface1)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class3)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class1)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class2a)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class2b)));
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(OrxonoxInterface)));
+
+ EXPECT_EQ(2u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxInterface)));
}
TEST_F(IdentifierClassHierarchyTest, TestBaseInterface2)
@@ -144,9 +239,21 @@
Identifier* identifier = Class(BaseInterface2);
EXPECT_EQ(2u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Interface2)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class3)));
+
EXPECT_EQ(4u, identifier->getChildren().size());
- EXPECT_EQ(0u, identifier->getDirectParents().size());
- EXPECT_EQ(0u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Interface2)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class3)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class2a)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class2b)));
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(OrxonoxInterface)));
+
+ EXPECT_EQ(2u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxInterface)));
}
TEST_F(IdentifierClassHierarchyTest, TestInterface1)
@@ -154,9 +261,22 @@
Identifier* identifier = Class(Interface1);
EXPECT_EQ(3u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class1)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class2a)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class2b)));
+
EXPECT_EQ(3u, identifier->getChildren().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class1)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class2a)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class2b)));
+
EXPECT_EQ(1u, identifier->getDirectParents().size());
- EXPECT_EQ(1u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(BaseInterface1)));
+
+ EXPECT_EQ(3u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxInterface)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseInterface1)));
}
TEST_F(IdentifierClassHierarchyTest, TestInterface2)
@@ -164,9 +284,20 @@
Identifier* identifier = Class(Interface2);
EXPECT_EQ(2u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class2a)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class2b)));
+
EXPECT_EQ(2u, identifier->getChildren().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class2a)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class2b)));
+
EXPECT_EQ(1u, identifier->getDirectParents().size());
- EXPECT_EQ(1u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(BaseInterface2)));
+
+ EXPECT_EQ(3u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxInterface)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseInterface2)));
}
TEST_F(IdentifierClassHierarchyTest, TestBaseClass)
@@ -174,9 +305,25 @@
Identifier* identifier = Class(BaseClass);
EXPECT_EQ(5u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class0)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class1)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class2a)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class2b)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class3)));
+
EXPECT_EQ(5u, identifier->getChildren().size());
- EXPECT_EQ(0u, identifier->getDirectParents().size());
- EXPECT_EQ(0u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class0)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class1)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class2a)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class2b)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class3)));
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(OrxonoxClass)));
+
+ EXPECT_EQ(2u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
}
TEST_F(IdentifierClassHierarchyTest, TestClass0)
@@ -184,9 +331,16 @@
Identifier* identifier = Class(Class0);
EXPECT_EQ(0u, identifier->getDirectChildren().size());
+
EXPECT_EQ(0u, identifier->getChildren().size());
+
EXPECT_EQ(1u, identifier->getDirectParents().size());
- EXPECT_EQ(1u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(BaseClass)));
+
+ EXPECT_EQ(3u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
}
TEST_F(IdentifierClassHierarchyTest, TestClass1)
@@ -194,9 +348,20 @@
Identifier* identifier = Class(Class1);
EXPECT_EQ(0u, identifier->getDirectChildren().size());
+
EXPECT_EQ(0u, identifier->getChildren().size());
+
EXPECT_EQ(2u, identifier->getDirectParents().size());
- EXPECT_EQ(3u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(BaseClass)));
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(Interface1)));
+
+ EXPECT_EQ(6u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxInterface)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseInterface1)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Interface1)));
}
TEST_F(IdentifierClassHierarchyTest, TestClass2a)
@@ -204,9 +369,23 @@
Identifier* identifier = Class(Class2a);
EXPECT_EQ(0u, identifier->getDirectChildren().size());
+
EXPECT_EQ(0u, identifier->getChildren().size());
+
EXPECT_EQ(3u, identifier->getDirectParents().size());
- EXPECT_EQ(5u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(BaseClass)));
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(Interface1)));
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(Interface2)));
+
+ EXPECT_EQ(8u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxInterface)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseInterface1)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Interface1)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseInterface2)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Interface2)));
}
TEST_F(IdentifierClassHierarchyTest, TestClass2b)
@@ -214,9 +393,23 @@
Identifier* identifier = Class(Class2b);
EXPECT_EQ(0u, identifier->getDirectChildren().size());
+
EXPECT_EQ(0u, identifier->getChildren().size());
+
EXPECT_EQ(3u, identifier->getDirectParents().size());
- EXPECT_EQ(5u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(BaseClass)));
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(Interface1)));
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(Interface2)));
+
+ EXPECT_EQ(8u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxInterface)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseInterface1)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Interface1)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseInterface2)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Interface2)));
}
TEST_F(IdentifierClassHierarchyTest, TestClass3)
@@ -224,8 +417,20 @@
Identifier* identifier = Class(Class3);
EXPECT_EQ(0u, identifier->getDirectChildren().size());
+
EXPECT_EQ(0u, identifier->getChildren().size());
+
EXPECT_EQ(3u, identifier->getDirectParents().size());
- EXPECT_EQ(3u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(BaseClass)));
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(BaseInterface1)));
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(BaseInterface2)));
+
+ EXPECT_EQ(6u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxInterface)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseInterface1)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseInterface2)));
}
}
Modified: code/branches/core6/test/core/class/IdentifierExternalClassHierarchyTest.cc
===================================================================
--- code/branches/core6/test/core/class/IdentifierExternalClassHierarchyTest.cc 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/test/core/class/IdentifierExternalClassHierarchyTest.cc 2013-08-13 21:35:26 UTC (rev 9646)
@@ -7,21 +7,43 @@
namespace
{
class Interface : virtual public Identifiable
- { public: Interface() { RegisterRootObject(Interface); } };
+ {
+ public:
+ Interface()
+ {
+ RegisterRootObject(Interface);
+ }
+ virtual void test() = 0;
+ };
+
class BaseClass : virtual public Identifiable
- { public: BaseClass() { RegisterRootObject(BaseClass); } };
+ {
+ public:
+ BaseClass()
+ {
+ RegisterRootObject(BaseClass);
+ }
+ };
class RealClass : public BaseClass, public Interface
- { public: RealClass() { RegisterObject(RealClass); } };
+ {
+ public:
+ RealClass()
+ {
+ RegisterObject(RealClass);
+ }
+ virtual void test() {}
+ };
+
// Fixture
class IdentifierExternalClassHierarchyTest : public ::testing::Test
{
public:
virtual void SetUp()
{
- registerClass("Interface", new ClassFactoryNoArgs<Interface>());
+ registerClass("Interface", static_cast<ClassFactory<Interface>*>(NULL), false).inheritsFrom(Class(Identifiable));
registerClass("BaseClass", new ClassFactoryNoArgs<BaseClass>());
registerClass("RealClass", new ClassFactoryNoArgs<RealClass>());
@@ -33,6 +55,11 @@
IdentifierManager::getInstance().destroyAllIdentifiers();
}
};
+
+ bool contains(const std::set<const Identifier*> identifiers, Identifier* identifier)
+ {
+ return identifiers.find(identifier) != identifiers.end();
+ }
}
TEST(IdentifierExternalClassHierarchyTest_NoFixture, NoInitialization)
@@ -58,23 +85,51 @@
{
Identifier* identifier = Class(Interface);
+ EXPECT_EQ(1u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(RealClass)));
+
EXPECT_EQ(1u, identifier->getChildren().size());
- EXPECT_EQ(0u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(RealClass)));
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(Identifiable)));
+
+ EXPECT_EQ(1u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
}
TEST_F(IdentifierExternalClassHierarchyTest, BaseClass)
{
Identifier* identifier = Class(BaseClass);
+ EXPECT_EQ(1u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(RealClass)));
+
EXPECT_EQ(1u, identifier->getChildren().size());
- EXPECT_EQ(0u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(RealClass)));
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(Identifiable)));
+
+ EXPECT_EQ(1u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
}
TEST_F(IdentifierExternalClassHierarchyTest, RealClass)
{
Identifier* identifier = Class(RealClass);
+ EXPECT_EQ(0u, identifier->getDirectChildren().size());
+
EXPECT_EQ(0u, identifier->getChildren().size());
- EXPECT_EQ(2u, identifier->getParents().size());
+
+ EXPECT_EQ(2u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(Interface)));
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(BaseClass)));
+
+ EXPECT_EQ(3u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Interface)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
}
}
Modified: code/branches/core6/test/core/class/IdentifierSimpleClassHierarchyTest.cc
===================================================================
--- code/branches/core6/test/core/class/IdentifierSimpleClassHierarchyTest.cc 2013-08-13 19:39:30 UTC (rev 9645)
+++ code/branches/core6/test/core/class/IdentifierSimpleClassHierarchyTest.cc 2013-08-13 21:35:26 UTC (rev 9646)
@@ -9,21 +9,45 @@
namespace
{
class Interface : public OrxonoxInterface
- { public: Interface() { RegisterRootObject(Interface); } };
+ {
+ public:
+ Interface()
+ {
+ RegisterRootObject(Interface);
+ }
+ virtual void test() = 0;
+ };
+
class BaseClass : public OrxonoxClass
- { public: BaseClass() { RegisterRootObject(BaseClass); } };
+ {
+ public:
+ BaseClass()
+ {
+ RegisterRootObject(BaseClass);
+ }
+ };
class RealClass : public BaseClass, public Interface
- { public: RealClass() { RegisterObject(RealClass); } };
+ {
+ public:
+ RealClass()
+ {
+ RegisterObject(RealClass);
+ }
+ virtual void test() {}
+ };
+
// Fixture
class IdentifierSimpleClassHierarchyTest : public ::testing::Test
{
public:
virtual void SetUp()
{
- registerClass("Interface", new ClassFactoryNoArgs<Interface>());
+ registerClass("OrxonoxInterface", new ClassFactoryNoArgs<OrxonoxInterface>());
+ registerClass("OrxonoxClass", new ClassFactoryNoArgs<OrxonoxClass>());
+ registerClass("Interface", static_cast<ClassFactory<Interface>*>(NULL), false).inheritsFrom(Class(OrxonoxInterface));
registerClass("BaseClass", new ClassFactoryNoArgs<BaseClass>());
registerClass("RealClass", new ClassFactoryNoArgs<RealClass>());
@@ -35,6 +59,11 @@
IdentifierManager::getInstance().destroyAllIdentifiers();
}
};
+
+ bool contains(const std::set<const Identifier*> identifiers, Identifier* identifier)
+ {
+ return identifiers.find(identifier) != identifiers.end();
+ }
}
TEST(IdentifierSimpleClassHierarchyTest_NoFixture, NoInitialization)
@@ -60,23 +89,55 @@
{
Identifier* identifier = Class(Interface);
+ EXPECT_EQ(1u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(RealClass)));
+
EXPECT_EQ(1u, identifier->getChildren().size());
- EXPECT_EQ(0u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(RealClass)));
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(OrxonoxInterface)));
+
+ EXPECT_EQ(2u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxInterface)));
}
TEST_F(IdentifierSimpleClassHierarchyTest, BaseClass)
{
Identifier* identifier = Class(BaseClass);
+ EXPECT_EQ(1u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(RealClass)));
+
EXPECT_EQ(1u, identifier->getChildren().size());
- EXPECT_EQ(0u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(RealClass)));
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(OrxonoxClass)));
+
+ EXPECT_EQ(2u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
}
TEST_F(IdentifierSimpleClassHierarchyTest, RealClass)
{
Identifier* identifier = Class(RealClass);
+ EXPECT_EQ(0u, identifier->getDirectChildren().size());
+
EXPECT_EQ(0u, identifier->getChildren().size());
- EXPECT_EQ(2u, identifier->getParents().size());
+
+ EXPECT_EQ(2u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(Interface)));
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(BaseClass)));
+
+ EXPECT_EQ(5u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxInterface)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Interface)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
}
}
More information about the Orxonox-commit
mailing list