From a432bafbdb36bf60538371b9d4df17a7baa42d1e Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 8 Nov 2018 09:59:51 +0100 Subject: [PATCH] Add a new PropertyType enum Prop_NoRecompute to reduce possible inconsistencies between touched and recomputed features. At the moment many feature classes lack of the mustExecute() method and thus can cause a touched feature not to be recomputed and causes the feature to be in a broken state. Now this new enum value virtually makes the mustExecute() superfluous and thus guarantees to recompute a feature if a modified property has not set the Prop_NoRecompute flag. On the other hand there are properties that should only touch a feature but not enforce a recompute. This guarantees a better performance and avoids unnecessary recomputes. For example this is useful for placements where a change can be applied on-the-fly and the feature is up-to-date. Other features that depend on the touched feature will still be recomputed. --- src/App/DocumentObject.cpp | 8 ++++++-- src/App/DynamicProperty.h | 2 +- src/App/GeoFeature.cpp | 2 +- src/App/PropertyContainer.h | 17 +++++++++-------- src/App/PropertyContainerPyImp.cpp | 2 ++ 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/App/DocumentObject.cpp b/src/App/DocumentObject.cpp index 763a121ab9..69aa7cd6aa 100644 --- a/src/App/DocumentObject.cpp +++ b/src/App/DocumentObject.cpp @@ -527,9 +527,13 @@ void DocumentObject::onChanged(const Property* prop) _pDoc->signalRelabelObject(*this); // set object touched if it is an input property - if (!(prop->getType() & Prop_Output)) + if (!(prop->getType() & Prop_Output)) { StatusBits.set(ObjectStatus::Touch); - + // must execute on document recompute + if (!(prop->getType() & Prop_NoRecompute)) + StatusBits.set(ObjectStatus::Enforce); + } + //call the parent for appropriate handling TransactionalObject::onChanged(prop); } diff --git a/src/App/DynamicProperty.h b/src/App/DynamicProperty.h index 94847d6cd8..d22cf4e23a 100644 --- a/src/App/DynamicProperty.h +++ b/src/App/DynamicProperty.h @@ -64,7 +64,7 @@ public: @a Group gives the grouping name which appears in the property editor and @a doc shows the tooltip there. With @a attr, @a ro and @a hidden the behaviour of the property can be controlled. - @a attr is an OR'ed value of Prop_ReadOnly, Prop_Transient, Prop_Hidden or Prop_Output. + @a attr is an OR'ed value of the PropertyType enumeration. If no special attribute should be set Prop_None can be set (or leave the default of 0). For convenience the attributes for 'Read-Only' and 'Hidden' can also be controlled with the values @a ro or @a hidden. This means, diff --git a/src/App/GeoFeature.cpp b/src/App/GeoFeature.cpp index 1847b40332..7f1b201a6e 100644 --- a/src/App/GeoFeature.cpp +++ b/src/App/GeoFeature.cpp @@ -42,7 +42,7 @@ PROPERTY_SOURCE(App::GeoFeature, App::DocumentObject) GeoFeature::GeoFeature(void) { - ADD_PROPERTY(Placement,(Base::Placement())); + ADD_PROPERTY_TYPE(Placement,(Base::Placement()),nullptr,Prop_NoRecompute,nullptr); } GeoFeature::~GeoFeature(void) diff --git a/src/App/PropertyContainer.h b/src/App/PropertyContainer.h index dab65cc58c..54ecc4c6b7 100644 --- a/src/App/PropertyContainer.h +++ b/src/App/PropertyContainer.h @@ -43,11 +43,12 @@ class Extension; enum PropertyType { - Prop_None = 0, - Prop_ReadOnly = 1, - Prop_Transient= 2, - Prop_Hidden = 4, - Prop_Output = 8 + Prop_None = 0, /*!< No special property type */ + Prop_ReadOnly = 1, /*!< Property is read-only in the editor */ + Prop_Transient = 2, /*!< Property won't be saved to file */ + Prop_Hidden = 4, /*!< Property won't appear in the editor */ + Prop_Output = 8, /*!< Modified property doesn't touch its parent container */ + Prop_NoRecompute = 16 /*!< Modified property doesn't touch its container for recompute */ }; struct AppExport PropertyData @@ -66,8 +67,8 @@ struct AppExport PropertyData //accepting void* struct OffsetBase { - OffsetBase(const App::PropertyContainer* container) : m_container(container) {}; - OffsetBase(const App::Extension* container) : m_container(container) {}; + OffsetBase(const App::PropertyContainer* container) : m_container(container) {} + OffsetBase(const App::Extension* container) : m_container(container) {} short int getOffsetTo(const App::Property* prop) const { auto *pt = (const char*)prop; @@ -76,7 +77,7 @@ struct AppExport PropertyData return -1; return (short) (pt-base); }; - char* getOffset() const {return (char*) m_container;}; + char* getOffset() const {return (char*) m_container;} private: const void* m_container; diff --git a/src/App/PropertyContainerPyImp.cpp b/src/App/PropertyContainerPyImp.cpp index 43e06e700d..0e4fd4d8c8 100644 --- a/src/App/PropertyContainerPyImp.cpp +++ b/src/App/PropertyContainerPyImp.cpp @@ -82,6 +82,8 @@ PyObject* PropertyContainerPy::getTypeOfProperty(PyObject *args) ret.append(Py::String("ReadOnly")); if (Type & Prop_Output) ret.append(Py::String("Output")); + if (Type & Prop_NoRecompute) + ret.append(Py::String("NoRecompute")); if (Type & Prop_Transient) ret.append(Py::String("Transient"));