Revert link integrity checks in properties

The DAG test is not needed anymore as the relevant functions are non-DAG save now, and the other check will be moved to the recompute as it is not efficient or save to do it in the links itself.
This commit is contained in:
Stefan Tröger
2017-06-03 15:27:24 +02:00
committed by wmayer
parent 4ecd831bfd
commit fa4d67735f
2 changed files with 8 additions and 125 deletions

View File

@@ -39,101 +39,11 @@
#include "Document.h"
#include "PropertyLinks.h"
#include "GeoFeatureGroupExtension.h"
#include "OriginFeature.h"
using namespace App;
using namespace Base;
using namespace std;
void ensureDAG(PropertyContainer* container, App::DocumentObject* object) {
if(!container || !object)
return;
//document containers and other non-object things don't need to be handled
if(!container->isDerivedFrom(App::DocumentObject::getClassTypeId()))
return;
//undo and redo do not need to be handled as they can only go to already checked stated (the link
//state during those actions can get messed up, we really don't want to check for that)
if(object->getDocument()->performsTransactionOperation())
return;
auto cont = static_cast<App::DocumentObject*>(container);
//on restore we don't need to do anything
if(cont->isRestoring() || object->isRestoring())
return;
//recursively traverse the object links and see if we reach the container, which would be a
//cyclic graph --> not allowed
for(auto obj : object->getOutList()) {
if(obj == cont)
throw Base::Exception("This link would create a cyclic dependency, hence it is rejected");
ensureDAG(container, obj);
}
};
//helper functions to ensure correct geofeaturegroups. Each object is only allowed to be in a
//single geofeatueregroup, and links are not allowed to cross GeoFeatureGroup borders
void ensureCorrectGroups(PropertyContainer* container, App::DocumentObject* object) {
//on object creation the container may be null, and linked objects may be null anyhow
if(!container || !object)
return;
//document containers and other non-object things don't need to be handled
if(!container->isDerivedFrom(App::DocumentObject::getClassTypeId()))
return;
//links to origin feature can go over CS borders, as they are the same everywere anyway. This is
//a workaround to allow moving of objects between GeoFeatureGroups that link to origin features.
//During movement there is always a link in to the wron CS and the error would occure. If we
//surpress the error at least the origin links can be fixed afterwards
//TODO: Find a more elegant solution
if(object->isDerivedFrom(App::OriginFeature::getClassTypeId()))
return;
//undo and redo do not need to be handled as they can only go to already checked stated (the link
//state during those actions can get messed up, we really don't want to check for that)
if(object->getDocument()->performsTransactionOperation())
return;
auto cont = static_cast<App::DocumentObject*>(container);
//on restore we don't need to do anything
if(cont->isRestoring() || object->isRestoring())
return;
std::vector< DocumentObject* > objs;
GeoFeatureGroupExtension::getCSRelevantLinks(object, objs);
objs.push_back(object);
for(auto obj : objs) {
App::DocumentObject* grp = GeoFeatureGroupExtension::getGroupOfObject(obj);
//if the container is a GeoFeatureGroup there are two allowed possibilites:
//1. the objet is in no group, hence in a single one after adding
//2. the object is already in the container group
if(cont->hasExtension(App::GeoFeatureGroupExtension::getExtensionClassTypeId())) {
if(!grp || (grp == cont))
return;
}
//if the container is a normal object there is only a single allowed possibility:
//1. The object has the exact same GeoFeatureGrou as the container (null included)
else if(grp == GeoFeatureGroupExtension::getGroupOfObject(cont)) {
return;
}
//if we arrive here the container and the object don't have compatible GeoFeatureGroups
throw Base::Exception("Links are only allowed within a GeoFeatureGroup");
}
};
//**************************************************************************
//**************************************************************************
// PropertyLink
@@ -162,8 +72,6 @@ PropertyLink::~PropertyLink()
void PropertyLink::setValue(App::DocumentObject * lValue)
{
ensureDAG(getContainer(), lValue);
ensureCorrectGroups(getContainer(), lValue);
aboutToSetValue();
#ifndef USE_OLD_DAG
// maintain the back link in the DocumentObject class
@@ -297,9 +205,6 @@ int PropertyLinkList::getSize(void) const
void PropertyLinkList::setValue(DocumentObject* lValue)
{
ensureDAG(getContainer(), lValue);
ensureCorrectGroups(getContainer(), lValue);
#ifndef USE_OLD_DAG
//maintain the back link in the DocumentObject class
for(auto *obj : _lValueList)
@@ -323,11 +228,6 @@ void PropertyLinkList::setValue(DocumentObject* lValue)
void PropertyLinkList::setValues(const std::vector<DocumentObject*>& lValue)
{
for(auto obj : lValue) {
ensureDAG(getContainer(), obj);
ensureCorrectGroups(getContainer(), obj);
}
aboutToSetValue();
#ifndef USE_OLD_DAG
//maintain the back link in the DocumentObject class
@@ -480,9 +380,6 @@ PropertyLinkSub::~PropertyLinkSub()
void PropertyLinkSub::setValue(App::DocumentObject * lValue, const std::vector<std::string> &SubList)
{
ensureDAG(getContainer(), lValue);
ensureCorrectGroups(getContainer(), lValue);
aboutToSetValue();
#ifndef USE_OLD_DAG
if (_pcLinkSub)
@@ -679,9 +576,6 @@ int PropertyLinkSubList::getSize(void) const
void PropertyLinkSubList::setValue(DocumentObject* lValue,const char* SubName)
{
ensureDAG(getContainer(), lValue);
ensureCorrectGroups(getContainer(), lValue);
#ifndef USE_OLD_DAG
//maintain backlinks
for(auto *obj : _lValueList)
@@ -711,11 +605,6 @@ void PropertyLinkSubList::setValues(const std::vector<DocumentObject*>& lValue,c
if (lValue.size() != lSubNames.size())
throw Base::ValueError("PropertyLinkSubList::setValues: size of subelements list != size of objects list");
for(auto obj : lValue) {
ensureDAG(getContainer(), obj);
ensureCorrectGroups(getContainer(), obj);
}
#ifndef USE_OLD_DAG
//maintain backlinks. _lValueList can contain items multiple times, but we trust the document
//object to ensure that this works
@@ -742,11 +631,6 @@ void PropertyLinkSubList::setValues(const std::vector<DocumentObject*>& lValue,c
if (lValue.size() != lSubNames.size())
throw Base::ValueError("PropertyLinkSubList::setValues: size of subelements list != size of objects list");
for(auto obj : lValue) {
ensureDAG(getContainer(), obj);
ensureCorrectGroups(getContainer(), obj);
}
#ifndef USE_OLD_DAG
//maintain backlinks. _lValueList can contain items multiple times, but we trust the document
//object to ensure that this works
@@ -767,9 +651,6 @@ void PropertyLinkSubList::setValues(const std::vector<DocumentObject*>& lValue,c
void PropertyLinkSubList::setValue(DocumentObject* lValue, const std::vector<string> &SubList)
{
ensureDAG(getContainer(), lValue);
ensureCorrectGroups(getContainer(), lValue);
#ifndef USE_OLD_DAG
//maintain backlinks. _lValueList can contain items multiple times, but we trust the document
//object to ensure that this works

View File

@@ -870,12 +870,14 @@ class UndoRedoCases(unittest.TestCase):
#to test: try add obj to second group by .Group = []
grp = prt1.Group
grp.append(grp2)
try:
prt1.Group=grp
except:
pass
else:
self.fail("No exception at cross geofeaturegroup links")
#to test: check if cross CS link works
#try:
# prt1.Group=grp
#except:
# pass
#else:
# self.fail("No exception at cross geofeaturegroup links")
prt2.addObject(grp1)
grp = grp1.Group