[Orxonox-commit 5703] r10363 - in code/branches/core7: src/libraries/core/class test/core test/core/class
landauf at orxonox.net
landauf at orxonox.net
Mon Apr 13 23:15:05 CEST 2015
Author: landauf
Date: 2015-04-13 23:15:04 +0200 (Mon, 13 Apr 2015)
New Revision: 10363
Added:
code/branches/core7/test/core/class/IdentifierNestedClassHierarchyTest.cc
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/test/core/CMakeLists.txt
Log:
bugfix: class hierarchy wrongly considered the classes of nested members as base classes of the surrounding class. this is now fixed by using RTTI (i.e. dynamic_cast). also added some tests.
Modified: code/branches/core7/src/libraries/core/class/Identifier.cc
===================================================================
--- code/branches/core7/src/libraries/core/class/Identifier.cc 2015-04-12 21:07:14 UTC (rev 10362)
+++ code/branches/core7/src/libraries/core/class/Identifier.cc 2015-04-13 21:15:04 UTC (rev 10363)
@@ -143,9 +143,10 @@
/**
* @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)
+ * @param instance The instance that was used to determine the class hierarchy of this identifier.
+ * @param identifiers All identifiers that were used to create the instance of this class (including this identifier itself)
*/
- void Identifier::initializeParents(const std::set<const Identifier*>& identifiers)
+ void Identifier::initializeParents(Identifiable* instance, const std::set<const Identifier*>& identifiers)
{
if (!IdentifierManager::getInstance().isCreatingHierarchy())
{
@@ -153,8 +154,11 @@
return;
}
+ // Add all identifiers which are real parents (dynamic_cast is possible) and that are not equal to THIS identifier.
+ // Checking for dynamic_cast is necessary because some classes may have other classes as nested members. This means that the Identifiers of the nested
+ // classes are also added to the set of potential parents. The only way to distinguish them is to use RTTI (i.e. dynamic_cast).
for (std::set<const Identifier*>::const_iterator it = identifiers.begin(); it != identifiers.end(); ++it)
- if (*it != this)
+ if (*it != this && (*it)->canDynamicCastObjectToIdentifierClass(instance))
this->parents_.insert(*it);
}
Modified: code/branches/core7/src/libraries/core/class/Identifier.h
===================================================================
--- code/branches/core7/src/libraries/core/class/Identifier.h 2015-04-12 21:07:14 UTC (rev 10362)
+++ code/branches/core7/src/libraries/core/class/Identifier.h 2015-04-13 21:15:04 UTC (rev 10363)
@@ -147,7 +147,7 @@
/////////////////////////////
Identifier& inheritsFrom(Identifier* directParent);
- void initializeParents(const std::set<const Identifier*>& identifiers);
+ void initializeParents(Identifiable* instance, const std::set<const Identifier*>& identifiers);
void initializeDirectParentsOfAbstractClass();
void finishInitialization();
@@ -222,7 +222,7 @@
void addXMLPortObjectContainer(const std::string& sectionname, XMLPortObjectContainer* container);
XMLPortObjectContainer* getXMLPortObjectContainer(const std::string& sectionname);
- virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) = 0;
+ virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) const = 0;
protected:
virtual void createSuperFunctionCaller() const = 0;
@@ -289,7 +289,7 @@
virtual const std::string& getTypeidName()
{ return this->typeidName_; }
- virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object)
+ virtual bool canDynamicCastObjectToIdentifierClass(Identifiable* object) const
{ return dynamic_cast<T*>(object) != 0; }
private:
Modified: code/branches/core7/src/libraries/core/class/IdentifierManager.cc
===================================================================
--- code/branches/core7/src/libraries/core/class/IdentifierManager.cc 2015-04-12 21:07:14 UTC (rev 10362)
+++ code/branches/core7/src/libraries/core/class/IdentifierManager.cc 2015-04-13 21:15:04 UTC (rev 10363)
@@ -121,9 +121,10 @@
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;
+
+ it->second->initializeParents(temp, this->identifiersOfNewObject_);
+
delete temp;
-
- it->second->initializeParents(this->identifiersOfNewObject_);
}
else
it->second->initializeDirectParentsOfAbstractClass();
Modified: code/branches/core7/test/core/CMakeLists.txt
===================================================================
--- code/branches/core7/test/core/CMakeLists.txt 2015-04-12 21:07:14 UTC (rev 10362)
+++ code/branches/core7/test/core/CMakeLists.txt 2015-04-13 21:15:04 UTC (rev 10363)
@@ -11,6 +11,7 @@
class/IdentifierTest.cc
class/IdentifierClassHierarchyTest.cc
class/IdentifierSimpleClassHierarchyTest.cc
+ class/IdentifierNestedClassHierarchyTest.cc
class/IdentifierExternalClassHierarchyTest.cc
class/OrxonoxClassTest.cc
class/OrxonoxInterfaceTest.cc
Added: code/branches/core7/test/core/class/IdentifierNestedClassHierarchyTest.cc
===================================================================
--- code/branches/core7/test/core/class/IdentifierNestedClassHierarchyTest.cc (rev 0)
+++ code/branches/core7/test/core/class/IdentifierNestedClassHierarchyTest.cc 2015-04-13 21:15:04 UTC (rev 10363)
@@ -0,0 +1,346 @@
+#include <gtest/gtest.h>
+#include "core/CoreIncludes.h"
+#include "core/class/Identifiable.h"
+#include "core/class/OrxonoxClass.h"
+#include "core/class/OrxonoxInterface.h"
+
+namespace orxonox
+{
+ // Tests the class hierarchy with classes that contain other classes as members.
+ //
+ // +------ Nested1 +------ Class1_notNested
+ // +------ Nested2 +------ Class2_oneNested
+ // OrxonoxClass <-----+------ BaseClass <-----+------ Class3_twoNested <----------- Class3_Child
+ // +------ Class4_class1Nested
+ // +------ Class5_class2Nested
+ // +------ Class6_class3Nested <-------- Class6_Child
+
+ namespace
+ {
+ class Nested1 : public OrxonoxClass
+ {
+ public:
+ Nested1() { RegisterObject(Nested1); }
+ };
+
+ class Nested2 : public OrxonoxClass
+ {
+ public:
+ Nested2() { RegisterObject(Nested2); }
+ };
+
+ class BaseClass : public OrxonoxClass
+ {
+ public:
+ BaseClass() { RegisterObject(BaseClass); }
+ };
+
+ class Class1_notNested : public BaseClass
+ {
+ public:
+ Class1_notNested() { RegisterObject(Class1_notNested); }
+ };
+
+ class Class2_oneNested : public BaseClass
+ {
+ public:
+ Class2_oneNested() { RegisterObject(Class2_oneNested); }
+ Nested1 nested1_;
+ };
+
+ class Class3_twoNested : public BaseClass
+ {
+ public:
+ Class3_twoNested() { RegisterObject(Class3_twoNested); }
+ Nested1 nested1_;
+ Nested2 nested2_;
+ };
+
+ class Class4_class1Nested : public BaseClass
+ {
+ public:
+ Class4_class1Nested() { RegisterObject(Class4_class1Nested); }
+ Class1_notNested nested_;
+ };
+
+ class Class5_class2Nested : public BaseClass
+ {
+ public:
+ Class5_class2Nested() { RegisterObject(Class5_class2Nested); }
+ Class2_oneNested nested_;
+ };
+
+ class Class6_class3Nested : public BaseClass
+ {
+ public:
+ Class6_class3Nested() { RegisterObject(Class6_class3Nested); }
+ Class3_twoNested nested_;
+ };
+
+ class Class3_Child : public Class3_twoNested
+ {
+ public:
+ Class3_Child() { RegisterObject(Class3_Child); }
+ };
+
+ class Class6_Child : public Class6_class3Nested
+ {
+ public:
+ Class6_Child() { RegisterObject(Class6_Child); }
+ };
+
+ // Fixture
+ class IdentifierNestedClassHierarchyTest : public ::testing::Test
+ {
+ public:
+ virtual void SetUp()
+ {
+ registerClass("Context", new ClassFactoryWithContext<Context>());
+ registerClass("Listable", new ClassFactoryWithContext<Listable>());
+ registerClass("Configurable", new ClassFactoryNoArgs<Configurable>());
+ registerClass("OrxonoxClass", new ClassFactoryNoArgs<OrxonoxClass>());
+ registerClass("Nested1", new ClassFactoryNoArgs<Nested1>());
+ registerClass("Nested2", new ClassFactoryNoArgs<Nested2>());
+ registerClass("BaseClass", new ClassFactoryNoArgs<BaseClass>());
+ registerClass("Class1_notNested", new ClassFactoryNoArgs<Class1_notNested>());
+ registerClass("Class2_oneNested", new ClassFactoryNoArgs<Class2_oneNested>());
+ registerClass("Class3_twoNested", new ClassFactoryNoArgs<Class3_twoNested>());
+ registerClass("Class4_class1Nested", new ClassFactoryNoArgs<Class4_class1Nested>());
+ registerClass("Class5_class2Nested", new ClassFactoryNoArgs<Class5_class2Nested>());
+ registerClass("Class6_class3Nested", new ClassFactoryNoArgs<Class6_class3Nested>());
+ registerClass("Class3_Child", new ClassFactoryNoArgs<Class3_Child>());
+ registerClass("Class6_Child", new ClassFactoryNoArgs<Class6_Child>());
+
+ IdentifierManager::getInstance().createClassHierarchy();
+ }
+
+ virtual void TearDown()
+ {
+ IdentifierManager::getInstance().destroyAllIdentifiers();
+ }
+ };
+
+ bool contains(const std::set<const Identifier*> identifiers, Identifier* identifier)
+ {
+ return identifiers.find(identifier) != identifiers.end();
+ }
+ }
+
+ TEST_F(IdentifierNestedClassHierarchyTest, TestNested1)
+ {
+ Identifier* identifier = Class(Nested1);
+
+ EXPECT_EQ(0u, identifier->getDirectChildren().size());
+ EXPECT_EQ(0u, identifier->getChildren().size());
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(OrxonoxClass)));
+
+ EXPECT_EQ(4u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Listable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Configurable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ }
+
+ TEST_F(IdentifierNestedClassHierarchyTest, TestNested2)
+ {
+ Identifier* identifier = Class(Nested2);
+
+ EXPECT_EQ(0u, identifier->getDirectChildren().size());
+ EXPECT_EQ(0u, identifier->getChildren().size());
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(OrxonoxClass)));
+
+ EXPECT_EQ(4u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Listable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Configurable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ }
+
+ TEST_F(IdentifierNestedClassHierarchyTest, TestBaseClass)
+ {
+ Identifier* identifier = Class(BaseClass);
+
+ EXPECT_EQ(6u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class1_notNested)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class2_oneNested)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class3_twoNested)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class4_class1Nested)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class5_class2Nested)));
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class6_class3Nested)));
+
+ EXPECT_EQ(8u, identifier->getChildren().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class1_notNested)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class2_oneNested)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class3_twoNested)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class4_class1Nested)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class5_class2Nested)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class6_class3Nested)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class3_Child)));
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class6_Child)));
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(OrxonoxClass)));
+
+ EXPECT_EQ(4u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Listable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Configurable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ }
+
+ TEST_F(IdentifierNestedClassHierarchyTest, TestClass1_notNested)
+ {
+ Identifier* identifier = Class(Class1_notNested);
+
+ EXPECT_EQ(0u, identifier->getDirectChildren().size());
+ EXPECT_EQ(0u, identifier->getChildren().size());
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ 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(Listable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Configurable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ }
+
+ TEST_F(IdentifierNestedClassHierarchyTest, TestClass2_oneNested)
+ {
+ Identifier* identifier = Class(Class2_oneNested);
+
+ EXPECT_EQ(0u, identifier->getDirectChildren().size());
+ EXPECT_EQ(0u, identifier->getChildren().size());
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ 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(Listable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Configurable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ }
+
+ TEST_F(IdentifierNestedClassHierarchyTest, TestClass3_twoNested)
+ {
+ Identifier* identifier = Class(Class3_twoNested);
+
+ EXPECT_EQ(1u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class3_Child)));
+
+ EXPECT_EQ(1u, identifier->getChildren().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class3_Child)));
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ 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(Listable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Configurable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ }
+
+ TEST_F(IdentifierNestedClassHierarchyTest, TestClass4_class1Nested)
+ {
+ Identifier* identifier = Class(Class4_class1Nested);
+
+ EXPECT_EQ(0u, identifier->getDirectChildren().size());
+ EXPECT_EQ(0u, identifier->getChildren().size());
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ 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(Listable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Configurable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ }
+
+ TEST_F(IdentifierNestedClassHierarchyTest, TestClass5_class2Nested)
+ {
+ Identifier* identifier = Class(Class5_class2Nested);
+
+ EXPECT_EQ(0u, identifier->getDirectChildren().size());
+ EXPECT_EQ(0u, identifier->getChildren().size());
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ 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(Listable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Configurable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ }
+
+ TEST_F(IdentifierNestedClassHierarchyTest, TestClass6_class3Nested)
+ {
+ Identifier* identifier = Class(Class6_class3Nested);
+
+ EXPECT_EQ(1u, identifier->getDirectChildren().size());
+ EXPECT_TRUE(contains(identifier->getDirectChildren(), Class(Class6_Child)));
+
+ EXPECT_EQ(1u, identifier->getChildren().size());
+ EXPECT_TRUE(contains(identifier->getChildren(), Class(Class6_Child)));
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ 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(Listable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Configurable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ }
+
+ TEST_F(IdentifierNestedClassHierarchyTest, TestClass3_Child)
+ {
+ Identifier* identifier = Class(Class3_Child);
+
+ EXPECT_EQ(0u, identifier->getDirectChildren().size());
+ EXPECT_EQ(0u, identifier->getChildren().size());
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(Class3_twoNested)));
+
+ EXPECT_EQ(6u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Listable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Configurable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Class3_twoNested)));
+ }
+
+ TEST_F(IdentifierNestedClassHierarchyTest, TestClass6_Child)
+ {
+ Identifier* identifier = Class(Class6_Child);
+
+ EXPECT_EQ(0u, identifier->getDirectChildren().size());
+ EXPECT_EQ(0u, identifier->getChildren().size());
+
+ EXPECT_EQ(1u, identifier->getDirectParents().size());
+ EXPECT_TRUE(contains(identifier->getDirectParents(), Class(Class6_class3Nested)));
+
+ EXPECT_EQ(6u, identifier->getParents().size());
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Identifiable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Listable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Configurable)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(OrxonoxClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(BaseClass)));
+ EXPECT_TRUE(contains(identifier->getParents(), Class(Class6_class3Nested)));
+ }
+}
More information about the Orxonox-commit
mailing list