diff options
Diffstat (limited to 'src/qml/qml')
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 18 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 8 |
2 files changed, 21 insertions, 5 deletions
diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 449552c9c3..f7f14a0e8f 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -873,10 +873,20 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper } } - if (_ddata->hasBindingBit(bindingProperty->coreIndex()) && !(binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) - && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment) - && !_valueTypeProperty) + const bool allowedToRemoveBinding = !(binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) + && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment) + && !(binding->flags & QV4::CompiledData::Binding::IsPropertyObserver) + && !_valueTypeProperty; + + if (_ddata->hasBindingBit(bindingProperty->coreIndex()) && allowedToRemoveBinding) { QQmlPropertyPrivate::removeBinding(_bindingTarget, QQmlPropertyIndex(bindingProperty->coreIndex())); + } else if (bindingProperty->isBindable() && allowedToRemoveBinding) { + QList<DeferredQPropertyBinding> &pendingBindings = sharedState.data()->allQPropertyBindings; + auto it = std::remove_if(pendingBindings.begin(), pendingBindings.end(), [&](const DeferredQPropertyBinding &deferred) { + return deferred.properyIndex == bindingProperty->coreIndex() && deferred.target == _bindingTarget; + }); + pendingBindings.erase(it, pendingBindings.end()); + } if (binding->type == QV4::CompiledData::Binding::Type_Script || binding->isTranslationBinding()) { if (binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression @@ -920,7 +930,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *bindingProper QQmlPropertyIndex index(bindingProperty->coreIndex(), -1); qmlBinding = QQmlPropertyBinding::create(bindingProperty, runtimeFunction, _scopeObject, context, currentQmlContext(), _bindingTarget, index); } - sharedState.data()->allQPropertyBindings.emplaceBack(_bindingTarget, bindingProperty->coreIndex(), qmlBinding); + sharedState.data()->allQPropertyBindings.push_back(DeferredQPropertyBinding {_bindingTarget, bindingProperty->coreIndex(), qmlBinding }); } else { // When writing bindings to grouped properties implemented as value types, // such as point.x: { someExpression; }, then the binding is installed on diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 50489fd55b..4e788e88d4 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -89,6 +89,12 @@ struct RequiredPropertyInfo class RequiredProperties : public QHash<QQmlPropertyData*, RequiredPropertyInfo> {}; +struct DeferredQPropertyBinding { + QObject *target = nullptr; + int properyIndex = -1; + QUntypedPropertyBinding binding; +}; + struct QQmlObjectCreatorSharedState : QQmlRefCount { QQmlRefPointer<QQmlContextData> rootContext; @@ -102,7 +108,7 @@ struct QQmlObjectCreatorSharedState : QQmlRefCount QQmlVmeProfiler profiler; QRecursionNode recursionNode; RequiredProperties requiredProperties; - QList<std::tuple<QObject *, int, QUntypedPropertyBinding>> allQPropertyBindings; + QList<DeferredQPropertyBinding> allQPropertyBindings; bool hadRequiredProperties; }; |