diff --git a/src/App/Document.cpp b/src/App/Document.cpp index 6a08dcdc6..0e026c0bf 100644 --- a/src/App/Document.cpp +++ b/src/App/Document.cpp @@ -1662,8 +1662,11 @@ Document::getDependencyList(const std::vector& objs) const // this sort gives the execute boost::topological_sort(DepList, std::front_inserter(make_order)); } - catch (const std::exception&) { - return std::vector(); + catch (const std::exception& e) { + std::stringstream ss; + ss << "Gathering all dependencies failed, probably due to circular dependencies. Error: "; + ss << e.what(); + throw Base::Exception(ss.str().c_str()); } std::set out; diff --git a/src/App/DocumentObject.cpp b/src/App/DocumentObject.cpp index a99b60873..0bc64d993 100644 --- a/src/App/DocumentObject.cpp +++ b/src/App/DocumentObject.cpp @@ -172,6 +172,41 @@ DocumentObjectGroup* DocumentObject::getGroup() const return DocumentObjectGroup::getGroupOfObject(this); } +bool DocumentObject::testIfLinkDAGCompatible(DocumentObject *linkTo) const +{ + std::vector linkTo_in_vector; + linkTo_in_vector.reserve(1); + linkTo_in_vector.push_back(linkTo); + return this->testIfLinkDAGCompatible(linkTo_in_vector); +} + +bool DocumentObject::testIfLinkDAGCompatible(const std::vector &linksTo) const +{ + Document* doc = this->getDocument(); + if (!doc) + throw Base::Exception("DocumentObject::testIfLinkIsDAG: object is not in any document."); + std::vector deplist = doc->getDependencyList(linksTo); + if( std::find(deplist.begin(),deplist.end(),this) != deplist.end() ) + //found this in dependency list + return false; + else + return true; +} + +bool DocumentObject::testIfLinkDAGCompatible(PropertyLinkSubList &linksTo) const +{ + const std::vector &linksTo_in_vector = linksTo.getValues(); + return this->testIfLinkDAGCompatible(linksTo_in_vector); +} + +bool DocumentObject::testIfLinkDAGCompatible(PropertyLinkSub &linkTo) const +{ + std::vector linkTo_in_vector; + linkTo_in_vector.reserve(1); + linkTo_in_vector.push_back(linkTo.getValue()); + return this->testIfLinkDAGCompatible(linkTo_in_vector); +} + void DocumentObject::onLostLinkToObject(DocumentObject*) { diff --git a/src/App/DocumentObject.h b/src/App/DocumentObject.h index e4ef9ebf7..437b0dafd 100644 --- a/src/App/DocumentObject.h +++ b/src/App/DocumentObject.h @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -132,6 +133,21 @@ public: /// get group if object is part of a group, otherwise 0 is returned DocumentObjectGroup* getGroup() const; + /** + * @brief testIfLinkIsDAG tests a link that is about to be created for + * circular references. + * @param objToLinkIn (input). The object this object is to depend on after + * the link is going to be created. + * @return true if link can be created (no cycles will be made). False if + * the link will cause a circular dependency and break recomputes. Throws an + * error if the document already has a circular dependency. + * That is, if the return is true, the link is allowed. + */ + bool testIfLinkDAGCompatible(DocumentObject* linkTo) const; + bool testIfLinkDAGCompatible(const std::vector &linksTo) const; + bool testIfLinkDAGCompatible(App::PropertyLinkSubList &linksTo) const; + bool testIfLinkDAGCompatible(App::PropertyLinkSub &linkTo) const; + public: /** mustExecute