From 00e7c0f2cb2cfb51acbbf75a5117050f79df062d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Sat, 16 Sep 2017 12:11:46 +0200 Subject: [PATCH] Maintain backlinks on dynamic property removal. fixes #0003189 --- src/App/PropertyLinks.cpp | 56 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 53 insertions(+), 3 deletions(-) diff --git a/src/App/PropertyLinks.cpp b/src/App/PropertyLinks.cpp index 2c81458ea7..137d293f89 100644 --- a/src/App/PropertyLinks.cpp +++ b/src/App/PropertyLinks.cpp @@ -67,7 +67,21 @@ PropertyLink::PropertyLink() PropertyLink::~PropertyLink() { - + + //in case this property gets dynamically removed +#ifndef USE_OLD_DAG + // maintain the back link in the DocumentObject class if it is from a document object + if (_pcLink && getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + if (_pcLink) + _pcLink->_removeBackLink(parent); + } + } +#endif + } //************************************************************************** @@ -202,6 +216,19 @@ PropertyLinkList::PropertyLinkList() PropertyLinkList::~PropertyLinkList() { + //in case this property gety dynamically removed +#ifndef USE_OLD_DAG + //maintain the back link in the DocumentObject class + if (!_lValueList.empty() && getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + for(auto *obj : _lValueList) + obj->_removeBackLink(parent); + } + } +#endif } @@ -408,7 +435,18 @@ PropertyLinkSub::PropertyLinkSub() PropertyLinkSub::~PropertyLinkSub() { - + //in case this property is dynamically removed +#ifndef USE_OLD_DAG + if (_pcLinkSub && getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + if (_pcLinkSub) + _pcLinkSub->_removeBackLink(parent); + } + } +#endif } //************************************************************************** @@ -605,7 +643,19 @@ PropertyLinkSubList::PropertyLinkSubList() PropertyLinkSubList::~PropertyLinkSubList() { - + //in case this property is dynamically removed +#ifndef USE_OLD_DAG + //maintain backlinks + if (!_lValueList.empty() && getContainer() && getContainer()->isDerivedFrom(App::DocumentObject::getClassTypeId())) { + App::DocumentObject* parent = static_cast(getContainer()); + // before accessing internals make sure the object is not about to be destroyed + // as otherwise the backlink contains dangling pointers + if (!parent->testStatus(ObjectStatus::Destroy)) { + for(auto *obj : _lValueList) + obj->_removeBackLink(parent); + } + } +#endif } void PropertyLinkSubList::setSize(int newSize)