diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-08-18 22:33:41 +0200 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2020-09-02 22:44:29 +0200 |
commit | 5b81c80b464ac27b70546ad5ae8cc09e131d30c5 (patch) | |
tree | ad492d37011b47b7b283d047c0f0907d3669be99 /src/corelib/kernel/qproperty.cpp | |
parent | 918c61f275e8a9b46459f425df3b69961955a81d (diff) |
Add QObjectCompatProperty
Add a compatibility property class that makes porting to the new
property system as simple as possible.
Binding evaluation for those compat properties is eager, as we
do not control possible side effects of the code in the existing
setters.
Change-Id: Ic56347abb49e40631ec73e88c6d40d4bdb05ca29
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'src/corelib/kernel/qproperty.cpp')
-rw-r--r-- | src/corelib/kernel/qproperty.cpp | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/src/corelib/kernel/qproperty.cpp b/src/corelib/kernel/qproperty.cpp index b39b4c1c33..72f74ac1e8 100644 --- a/src/corelib/kernel/qproperty.cpp +++ b/src/corelib/kernel/qproperty.cpp @@ -82,6 +82,10 @@ void QPropertyBindingPrivate::markDirtyAndNotifyObservers() if (dirty) return; dirty = true; + if (requiresEagerEvaluation()) { + // these are compat properties that we will need to evaluate eagerly + evaluateIfDirtyAndReturnTrueIfValueChanged(propertyDataPtr); + } if (firstObserver) firstObserver.notify(this, propertyDataPtr); if (hasStaticObserver) @@ -109,7 +113,7 @@ bool QPropertyBindingPrivate::evaluateIfDirtyAndReturnTrueIfValueChanged(const Q QPropertyBindingPrivatePtr keepAlive {this}; QScopedValueRollback<bool> updateGuard(updating, true); - QBindingEvaluationState evaluationFrame(this); + BindingEvaluationState evaluationFrame(this); bool changed = false; @@ -117,7 +121,7 @@ bool QPropertyBindingPrivate::evaluateIfDirtyAndReturnTrueIfValueChanged(const Q QUntypedPropertyData *mutable_data = const_cast<QUntypedPropertyData *>(data); if (hasBindingWrapper) { - changed = staticBindingWrapper(metaType, propertyDataPtr, evaluationFunction); + changed = staticBindingWrapper(metaType, mutable_data, evaluationFunction); } else { changed = evaluationFunction(metaType, mutable_data); } @@ -260,6 +264,8 @@ QUntypedPropertyBinding QPropertyBindingData::setBinding(const QUntypedPropertyB if (observer) newBinding->prependObserver(observer); newBinding->setStaticObserver(staticObserverCallback, guardCallback); + if (newBinding->requiresEagerEvaluation()) + newBinding->evaluateIfDirtyAndReturnTrueIfValueChanged(propertyDataPtr); } else if (observer) { d.setObservers(observer.ptr); } else { @@ -280,27 +286,33 @@ QPropertyBindingPrivate *QPropertyBindingData::binding() const return nullptr; } -static thread_local QBindingEvaluationState *currentBindingEvaluationState = nullptr; +static thread_local QBindingStatus bindingStatus; -QBindingEvaluationState::QBindingEvaluationState(QPropertyBindingPrivate *binding) +BindingEvaluationState::BindingEvaluationState(QPropertyBindingPrivate *binding) : binding(binding) { // store a pointer to the currentBindingEvaluationState to avoid a TLS lookup in // the destructor (as these come with a non zero cost) - currentState = ¤tBindingEvaluationState; + currentState = &bindingStatus.currentlyEvaluatingBinding; previousState = *currentState; *currentState = this; binding->clearDependencyObservers(); } -QBindingEvaluationState::~QBindingEvaluationState() +CurrentCompatProperty::CurrentCompatProperty(QBindingStatus *status, QUntypedPropertyData *property) + : property(property) { - *currentState = previousState; + // store a pointer to the currentBindingEvaluationState to avoid a TLS lookup in + // the destructor (as these come with a non zero cost) + currentState = &status->currentCompatProperty; + previousState = *currentState; + *currentState = this; } QPropertyBindingPrivate *QPropertyBindingPrivate::currentlyEvaluatingBinding() { - return currentBindingEvaluationState ? currentBindingEvaluationState->binding : nullptr; + auto currentState = bindingStatus.currentlyEvaluatingBinding ; + return currentState ? currentState->binding : nullptr; } void QPropertyBindingData::evaluateIfDirty(const QUntypedPropertyData *property) const @@ -327,7 +339,7 @@ void QPropertyBindingData::removeBinding() void QPropertyBindingData::registerWithCurrentlyEvaluatingBinding() const { - auto currentState = currentBindingEvaluationState; + auto currentState = bindingStatus.currentlyEvaluatingBinding; if (!currentState) return; @@ -1448,8 +1460,8 @@ struct QBindingStoragePrivate QBindingStorage::QBindingStorage() { - currentlyEvaluatingBinding = ¤tBindingEvaluationState; - Q_ASSERT(currentlyEvaluatingBinding); + bindingStatus = &QT_PREPEND_NAMESPACE(bindingStatus); + Q_ASSERT(bindingStatus); } QBindingStorage::~QBindingStorage() @@ -1459,9 +1471,9 @@ QBindingStorage::~QBindingStorage() void QBindingStorage::maybeUpdateBindingAndRegister(const QUntypedPropertyData *data) const { - Q_ASSERT(currentlyEvaluatingBinding); + Q_ASSERT(bindingStatus); QUntypedPropertyData *dd = const_cast<QUntypedPropertyData *>(data); - auto storage = *currentlyEvaluatingBinding ? + auto storage = bindingStatus->currentlyEvaluatingBinding ? QBindingStoragePrivate(d).getAndCreate(dd) : QBindingStoragePrivate(d).get(dd); if (!storage) |