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.
This commit is contained in:
wmayer
2018-11-08 09:59:51 +01:00
parent d2089999e0
commit a432bafbdb
5 changed files with 19 additions and 12 deletions

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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)

View File

@@ -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;

View File

@@ -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"));