diff options
Diffstat (limited to 'src/corelib/kernel')
-rw-r--r-- | src/corelib/kernel/qproperty.cpp | 8 | ||||
-rw-r--r-- | src/corelib/kernel/qproperty_p.h | 11 |
2 files changed, 17 insertions, 2 deletions
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index 72f74ac1e8..81871587e8 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -41,6 +41,7 @@ #include "qproperty_p.h" #include <qscopedvaluerollback.h> +#include <QScopeGuard> QT_BEGIN_NAMESPACE @@ -82,6 +83,13 @@ void QPropertyBindingPrivate::markDirtyAndNotifyObservers() if (dirty) return; dirty = true; + if (eagerlyUpdating) { + error = QPropertyBindingError(QPropertyBindingError::BindingLoop); + return; + } + + eagerlyUpdating = true; + QScopeGuard guard([&](){eagerlyUpdating = false;}); if (requiresEagerEvaluation()) { // these are compat properties that we will need to evaluate eagerly evaluateIfDirtyAndReturnTrueIfValueChanged(propertyDataPtr); diff --git a/src/corelib/kernel/qproperty_p.h b/src/corelib/kernel/qproperty_p.h index c5c74147c1..999760ec86 100644 --- a/src/corelib/kernel/qproperty_p.h +++ b/src/corelib/kernel/qproperty_p.h @@ -163,10 +163,15 @@ private: using ObserverArray = std::array<QPropertyObserver, 4>; // QSharedData is 4 bytes. Use the padding for the bools as we need 8 byte alignment below. + + // a dependent property has changed, and the binding needs to be reevaluated on access bool dirty = false; + // used to detect binding loops for lazy evaluated properties bool updating = false; bool hasStaticObserver = false; - bool hasBindingWrapper = false; + bool hasBindingWrapper:1; + // used to detect binding loops for eagerly evaluated properties + bool eagerlyUpdating:1; QUntypedPropertyBinding::BindingEvaluationFunction evaluationFunction; @@ -192,7 +197,9 @@ public: QPropertyBindingPrivate(QMetaType metaType, QUntypedPropertyBinding::BindingEvaluationFunction evaluationFunction, const QPropertyBindingSourceLocation &location) - : evaluationFunction(std::move(evaluationFunction)) + : hasBindingWrapper(false) + , eagerlyUpdating(false) + , evaluationFunction(std::move(evaluationFunction)) , inlineDependencyObservers() // Explicit initialization required because of union , location(location) , metaType(metaType) |