diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldHandle.h index a7a83e52db..7ef8a7c244 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmFieldHandle.h @@ -34,7 +34,6 @@ public: // Ptr referenced objects bool hasPtrReferencedObjects(); virtual void ptrReferencedObjects(std::vector*) { } - virtual void resolveReferences() { } // Capabilities void addCapability(PdmFieldCapability* capability, bool takeOwnership) { m_capabilities.push_back(std::make_pair(capability, takeOwnership)); } diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.h index 8adb40ffab..f483d069cc 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.h @@ -68,7 +68,7 @@ public: // Ptr referenced objects virtual void ptrReferencedObjects(std::vector* objectsToFill); - virtual void resolveReferences(); + private: PDM_DISABLE_COPY_AND_ASSIGN(PdmPtrField); diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.inl index d6e30270a7..cf3dbf9d23 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.inl +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmCore/cafPdmPtrField.inl @@ -100,19 +100,5 @@ void PdmPtrField::ptrReferencedObjects(std::vector* } } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -template -void PdmPtrField::resolveReferences() -{ - if (m_isResolved) return; - if (m_referenceString.isEmpty()) return; - - PdmObjectHandle* objHandle = PdmReferenceHelper::objectFromFieldReference(this, m_referenceString); - this->setRawPtr(objHandle); - m_isResolved = true; -} - } // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp index 0e5a83f20b..9f95184ef1 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.cpp @@ -91,8 +91,8 @@ void PdmDocument::readFile(QIODevice* xmlFile) // Ask all objects to initialize and set up internal datastructure and pointers // after everything is read from file - PdmDocument::resolveReferencesTraversal(this); - PdmDocument::initAfterReadTraversal(this); + resolveReferencesRecursively(); + initAfterReadRecursively(); } //-------------------------------------------------------------------------------------------------- @@ -113,7 +113,7 @@ void PdmDocument::writeFile() void PdmDocument::writeFile(QIODevice* xmlFile) { // Ask all objects to make them ready to write themselves to file - PdmDocument::setupBeforeSaveTraversal(this); + setupBeforeSaveRecursively(); QXmlStreamWriter xmlStream(xmlFile); xmlStream.setAutoFormatting(true); @@ -129,123 +129,5 @@ void PdmDocument::writeFile(QIODevice* xmlFile) } -void PdmDocument::setupBeforeSaveTraversal(PdmObjectHandle * object) -{ - if (object == NULL) return; - - std::vector fields; - object->fields(fields); - - std::vector children; - size_t fIdx; - for (fIdx = 0; fIdx < fields.size(); ++fIdx) - { - if (fields[fIdx]) fields[fIdx]->childObjects(&children); - } - - size_t cIdx; - for (cIdx = 0; cIdx < children.size(); ++cIdx) - { - PdmDocument::setupBeforeSaveTraversal(children[cIdx]); - } - - PdmXmlObjectHandle* xmlObject = xmlObj(object); - if (xmlObject) - { - xmlObject->setupBeforeSave(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmDocument::initAfterReadTraversal(PdmObjectHandle* object) -{ - if (object == NULL) return; - - std::vector fields; - object->fields(fields); - - std::vector children; - size_t fIdx; - for (fIdx = 0; fIdx < fields.size(); ++fIdx) - { - if (fields[fIdx]) fields[fIdx]->childObjects(&children); - } - - size_t cIdx; - for (cIdx = 0; cIdx < children.size(); ++cIdx) - { - PdmDocument::initAfterReadTraversal(children[cIdx]); - } - - PdmXmlObjectHandle* xmlObject = xmlObj(object); - if (xmlObject) - { - xmlObject->initAfterRead(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmDocument::updateUiIconStateRecursively(PdmObjectHandle* object) -{ - if (object == NULL) return; - - std::vector fields; - object->fields(fields); - - std::vector children; - size_t fIdx; - for (fIdx = 0; fIdx < fields.size(); ++fIdx) - { - if (fields[fIdx]) fields[fIdx]->childObjects(&children); - } - - size_t cIdx; - for (cIdx = 0; cIdx < children.size(); ++cIdx) - { - PdmDocument::updateUiIconStateRecursively(children[cIdx]); - } - - PdmUiObjectHandle* uiObjectHandle = uiObj(object); - if (uiObjectHandle) - { - uiObjectHandle->updateUiIconFromToggleField(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void PdmDocument::resolveReferencesTraversal(PdmObjectHandle* object) -{ - if (object == NULL) return; - - std::vector fields; - object->fields(fields); - - std::vector children; - size_t fIdx; - for (fIdx = 0; fIdx < fields.size(); ++fIdx) - { - PdmFieldHandle* field = fields[fIdx]; - if (field) - { - field->childObjects(&children); - - field->resolveReferences(); - } - } - - size_t cIdx; - for (cIdx = 0; cIdx < children.size(); ++cIdx) - { - PdmDocument::resolveReferencesTraversal(children[cIdx]); - } -} - - } //End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h index 3b3bd8b10a..17dafdab4b 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmDocument.h @@ -62,11 +62,6 @@ class PdmDocument: public PdmObject void writeFile(QIODevice* device); static void updateUiIconStateRecursively(PdmObjectHandle* root); - static void initAfterReadTraversal(PdmObjectHandle* root); - static void resolveReferencesTraversal(PdmObjectHandle* root); - -private: - static void setupBeforeSaveTraversal(PdmObjectHandle * root); }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h index 867b5768fe..f14cd1914b 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.h @@ -28,14 +28,26 @@ class PdmFieldXmlCap< PdmPtrField > : public PdmXmlFieldHandle { typedef PdmPtrField FieldType; public: - PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) { m_field = field; m_childClassKeyword = DataType::classKeywordStatic(); } + PdmFieldXmlCap(FieldType* field, bool giveOwnership) : PdmXmlFieldHandle(field, giveOwnership) + { + m_field = field; + m_childClassKeyword = DataType::classKeywordStatic(); + m_isResolved = false; + m_referenceString = ""; + } // Xml Serializing public: virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory); virtual void writeFieldData(QXmlStreamWriter& xmlStream); + virtual void resolveReferences(); + private: FieldType* m_field; + + // Resolving + QString m_referenceString; + bool m_isResolved; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl index 772c204023..5842df0414 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafInternalPdmXmlFieldCapability.inl @@ -67,8 +67,9 @@ template // // and then we need a traversal of the object hierarchy to resolve all references before initAfterRead. - m_field->m_isResolved = false; - m_field->m_referenceString = dataString; + m_isResolved = false; + m_referenceString = dataString; + m_field->setRawPtr(NULL); } //-------------------------------------------------------------------------------------------------- @@ -87,6 +88,22 @@ template xmlStream.writeCharacters(dataString); } + + //-------------------------------------------------------------------------------------------------- + /// + //-------------------------------------------------------------------------------------------------- + template < typename DataType> + void caf::PdmFieldXmlCap< PdmPtrField >::resolveReferences() + { + if (m_isResolved) return; + if (m_referenceString.isEmpty()) return; + + PdmObjectHandle* objHandle = PdmReferenceHelper::objectFromFieldReference(this->fieldHandle(), m_referenceString); + m_field->setRawPtr(objHandle); + m_isResolved = true; + } + + //================================================================================================== /// XML Implementation for PdmChildField<> //================================================================================================== diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h index 9aa157f836..bf426be4a1 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlFieldHandle.h @@ -26,29 +26,28 @@ public: virtual ~PdmXmlFieldHandle() { } PdmFieldHandle* fieldHandle() { return m_owner; } -private: - PdmFieldHandle* m_owner; - /// Xml Serialization -public: - virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) = 0; - virtual void writeFieldData(QXmlStreamWriter& xmlStream) = 0; + bool isIOReadable() { return m_isIOReadable; } + bool isIOWritable() { return m_isIOWritable; } + void setIOWritable(bool isWritable) { m_isIOWritable = isWritable; } + void setIOReadable(bool isReadable) { m_isIOReadable = isReadable; } - bool isIOReadable() { return m_isIOReadable; } - bool isIOWritable() { return m_isIOWritable; } - void setIOWritable(bool isWritable) { m_isIOWritable = isWritable; } - void setIOReadable(bool isReadable) { m_isIOReadable = isReadable; } + QString childClassKeyword(); + + virtual void readFieldData(QXmlStreamReader& xmlStream, PdmObjectFactory* objectFactory) = 0; + virtual void writeFieldData(QXmlStreamWriter& xmlStream) = 0; + + virtual void resolveReferences() { }; - QString childClassKeyword(); protected: - bool assertValid() const; - QString m_childClassKeyword; ///< Must be set in constructor of derived XmlFieldHandle + bool assertValid() const; + QString m_childClassKeyword; ///< Must be set in constructor of derived XmlFieldHandle private: - bool m_isIOReadable; - bool m_isIOWritable; + bool m_isIOReadable; + bool m_isIOWritable; - + PdmFieldHandle* m_owner; }; } // End of namespace caf diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.cpp index 893f2fe807..7a9fb59c64 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.cpp @@ -228,6 +228,96 @@ bool PdmXmlObjectHandle::isValidXmlElementName(const QString& name) return true; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmXmlObjectHandle::initAfterReadRecursively(PdmObjectHandle* object) +{ + if (object == NULL) return; + + std::vector fields; + object->fields(fields); + + std::vector children; + size_t fIdx; + for (fIdx = 0; fIdx < fields.size(); ++fIdx) + { + if (fields[fIdx]) fields[fIdx]->childObjects(&children); + } + + size_t cIdx; + for (cIdx = 0; cIdx < children.size(); ++cIdx) + { + initAfterReadRecursively(children[cIdx]); + } + + PdmXmlObjectHandle* xmlObject = xmlObj(object); + if (xmlObject) + { + xmlObject->initAfterRead(); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmXmlObjectHandle::resolveReferencesRecursively(PdmObjectHandle* object) +{ + if (object == NULL) return; + + std::vector fields; + object->fields(fields); + + std::vector children; + size_t fIdx; + for (fIdx = 0; fIdx < fields.size(); ++fIdx) + { + PdmFieldHandle* field = fields[fIdx]; + if (field) + { + field->childObjects(&children); + + field->xmlCapability()->resolveReferences(); + } + } + + size_t cIdx; + for (cIdx = 0; cIdx < children.size(); ++cIdx) + { + resolveReferencesRecursively(children[cIdx]); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void PdmXmlObjectHandle::setupBeforeSaveRecursively(PdmObjectHandle* object) +{ + if (object == NULL) return; + + std::vector fields; + object->fields(fields); + + std::vector children; + size_t fIdx; + for (fIdx = 0; fIdx < fields.size(); ++fIdx) + { + if (fields[fIdx]) fields[fIdx]->childObjects(&children); + } + + size_t cIdx; + for (cIdx = 0; cIdx < children.size(); ++cIdx) + { + setupBeforeSaveRecursively(children[cIdx]); + } + + PdmXmlObjectHandle* xmlObject = xmlObj(object); + if (xmlObject) + { + xmlObject->setupBeforeSave(); + } +} + //-------------------------------------------------------------------------------------------------- /// Implementation of xmlCapability() defined in cafPdmObjectHandle.h diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.h b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.h index 32cb47d090..4bf992e5d6 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.h +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXmlObjectHandle.h @@ -45,6 +45,10 @@ public: /// Check if a string is a valid Xml element name static bool isValidXmlElementName(const QString& name); + void initAfterReadRecursively() { initAfterReadRecursively(this->m_owner); }; + void setupBeforeSaveRecursively() { setupBeforeSaveRecursively(this->m_owner); }; + void resolveReferencesRecursively() { resolveReferencesRecursively(this->m_owner); }; + protected: // Virtual /// Method gets called from PdmDocument after all objects are read. /// Re-implement to set up internal pointers etc. in your data structure @@ -57,10 +61,13 @@ protected: // Virtual // if user uses them on wrong type of objects bool isInheritedFromPdmXmlSerializable() { return true; } +private: + void initAfterReadRecursively(PdmObjectHandle* object); + void setupBeforeSaveRecursively(PdmObjectHandle * object); + void resolveReferencesRecursively(PdmObjectHandle* object); + private: friend class PdmObjectHandle ; // Only temporary for void PdmObject::addFieldNoDefault( ) accessing findField - friend class PdmDocument; // To access setupBeforeSave() - friend class PdmObjectGroup; // To access initAfterRead PdmObjectHandle* m_owner; }; diff --git a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmAdvancedTemplateTest.cpp b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmAdvancedTemplateTest.cpp index c1bee1603f..7c8000f8c9 100644 --- a/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmAdvancedTemplateTest.cpp +++ b/Fwk/AppFwk/cafProjectDataModel/cafPdmXml/cafPdmXml_UnitTests/cafPdmAdvancedTemplateTest.cpp @@ -194,7 +194,7 @@ TEST(AdvancedObjectTest, FieldWrite) sibling->m_demoObjs.push_back(a); a->readObjectFromXmlString(serializedString, caf::PdmDefaultObjectFactory::instance()); - //caf::PdmDocument::resolveReferencesTraversal(a); + a->xmlCapability()->resolveReferencesRecursively(); ASSERT_TRUE(a->m_pointerToItem() == container->m_items[1]); } diff --git a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/cafPdmBasicTest.cpp b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/cafPdmBasicTest.cpp index 6d795199e0..e28b2f6b5b 100644 --- a/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/cafPdmBasicTest.cpp +++ b/Fwk/AppFwk/cafTests/cafProjectDataModel_UnitTests/cafPdmBasicTest.cpp @@ -44,6 +44,7 @@ #include "cafPdmDocument.h" #include "cafPdmField.h" #include "cafPdmObject.h" +#include "cafPdmObjectGroup.h" #include "cafPdmPointer.h" #include "cafPdmProxyValueField.h" #include "cafPdmReferenceHelper.h" @@ -51,7 +52,6 @@ #include #include -#include "cafPdmObjectGroup.h" /// Demo objects to show the usage of the Pdm system @@ -102,7 +102,7 @@ public: caf::PdmField m_dir; caf::PdmField m_up; caf::PdmField > m_numbers; - caf::PdmProxyValueField m_proxyDouble; + caf::PdmProxyValueField m_proxyDouble; void setDoubleMember(const double& d) { m_doubleMember = d; std::cout << "setDoubleMember" << std::endl; } double doubleMember() const { std::cout << "doubleMember" << std::endl; return m_doubleMember; } @@ -176,7 +176,7 @@ public: caf::PdmField > m_texts; caf::PdmField< caf::AppEnum > m_testEnumField; - caf::PdmChildArrayField m_simpleObjectsField; + caf::PdmChildArrayField m_simpleObjectsField; }; CAF_PDM_SOURCE_INIT(InheritedDemoObj, "InheritedDemoObj"); @@ -644,21 +644,27 @@ TEST(BaseTest, ReadWrite) f3.close(); // Read the document containing errors -/* - caf::PdmDocument xmlErrorDoc; + + MyPdmDocument xmlErrorDoc; xmlErrorDoc.fileName = "PdmTestFilWithError.xml"; xmlErrorDoc.readFile(); + caf::PdmObjectGroup pog; + for (size_t i = 0; i < xmlErrorDoc.objects.size(); i++) + { + pog.addObject(xmlErrorDoc.objects[i]); + } + // Check the pointersfield std::vector > ihDObjs; - xmlErrorDoc.objectsByType(&ihDObjs); + pog.objectsByType(&ihDObjs); EXPECT_EQ(size_t(2), ihDObjs.size() ); ASSERT_EQ(size_t(3), ihDObjs[0]->m_simpleObjectsField.size()); // check single pointer field std::vector > demoObjs; - xmlErrorDoc.objectsByType(&demoObjs); + pog.objectsByType(&demoObjs); EXPECT_EQ(size_t(4), demoObjs.size() ); EXPECT_TRUE(demoObjs[0]->m_simpleObjPtrField == NULL ); @@ -666,11 +672,9 @@ TEST(BaseTest, ReadWrite) // check single pointer field std::vector > simpleObjs; - xmlErrorDoc.objectsByType(&simpleObjs); + pog.objectsByType(&simpleObjs); EXPECT_EQ(size_t(1), simpleObjs.size() ); EXPECT_EQ(size_t(0), simpleObjs[0]->m_numbers().size()); -*/ - } }