From 7a45d74bc7319d3c9d996b5705b760b8d4dd5285 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 18 Oct 2019 15:38:58 +0200 Subject: [PATCH] + implement a correct cleaning of a parameter group without creating ghost instances of ParameterGrp --- src/Base/Parameter.cpp | 48 ++++++++++++++++++++++++++++++------------ src/Base/Parameter.h | 1 + 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/src/Base/Parameter.cpp b/src/Base/Parameter.cpp index 9aeacb75af..4142a3fac5 100644 --- a/src/Base/Parameter.cpp +++ b/src/Base/Parameter.cpp @@ -891,27 +891,37 @@ void ParameterGrp::Clear(void) std::vector vecNodes; // checking on references - std::map >::iterator It1; - for (It1 = _GroupMap.begin();It1!=_GroupMap.end();++It1) { - if (It1->second.getRefCount() > 1) - Console().Warning("ParameterGrp::Clear(): Group clear with active references"); + std::vector removeGrp; + for (auto it = _GroupMap.begin();it!=_GroupMap.end();++it) { + // If a group is referenced by some observer then do not remove it + // but clear it + if (!it->second->ShouldRemove()) { + it->second->Clear(); + } + else { + removeGrp.push_back(it->first); + } } // remove group handles - _GroupMap.clear(); + for (auto it : removeGrp) { + auto pos = _GroupMap.find(it); + vecNodes.push_back(pos->second->_pGroupNode); + _GroupMap.erase(pos->first); + } - // searching all nodes - for (DOMNode *clChild = _pGroupNode->getFirstChild(); clChild != 0; clChild = clChild->getNextSibling()) { - vecNodes.push_back(clChild); + // searching all non-group nodes + for (DOMNode *child = _pGroupNode->getFirstChild(); child != 0; child = child->getNextSibling()) { + if (XMLString::compareString(child->getNodeName(), XStr("FCParamGroup").unicodeForm()) != 0) + vecNodes.push_back(child); } // deleting the nodes - DOMNode* pcTemp; - for (std::vector::iterator It=vecNodes.begin();It!=vecNodes.end();++It) { - pcTemp = _pGroupNode->removeChild(*It); - //delete pcTemp; - pcTemp->release(); + for (auto it = vecNodes.begin(); it != vecNodes.end(); ++it) { + DOMNode *child = _pGroupNode->removeChild(*it); + child->release(); } + // trigger observer Notify(""); } @@ -919,6 +929,18 @@ void ParameterGrp::Clear(void) //************************************************************************** // Access methods +bool ParameterGrp::ShouldRemove() const +{ + if (this->getRefCount() > 1) + return false; + for (auto it : _GroupMap) { + bool ok = it.second->ShouldRemove(); + if (!ok) + return false; + } + return true; +} + XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *ParameterGrp::FindElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *Start, const char* Type, const char* Name) const { if (XMLString::compareString(Start->getNodeName(), XStr("FCParamGroup").unicodeForm()) != 0 && diff --git a/src/Base/Parameter.h b/src/Base/Parameter.h index 474d78b414..90c8c71830 100644 --- a/src/Base/Parameter.h +++ b/src/Base/Parameter.h @@ -236,6 +236,7 @@ protected: ~ParameterGrp(); /// helper function for GetGroup Base::Reference _GetGroup(const char* Name); + bool ShouldRemove() const; XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *FindNextElement(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode *Prev, const char* Type) const;