#3214 AppFwk : Add function to get referencing objects of specified type

This commit is contained in:
Magne Sjaastad 2018-08-15 12:36:42 +02:00
parent 37962e040c
commit 97c3b9efea
2 changed files with 171 additions and 146 deletions

View File

@ -14,13 +14,11 @@
#include <vector>
class DemoPdmObject: public caf::PdmObjectHandle
class DemoPdmObject : public caf::PdmObjectHandle
{
public:
DemoPdmObject()
{
DemoPdmObject()
{
this->addField(&m_proxyDoubleField, "m_proxyDoubleField");
m_proxyDoubleField.registerSetMethod(this, &DemoPdmObject::setDoubleMember);
m_proxyDoubleField.registerGetMethod(this, &DemoPdmObject::doubleMember);
@ -34,105 +32,111 @@ public:
m_proxyStringField.registerGetMethod(this, &DemoPdmObject::stringMember);
this->addField(&m_memberDoubleField, "m_memberDoubleField");
this->addField(&m_memberIntField, "m_memberIntField");
this->addField(&m_memberIntField, "m_memberIntField");
this->addField(&m_memberStringField, "m_memberStringField");
// Default values
// Default values
m_doubleMember = 2.1;
m_intMember = 7;
m_intMember = 7;
m_stringMember = "abba";
m_memberDoubleField = 0.0;
m_memberIntField = 0;
m_memberIntField = 0;
m_memberStringField = "";
}
~DemoPdmObject()
{
}
~DemoPdmObject() {}
// Fields
caf::PdmProxyValueField<double> m_proxyDoubleField;
caf::PdmProxyValueField<int> m_proxyIntField;
caf::PdmProxyValueField<QString> m_proxyStringField;
caf::PdmDataValueField<double> m_memberDoubleField;
caf::PdmDataValueField<int> m_memberIntField;
caf::PdmDataValueField<QString> m_memberStringField;
caf::PdmDataValueField<double> m_memberDoubleField;
caf::PdmDataValueField<int> m_memberIntField;
caf::PdmDataValueField<QString> m_memberStringField;
// Internal class members accessed by proxy fields
double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; }
void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; }
int intMember() const { return m_intMember; }
void setIntMember(const int& val) { m_intMember = val; }
double doubleMember() const
{
std::cout << "doubleMember" << std::endl;
return m_doubleMember;
}
void setDoubleMember(const double& d)
{
m_doubleMember = d;
std::cout << "setDoubleMember" << std::endl;
}
QString stringMember() const { return m_stringMember; }
void setStringMember(const QString& val) { m_stringMember = val; }
int intMember() const
{
return m_intMember;
}
void setIntMember(const int& val)
{
m_intMember = val;
}
private:
QString stringMember() const
{
return m_stringMember;
}
void setStringMember(const QString& val)
{
m_stringMember = val;
}
private:
double m_doubleMember;
int m_intMember;
QString m_stringMember;
};
class InheritedDemoObj : public DemoPdmObject
{
public:
InheritedDemoObj()
{
this->addField(&m_texts, "Texts");
this->addField(&m_childArrayField, "DemoPdmObjectects");
this->addField(&m_ptrField, "m_ptrField");
this->addField(&m_singleFilePath, "m_singleFilePath");
this->addField(&m_multipleFilePath, "m_multipleFilePath");
}
caf::PdmDataValueField<QString > m_texts;
caf::PdmDataValueField<QString> m_texts;
caf::PdmChildArrayField<DemoPdmObject*> m_childArrayField;
caf::PdmPtrField<InheritedDemoObj*> m_ptrField;
caf::PdmDataValueField<caf::FilePath> m_singleFilePath;
caf::PdmDataValueField<std::vector<caf::FilePath>> m_multipleFilePath;
caf::PdmDataValueField<caf::FilePath> m_singleFilePath;
caf::PdmDataValueField<std::vector<caf::FilePath>> m_multipleFilePath;
};
TEST(BaseTest, Delete)
{
DemoPdmObject* s2 = new DemoPdmObject;
delete s2;
DemoPdmObject* s2 = new DemoPdmObject;
delete s2;
}
//--------------------------------------------------------------------------------------------------
/// TestPdmDataValueField
//--------------------------------------------------------------------------------------------------
TEST(BaseTest, TestPdmDataValueField)
{
DemoPdmObject* a = new DemoPdmObject;
DemoPdmObject* a = new DemoPdmObject;
ASSERT_DOUBLE_EQ(0.0, a->m_memberDoubleField.value());
a->m_memberDoubleField.setValue(1.2);
ASSERT_DOUBLE_EQ(1.2, a->m_memberDoubleField.value());
ASSERT_DOUBLE_EQ(0.0, a->m_memberDoubleField.value());
a->m_memberDoubleField.setValue(1.2);
ASSERT_DOUBLE_EQ(1.2, a->m_memberDoubleField.value());
ASSERT_EQ(0, a->m_memberIntField.value());
a->m_memberIntField.setValue(11);
ASSERT_EQ(11, a->m_memberIntField.value());
ASSERT_TRUE(a->m_memberStringField.value().isEmpty());
a->m_memberStringField.setValue("123");
ASSERT_TRUE(a->m_memberStringField.value() == "123");
ASSERT_EQ(0, a->m_memberIntField.value());
a->m_memberIntField.setValue(11);
ASSERT_EQ(11, a->m_memberIntField.value());
ASSERT_TRUE(a->m_memberStringField.value().isEmpty());
a->m_memberStringField.setValue("123");
ASSERT_TRUE(a->m_memberStringField.value() == "123");
}
//--------------------------------------------------------------------------------------------------
@ -153,66 +157,63 @@ TEST(BaseTest, TestPdmProxyValueField)
ASSERT_TRUE(a->m_proxyStringField.value() == "abba");
a->m_proxyStringField.setValue("123");
ASSERT_TRUE(a->m_proxyStringField.value() == "123");
}
//--------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------
TEST(BaseTest, TestPdmValueFieldInterface)
{
DemoPdmObject* a = new DemoPdmObject;
DemoPdmObject* a = new DemoPdmObject;
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_proxyDoubleField"));
QVariant newVal = 3.4;
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_proxyDoubleField"));
QVariant newVal = 3.4;
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_proxyIntField"));
QVariant newVal = 3;
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_proxyIntField"));
QVariant newVal = 3;
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_proxyStringField"));
QVariant newVal = "test";
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_proxyStringField"));
QVariant newVal = "test";
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_memberDoubleField"));
QVariant newVal = 3.4;
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_memberDoubleField"));
QVariant newVal = 3.4;
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_memberIntField"));
QVariant newVal = 3;
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_memberStringField"));
QVariant newVal = "test";
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_memberIntField"));
QVariant newVal = 3;
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
{
caf::PdmValueField* valField = dynamic_cast<caf::PdmValueField*>(a->findField("m_memberStringField"));
QVariant newVal = "test";
valField->setFromQVariant(newVal);
QVariant var = valField->toQVariant();
ASSERT_TRUE(newVal == var);
}
}
//--------------------------------------------------------------------------------------------------
/// Test of PdmDataValueField operations
//--------------------------------------------------------------------------------------------------
@ -221,19 +222,20 @@ TEST(BaseTest, NormalPdmField)
class A : public caf::PdmObjectHandle
{
public:
explicit A(const std::vector<double>& testValue) : field2(testValue), field3(field2)
explicit A(const std::vector<double>& testValue)
: field2(testValue)
, field3(field2)
{
this->addField(&field1, "field1");
this->addField(&field2, "field2");
this->addField(&field3, "field3");
}
caf::PdmDataValueField<std::vector<double> > field1;
caf::PdmDataValueField<std::vector<double> > field2;
caf::PdmDataValueField<std::vector<double> > field3;
caf::PdmDataValueField<std::vector<double>> field1;
caf::PdmDataValueField<std::vector<double>> field2;
caf::PdmDataValueField<std::vector<double>> field3;
};
std::vector<double> testValue;
testValue.push_back(1.1);
testValue.push_back(1.2);
@ -351,14 +353,12 @@ TEST(BaseTest, PdmChildArrayField)
EXPECT_TRUE(s3 == NULL);
}
TEST(BaseTest, PdmChildArrayParentField)
{
// Test of instanciating a class with forward declare of object used in PdmChildArrayField and PdmChildField
Parent* parentObj = new Parent;
delete parentObj;
}
#include "Child.h"
@ -371,7 +371,7 @@ TEST(BaseTest, PdmPointersFieldInsertVector)
Child* s2 = new Child;
Child* s3 = new Child;
std::vector<caf::PdmPointer<Child> > typedObjects;
std::vector<caf::PdmPointer<Child>> typedObjects;
typedObjects.push_back(s1);
typedObjects.push_back(s2);
typedObjects.push_back(s3);
@ -389,30 +389,29 @@ TEST(BaseTest, PdmPointersFieldInsertVector)
//--------------------------------------------------------------------------------------------------
TEST(BaseTest, PdmChildArrayFieldHandle)
{
// virtual size_t size() const = 0;
// virtual bool empty() const = 0;
// virtual void clear() = 0;
// virtual PdmObject* createAppendObject(int indexAfter) = 0;
// virtual void erase(size_t index) = 0;
// virtual void deleteAllChildObjects() = 0;
//
//
// virtual PdmObject* at(size_t index) = 0;
//
//
// bool hasSameFieldCountForAllObjects();
DemoPdmObject* s0 = new DemoPdmObject;
DemoPdmObject* s0 = new DemoPdmObject;
s0->m_memberDoubleField = 1000;
DemoPdmObject* s1 = new DemoPdmObject;
DemoPdmObject* s1 = new DemoPdmObject;
s1->m_memberDoubleField = 1000;
DemoPdmObject* s2 = new DemoPdmObject;
DemoPdmObject* s2 = new DemoPdmObject;
s2->m_memberDoubleField = 2000;
DemoPdmObject* s3 = new DemoPdmObject;
DemoPdmObject* s3 = new DemoPdmObject;
s3->m_memberDoubleField = 3000;
InheritedDemoObj* ihd1 = new InheritedDemoObj;
InheritedDemoObj* ihd1 = new InheritedDemoObj;
caf::PdmChildArrayFieldHandle* listField = &(ihd1->m_childArrayField);
EXPECT_EQ(0, listField->size());
@ -441,7 +440,6 @@ TEST(BaseTest, PdmChildArrayFieldHandle)
EXPECT_EQ(0, listField->size());
EXPECT_TRUE(listField->hasSameFieldCountForAllObjects());
EXPECT_TRUE(listField->empty());
}
//--------------------------------------------------------------------------------------------------
/// Test of PdmChildField
@ -453,8 +451,8 @@ TEST(BaseTest, PdmChildField)
{
public:
explicit A(Child* a)
: field2(a),
b(0)
: field2(a)
, b(0)
{
this->addField(&field2, "field2");
}
@ -465,7 +463,7 @@ TEST(BaseTest, PdmChildField)
}
caf::PdmChildField<Child*> field2;
int b;
int b;
};
{
@ -480,7 +478,7 @@ TEST(BaseTest, PdmChildField)
EXPECT_EQ(static_cast<Child*>(nullptr), a.field2);
}
{
A a(NULL);
A a(NULL);
Child* c2 = new Child;
// Assign
a.field2 = c2;
@ -490,7 +488,6 @@ TEST(BaseTest, PdmChildField)
EXPECT_EQ(c2, a.field2.value());
EXPECT_TRUE(c2 == a.field2);
std::vector<caf::PdmObjectHandle*> objects;
a.field2.childObjects(&objects);
EXPECT_EQ((size_t)1, objects.size());
@ -498,7 +495,6 @@ TEST(BaseTest, PdmChildField)
}
}
TEST(BaseTest, PdmPtrField)
{
InheritedDemoObj* ihd1 = new InheritedDemoObj;
@ -508,18 +504,18 @@ TEST(BaseTest, PdmPtrField)
EXPECT_EQ(static_cast<InheritedDemoObj*>(nullptr), ihd1->m_ptrField);
// Assignment
ihd1->m_ptrField = ihd1;
ihd1->m_ptrField = ihd1;
InheritedDemoObj* accessedIhd = ihd1->m_ptrField;
EXPECT_EQ(ihd1, accessedIhd);
ihd1->m_ptrField = caf::PdmPointer<InheritedDemoObj>(ihd2);
accessedIhd = ihd1->m_ptrField;
accessedIhd = ihd1->m_ptrField;
EXPECT_EQ(ihd2, accessedIhd);
// Access
accessedIhd = ihd1->m_ptrField; // Conversion
EXPECT_EQ(ihd2, accessedIhd);
accessedIhd = ihd1->m_ptrField.value();
accessedIhd = ihd1->m_ptrField.value();
EXPECT_EQ(ihd2, accessedIhd);
caf::PdmPointer<InheritedDemoObj> accessedPdmPtr;
@ -532,43 +528,52 @@ TEST(BaseTest, PdmPtrField)
// Operator ==
EXPECT_TRUE(ihd1->m_ptrField == ihd2);
EXPECT_FALSE(ihd1->m_ptrField == ihd1);
EXPECT_TRUE(ihd1->m_ptrField == caf::PdmPointer<InheritedDemoObj>(ihd2));
// Generic access
std::vector<caf::PdmObjectHandle*> objects;
ihd1->m_ptrField.ptrReferencedObjects(&objects);
EXPECT_EQ(1, objects.size());
EXPECT_EQ(ihd2, objects[0]);
{
std::vector<caf::PdmObjectHandle*> objects;
ihd1->m_ptrField.ptrReferencedObjects(&objects);
EXPECT_EQ(1, objects.size());
EXPECT_EQ(ihd2, objects[0]);
}
// Operator ->
ihd1->m_ptrField->m_texts = "Hei PtrField";
EXPECT_TRUE(ihd1->m_ptrField->m_texts == "Hei PtrField");
EXPECT_TRUE(ihd1->m_ptrField->m_texts == "Hei PtrField");
// Refrencing system
std::vector<caf::PdmFieldHandle*> ptrFields;
ihd2->referringPtrFields(ptrFields);
EXPECT_EQ(1, ptrFields.size());
EXPECT_EQ(&(ihd1->m_ptrField), ptrFields[0]);
// Referencing system
{
std::vector<caf::PdmFieldHandle*> ptrFields;
ihd2->referringPtrFields(ptrFields);
EXPECT_EQ(1, ptrFields.size());
EXPECT_EQ(&(ihd1->m_ptrField), ptrFields[0]);
}
objects.clear();
ihd2->objectsWithReferringPtrFields(objects);
EXPECT_EQ(1, objects.size());
EXPECT_EQ(ihd1, objects[0]);
{
std::vector<caf::PdmObjectHandle*> objects;
ihd2->objectsWithReferringPtrFields(objects);
EXPECT_EQ(1, objects.size());
EXPECT_EQ(ihd1, objects[0]);
}
{
std::vector<InheritedDemoObj*> reffingDemoObjects;
ihd2->objectsWithReferringPtrFieldsOfType(reffingDemoObjects);
EXPECT_EQ(1, reffingDemoObjects.size());
}
delete ihd1;
delete ihd2;
}
//--------------------------------------------------------------------------------------------------
/// Tests the features of PdmPointer
//--------------------------------------------------------------------------------------------------
TEST(BaseTest, PdmPointer)
{
InheritedDemoObj * d = new InheritedDemoObj;
InheritedDemoObj* d = new InheritedDemoObj;
{
caf::PdmPointer<InheritedDemoObj> p;
@ -594,12 +599,10 @@ TEST(BaseTest, PdmPointer)
caf::PdmPointer<DemoPdmObject> p3(new DemoPdmObject());
delete p3;
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
TEST(BaseTest, PdmFilePath)
{
@ -615,7 +618,7 @@ TEST(BaseTest, PdmFilePath)
}
//--------------------------------------------------------------------------------------------------
///
///
//--------------------------------------------------------------------------------------------------
TEST(BaseTest, MultiplePdmFilePath)
{
@ -625,7 +628,7 @@ TEST(BaseTest, MultiplePdmFilePath)
d->m_multipleFilePath.v().push_back(newVal);
d->m_multipleFilePath.v().push_back(newVal);
QVariant var = d->m_multipleFilePath.toQVariant();
QVariant var = d->m_multipleFilePath.toQVariant();
QStringList str = var.toStringList();
EXPECT_EQ(2, str.size());

View File

@ -53,6 +53,9 @@ public:
void referringPtrFields(std::vector<PdmFieldHandle*>& fieldsReferringToMe) const;
/// Convenience method to get the objects pointing to this field
void objectsWithReferringPtrFields(std::vector<PdmObjectHandle*>& objects) const;
/// Convenience method to get the objects of specified type pointing to this field
template <typename T>
void objectsWithReferringPtrFieldsOfType(std::vector<T*>& objectsOfType) const;
// Detach object from all referring fields
void prepareForDelete();
@ -202,5 +205,24 @@ void PdmObjectHandle::descendantsIncludingThisOfType(std::vector<T*>& descendant
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template <typename T>
void PdmObjectHandle::objectsWithReferringPtrFieldsOfType(std::vector<T*>& objectsOfType) const
{
std::vector<PdmObjectHandle*> objectsReferencingThis;
this->objectsWithReferringPtrFields(objectsReferencingThis);
for (auto object : objectsReferencingThis)
{
if (dynamic_cast<T*>(object))
{
objectsOfType.push_back(dynamic_cast<T*>(object));
}
}
}
} // End of namespace caf