Fix _inList tracking in case of link removal

This commit is contained in:
Stefan Tröger
2017-06-05 11:40:52 +02:00
committed by wmayer
parent 45d1acf9f3
commit 51005bb81e
2 changed files with 19 additions and 6 deletions

View File

@@ -2198,8 +2198,14 @@ std::vector<App::DocumentObject*> Document::topologicalSort() const
ret.reserve(d->objectArray.size());
map < App::DocumentObject*,int > countMap;
for (auto objectIt : d->objectMap)
countMap[objectIt.second] = objectIt.second->getInList().size();
for (auto objectIt : d->objectMap) {
//we need inlist with unique entries
auto in = objectIt.second->getInList();
std::sort(in.begin(), in.end());
in.erase(std::unique(in.begin(), in.end()), in.end());
countMap[objectIt.second] = in.size();
}
auto rootObjeIt = find_if(countMap.begin(), countMap.end(), [](pair < App::DocumentObject*, int > count)->bool {
return count.second == 0;
@@ -2213,7 +2219,7 @@ std::vector<App::DocumentObject*> Document::topologicalSort() const
while (rootObjeIt != countMap.end()){
rootObjeIt->second = rootObjeIt->second - 1;
//we need outlist with unique entries, as inlist also has unique entries
//we need outlist with unique entries
auto out = rootObjeIt->first->getOutList();
std::sort(out.begin(), out.end());
out.erase(std::unique(out.begin(), out.end()), out.end());

View File

@@ -578,7 +578,11 @@ void DocumentObject::unsetupObject()
void App::DocumentObject::_removeBackLink(DocumentObject* rmvObj)
{
#ifndef USE_OLD_DAG
_inList.erase(std::remove(_inList.begin(), _inList.end(), rmvObj), _inList.end());
//do not use erase-remove idom, as this erases ALL entries that match. we only want to remove a
//single one.
auto it = std::find(_inList.begin(), _inList.end(), rmvObj);
if(it != _inList.end())
_inList.erase(it);
#else
(void)rmvObj;
#endif
@@ -587,8 +591,11 @@ void App::DocumentObject::_removeBackLink(DocumentObject* rmvObj)
void App::DocumentObject::_addBackLink(DocumentObject* newObj)
{
#ifndef USE_OLD_DAG
if ( std::find(_inList.begin(), _inList.end(), newObj) == _inList.end() )
_inList.push_back(newObj);
//we need to add all links, even if they are available multiple times. The reason for this is the
//removal: If a link loses this object it removes the backlink. If we would have added it only once
//this removal would clear the object from the inlist, even though there may be other link properties
//from this object that link to us.
_inList.push_back(newObj);
#else
(void)newObj;
#endif //USE_OLD_DAG