From 3bc239a0f16fb93f84def55a5980ef8561e7a7b4 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Wed, 15 Apr 2015 14:26:50 +0200 Subject: [PATCH] Simplify binding setup code further Reduce the number of setBinding/removeBinding overloads and simplify their internal handling. Change-Id: I87174a3b2dc0ecb8380e8fc28f8969fbf475c728 Reviewed-by: Simon Hausmann --- src/qml/debugger/qqmlenginedebugservice.cpp | 11 +- src/qml/jsruntime/qv4qobjectwrapper.cpp | 8 +- src/qml/qml/qqmlabstractbinding_p.h | 2 +- src/qml/qml/qqmlobjectcreator.cpp | 20 +-- src/qml/qml/qqmlproperty.cpp | 199 ++++++++--------------- src/qml/qml/qqmlproperty_p.h | 25 +-- src/qml/qml/qqmlvaluetypewrapper.cpp | 61 ++++--- src/qml/qml/qqmlvmemetaobject.cpp | 6 +- src/qml/types/qqmlbind.cpp | 13 +- src/quick/util/qquickpropertychanges.cpp | 20 +-- src/quick/util/qquickstate.cpp | 29 +--- src/quick/util/qquicktransitionmanager.cpp | 4 +- tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp | 26 +-- 13 files changed, 158 insertions(+), 266 deletions(-) diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp index 7067a78..a7ef450 100644 --- a/src/qml/debugger/qqmlenginedebugservice.cpp +++ b/src/qml/debugger/qqmlenginedebugservice.cpp @@ -646,9 +646,7 @@ bool QQmlEngineDebugService::setBinding(int objectId, } else if (property.isProperty()) { QQmlBinding *binding = new QQmlBinding(expression.toString(), object, QQmlContextData::get(context), filename, line, column); binding->setTarget(property); - QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::setBinding(property, binding); - if (oldBinding) - oldBinding->destroy(); + QQmlPropertyPrivate::setBinding(binding); binding->update(); } else { ok = false; @@ -679,12 +677,7 @@ bool QQmlEngineDebugService::resetBinding(int objectId, const QString &propertyN if (object->property(parentProperty.toLatin1()).isValid()) { QQmlProperty property(object, propertyName); - QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(property); - if (oldBinding) { - QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::removeBinding(property); - if (oldBinding) - oldBinding->destroy(); - } + QQmlPropertyPrivate::removeBinding(property, QQmlPropertyPrivate::DestroyOldBinding); if (property.isResettable()) { // Note: this will reset the property in any case, without regard to states // Right now almost no QQuickItem has reset methods for its properties (with the diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index f74ed15..c421fae 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -481,10 +481,10 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro } } - QQmlAbstractBinding *oldBinding = - QQmlPropertyPrivate::setBinding(object, property->coreIndex, -1, newBinding); - if (oldBinding) - oldBinding->destroy(); + if (newBinding) + QQmlPropertyPrivate::setBinding(newBinding); + else + QQmlPropertyPrivate::removeBinding(object, property->encodedIndex(), QQmlPropertyPrivate::DestroyOldBinding); if (!newBinding && property->isVarProperty()) { // allow assignment of "special" values (null, undefined, function) to var properties diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h index b9275dc..0d8766a 100644 --- a/src/qml/qml/qqmlabstractbinding_p.h +++ b/src/qml/qml/qqmlabstractbinding_p.h @@ -88,6 +88,7 @@ public: static inline Pointer getPointer(QQmlAbstractBinding *p); static void printBindingLoopError(QQmlProperty &prop); + inline QQmlAbstractBinding *nextBinding() const; protected: QQmlAbstractBinding(BindingType); @@ -114,7 +115,6 @@ private: inline void setAddedToObject(bool v); inline bool isAddedToObject() const; - inline QQmlAbstractBinding *nextBinding() const; inline void setNextBinding(QQmlAbstractBinding *); // Pointer to the next binding in the linked list of bindings. diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 5a1dbdf..cf438cd 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -62,14 +62,6 @@ struct ActiveOCRestorer }; } -static void removeBindingOnProperty(QObject *o, int index) -{ - int coreIndex; - int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex); - QQmlAbstractBinding *binding = QQmlPropertyPrivate::removeBinding(o, coreIndex, valueTypeIndex); - if (binding) binding->destroy(); -} - QQmlObjectCreator::QQmlObjectCreator(QQmlContextData *parentContext, QQmlCompiledData *compiledData, QQmlContextData *creationContext, void *activeVMEDataForRootContext) : phase(Startup) , compiledData(compiledData) @@ -664,8 +656,7 @@ void QQmlObjectCreator::setupBindings(const QBitArray &bindingsToSkip) QQmlPropertyPrivate::binding(_bindingTarget, _valueTypeProperty->coreIndex, -1); if (binding && binding->bindingType() != QQmlAbstractBinding::ValueTypeProxy) { - QQmlPropertyPrivate::removeBinding(_bindingTarget, _valueTypeProperty->coreIndex, -1); - binding->destroy(); + QQmlPropertyPrivate::removeBinding(_bindingTarget, _valueTypeProperty->coreIndex, QQmlPropertyPrivate::DestroyOldBinding); } else if (binding) { QQmlValueTypeProxyBinding *proxy = static_cast(binding); @@ -800,7 +791,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con if (_ddata->hasBindingBit(property->coreIndex) && !(binding->flags & QV4::CompiledData::Binding::IsSignalHandlerExpression) && !(binding->flags & QV4::CompiledData::Binding::IsOnAssignment) && !_valueTypeProperty) - removeBindingOnProperty(_bindingTarget, property->coreIndex); + QQmlPropertyPrivate::removeBinding(_bindingTarget, property->coreIndex, QQmlPropertyPrivate::DestroyOldBinding); if (binding->type == QV4::CompiledData::Binding::Type_Script) { QV4::Function *runtimeFunction = compiledData->compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex]; @@ -834,12 +825,7 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con qmlBinding->setTarget(_bindingTarget, targetCorePropertyData); if (targetCorePropertyData.isAlias()) { - QQmlAbstractBinding *old = - QQmlPropertyPrivate::setBindingNoEnable(_bindingTarget, - targetCorePropertyData.coreIndex, - targetCorePropertyData.getValueTypeCoreIndex(), - qmlBinding); - if (old) { old->destroy(); } + QQmlPropertyPrivate::setBinding(qmlBinding, QQmlPropertyPrivate::DontEnable|QQmlPropertyPrivate::DestroyOldBinding); } else { qmlBinding->addToObject(); diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index f003bf8..cd59c2d 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -717,37 +717,73 @@ QQmlPropertyPrivate::binding(const QQmlProperty &that) \a flags is passed through to the binding and is used for the initial update (when the binding sets the initial value, it will use these flags for the write). */ -QQmlAbstractBinding * -QQmlPropertyPrivate::setBinding(const QQmlProperty &that, - QQmlAbstractBinding *newBinding, - WriteFlags flags) +void +QQmlPropertyPrivate::setBinding(const QQmlProperty &that, QQmlAbstractBinding *newBinding) { - if (!newBinding) + if (!newBinding) { removeBinding(that); + return; + } if (!that.d || !that.isProperty() || !that.d->object) { newBinding->destroy(); + return; + } + setBinding(newBinding); +} + +static QQmlAbstractBinding *removeOldBinding(QObject *object, int index, QQmlPropertyPrivate::BindingFlags flags) +{ + int coreIndex; + int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex); + + QQmlData *data = QQmlData::get(object, false); + + if (!data || !data->hasBindingBit(coreIndex)) + return 0; + + QQmlAbstractBinding *oldBinding = data->bindings; + + while (oldBinding && oldBinding->targetPropertyIndex() != coreIndex) + oldBinding = oldBinding->nextBinding(); + + if (!oldBinding) + return 0; + + if (valueTypeIndex != -1 && oldBinding->bindingType() == QQmlAbstractBinding::ValueTypeProxy) + oldBinding = static_cast(oldBinding)->binding(index); + + if (!oldBinding) + return 0; + + oldBinding->removeFromObject(); + if (!(flags & QQmlPropertyPrivate::DontEnable)) + oldBinding->setEnabled(false, 0); + + if (flags & QQmlPropertyPrivate::DestroyOldBinding) { + oldBinding->destroy(); return 0; } - // In the case that the new binding is provided, we must target the property it - // is associated with. If we don't do this, retargetBinding() can fail. - QObject *object = newBinding->targetObject(); - int pi = newBinding->targetPropertyIndex(); + return oldBinding; +} - int core; - int vt = QQmlPropertyData::decodeValueTypePropertyIndex(pi, &core); +QQmlAbstractBinding *QQmlPropertyPrivate::removeBinding(QObject *o, int index, QQmlPropertyPrivate::BindingFlag flags) +{ + Q_ASSERT(o); - return setBinding(object, core, vt, newBinding, flags); + QObject *target; + int targetIndex; + findAliasTarget(o, index, &target, &targetIndex); + return removeOldBinding(target, targetIndex, flags); } -QQmlAbstractBinding *QQmlPropertyPrivate::removeBinding(const QQmlProperty &that) +QQmlAbstractBinding *QQmlPropertyPrivate::removeBinding(const QQmlProperty &that, BindingFlag flags) { if (!that.d || !that.isProperty() || !that.d->object) return 0; - return removeBinding(that.d->object, that.d->core.coreIndex, - that.d->core.getValueTypeCoreIndex()); + return removeBinding(that.d->object, that.d->core.encodedIndex(), flags); } QQmlAbstractBinding * @@ -792,11 +828,11 @@ QQmlPropertyPrivate::binding(QObject *object, int coreIndex, int valueTypeIndex) void QQmlPropertyPrivate::findAliasTarget(QObject *object, int bindingIndex, QObject **targetObject, int *targetBindingIndex) { - int coreIndex; - int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(bindingIndex, &coreIndex); - QQmlData *data = QQmlData::get(object, false); if (data) { + int coreIndex; + int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(bindingIndex, &coreIndex); + QQmlPropertyData *propertyData = data->propertyCache?data->propertyCache->property(coreIndex):0; if (propertyData && propertyData->isAlias()) { @@ -823,118 +859,30 @@ void QQmlPropertyPrivate::findAliasTarget(QObject *object, int bindingIndex, *targetBindingIndex = bindingIndex; } -QQmlAbstractBinding * -QQmlPropertyPrivate::setBinding(QObject *object, int coreIndex, int valueTypeIndex, - QQmlAbstractBinding *newBinding, WriteFlags flags) -{ - QQmlData *data = QQmlData::get(object, 0 != newBinding); - QQmlAbstractBinding *binding = 0; - - if (data) { - QQmlPropertyData *propertyData = - data->propertyCache?data->propertyCache->property(coreIndex):0; - if (propertyData && propertyData->isAlias()) { - QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex); - - QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1; - if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) { - if (newBinding) newBinding->destroy(); - return 0; - } - - // This will either be a value type sub-reference or an alias to a value-type sub-reference not both - Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); - aValueTypeIndex = (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex; - return setBinding(aObject, aCoreIndex, aValueTypeIndex, newBinding, flags); - } - } - - if (data && data->hasBindingBit(coreIndex)) { - binding = data->bindings; - - while (binding && binding->targetPropertyIndex() != coreIndex) - binding = binding->nextBinding(); - } - - int index = coreIndex; - if (valueTypeIndex != -1) - index = QQmlPropertyData::encodeValueTypePropertyIndex(index, valueTypeIndex); - - if (binding && valueTypeIndex != -1 && binding->bindingType() == QQmlAbstractBinding::ValueTypeProxy) - binding = static_cast(binding)->binding(index); - - if (binding) { - binding->removeFromObject(); - binding->setEnabled(false, 0); - } - - if (newBinding) { - Q_ASSERT(newBinding->targetPropertyIndex() == index); - Q_ASSERT(newBinding->targetObject() == object); - - newBinding->addToObject(); - newBinding->setEnabled(true, flags); - } - - return binding; -} - -QQmlAbstractBinding *QQmlPropertyPrivate::removeBinding(QObject *object, int coreIndex, int valueTypeIndex) -{ - return setBinding(object, coreIndex, valueTypeIndex, 0); -} -QQmlAbstractBinding * -QQmlPropertyPrivate::setBindingNoEnable(QObject *object, int coreIndex, int valueTypeIndex, - QQmlAbstractBinding *newBinding) +void QQmlPropertyPrivate::setBinding(QQmlAbstractBinding *binding, BindingFlags flags, WriteFlags writeFlags) { - QQmlData *data = QQmlData::get(object, 0 != newBinding); - QQmlAbstractBinding *binding = 0; + Q_ASSERT(binding); - if (data) { - QQmlPropertyData *propertyData = - data->propertyCache?data->propertyCache->property(coreIndex):0; - if (propertyData && propertyData->isAlias()) { - QQmlVMEMetaObject *vme = QQmlVMEMetaObject::getForProperty(object, coreIndex); - - QObject *aObject = 0; int aCoreIndex = -1; int aValueTypeIndex = -1; - if (!vme->aliasTarget(coreIndex, &aObject, &aCoreIndex, &aValueTypeIndex)) { - if (newBinding) newBinding->destroy(); - return 0; - } - - // This will either be a value type sub-reference or an alias to a value-type sub-reference not both - Q_ASSERT(valueTypeIndex == -1 || aValueTypeIndex == -1); - aValueTypeIndex = (valueTypeIndex == -1)?aValueTypeIndex:valueTypeIndex; - return setBindingNoEnable(aObject, aCoreIndex, aValueTypeIndex, newBinding); - } - } + QObject *object = binding->targetObject(); + int index = binding->targetPropertyIndex(); - if (data && data->hasBindingBit(coreIndex)) { - binding = data->bindings; - - while (binding && binding->targetPropertyIndex() != coreIndex) - binding = binding->nextBinding(); +#ifndef QT_NO_DEBUG + int coreIndex; + QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex); + QQmlData *data = QQmlData::get(object, true); + if (data->propertyCache) { + QQmlPropertyData *propertyData = data->propertyCache->property(coreIndex); + Q_ASSERT(propertyData && !propertyData->isAlias()); } +#endif - int index = coreIndex; - if (valueTypeIndex != -1) - index = QQmlPropertyData::encodeValueTypePropertyIndex(index, valueTypeIndex); - - if (binding && valueTypeIndex != -1 && binding->bindingType() == QQmlAbstractBinding::ValueTypeProxy) - binding = static_cast(binding)->binding(index); - - if (binding) - binding->removeFromObject(); - - if (newBinding) { - Q_ASSERT(newBinding->targetPropertyIndex() == index); - Q_ASSERT(newBinding->targetObject() == object); + removeOldBinding(object, index, flags); - newBinding->addToObject(); - } + binding->addToObject(); + if (!(flags & DontEnable)) + binding->setEnabled(true, writeFlags); - return binding; } /*! @@ -1215,11 +1163,8 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object, QQmlContextData *context, WriteFlags flags) { // Remove any existing bindings on this property - if (!(flags & DontRemoveBinding) && object) { - QQmlAbstractBinding *binding = removeBinding(object, core.coreIndex, - core.getValueTypeCoreIndex()); - if (binding) binding->destroy(); - } + if (!(flags & DontRemoveBinding) && object) + removeBinding(object, core.encodedIndex(), DestroyOldBinding); bool rv = false; if (core.isValueTypeVirtual()) { diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h index 4b51128..b6b5421 100644 --- a/src/qml/qml/qqmlproperty_p.h +++ b/src/qml/qml/qqmlproperty_p.h @@ -104,14 +104,17 @@ public: QQmlContextData *, WriteFlags flags = 0); static void findAliasTarget(QObject *, int, QObject **, int *); - static QQmlAbstractBinding *setBinding(QObject *, int coreIndex, - int valueTypeIndex /* -1 */, - QQmlAbstractBinding *, - WriteFlags flags = DontRemoveBinding); - static QQmlAbstractBinding *removeBinding(QObject *object, int coreIndex, int valueTypeIndex /* -1 */); - static QQmlAbstractBinding *setBindingNoEnable(QObject *, int coreIndex, - int valueTypeIndex /* -1 */, - QQmlAbstractBinding *); + enum BindingFlag { + None = 0, + DestroyOldBinding = 0x1, + DontEnable = 0x2 + }; + Q_DECLARE_FLAGS(BindingFlags, BindingFlag) + + static void setBinding(QQmlAbstractBinding *binding, BindingFlags flags = None, WriteFlags writeFlags = DontRemoveBinding); + + static QQmlAbstractBinding *removeBinding(const QQmlProperty &that, BindingFlag flag = None); + static QQmlAbstractBinding *removeBinding(QObject *o, int index, BindingFlag flag = None); static QQmlAbstractBinding *binding(QObject *, int coreIndex, int valueTypeIndex /* -1 */); @@ -130,10 +133,7 @@ public: // "Public" (to QML) methods static QQmlAbstractBinding *binding(const QQmlProperty &that); - static QQmlAbstractBinding *setBinding(const QQmlProperty &that, - QQmlAbstractBinding *, - WriteFlags flags = DontRemoveBinding); - static QQmlAbstractBinding *removeBinding(const QQmlProperty &that); + static void setBinding(const QQmlProperty &that, QQmlAbstractBinding *); static QQmlBoundSignalExpression *signalExpression(const QQmlProperty &that); static QQmlBoundSignalExpressionPointer setSignalExpression(const QQmlProperty &that, QQmlBoundSignalExpression *); @@ -156,6 +156,7 @@ public: }; Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyPrivate::WriteFlags) +Q_DECLARE_OPERATORS_FOR_FLAGS(QQmlPropertyPrivate::BindingFlags) QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index 93df3a6..3d54833 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -407,45 +407,42 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value) QMetaProperty property = metaObject->property(pd->coreIndex); Q_ASSERT(property.isValid()); - QQmlBinding *newBinding = 0; - - QV4::ScopedFunctionObject f(scope, value); - if (reference && f) { - if (!f->isBinding()) { - // assigning a JS function to a non-var-property is not allowed. - QString error = QStringLiteral("Cannot assign JavaScript function to value-type property"); - ScopedString e(scope, v4->newString(error)); - v4->throwError(e); - return; - } + if (reference) { + QV4::ScopedFunctionObject f(scope, value); + if (f) { + if (!f->isBinding()) { + // assigning a JS function to a non-var-property is not allowed. + QString error = QStringLiteral("Cannot assign JavaScript function to value-type property"); + ScopedString e(scope, v4->newString(error)); + v4->throwError(e); + return; + } - QQmlContextData *context = QmlContextWrapper::callingContext(v4); + QQmlContextData *context = QmlContextWrapper::callingContext(v4); - QQmlPropertyData cacheData; - cacheData.setFlags(QQmlPropertyData::IsWritable | - QQmlPropertyData::IsValueTypeVirtual); - cacheData.propType = writeBackPropertyType; - cacheData.coreIndex = reference->d()->property; - cacheData.valueTypeFlags = 0; - cacheData.valueTypeCoreIndex = pd->coreIndex; - cacheData.valueTypePropType = property.userType(); + QQmlPropertyData cacheData; + cacheData.setFlags(QQmlPropertyData::IsWritable | + QQmlPropertyData::IsValueTypeVirtual); + cacheData.propType = writeBackPropertyType; + cacheData.coreIndex = reference->d()->property; + cacheData.valueTypeFlags = 0; + cacheData.valueTypeCoreIndex = pd->coreIndex; + cacheData.valueTypePropType = property.userType(); - QV4::Scoped bindingFunction(scope, (const Value &)f); - bindingFunction->initBindingLocation(); + QV4::Scoped bindingFunction(scope, (const Value &)f); + bindingFunction->initBindingLocation(); - newBinding = new QQmlBinding(value, reference->d()->object, context); - newBinding->setTarget(reference->d()->object, cacheData); - } + QQmlBinding *newBinding = new QQmlBinding(value, reference->d()->object, context); + newBinding->setTarget(reference->d()->object, cacheData); + QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::DestroyOldBinding); + return; + } else { + QQmlPropertyPrivate::removeBinding(reference->d()->object, QQmlPropertyData::encodeValueTypePropertyIndex(reference->d()->property, pd->coreIndex), + QQmlPropertyPrivate::DestroyOldBinding); - if (reference) { - QQmlAbstractBinding *oldBinding = - QQmlPropertyPrivate::setBinding(reference->d()->object, reference->d()->property, pd->coreIndex, newBinding); - if (oldBinding) - oldBinding->destroy(); + } } - if (newBinding) - return; QVariant v = v4->toVariant(value, property.userType()); diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 1260022..586d4aa 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -874,10 +874,8 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) int flags = *reinterpret_cast(a[3]); if (flags & QQmlPropertyPrivate::RemoveBindingOnAliasWrite) { QQmlData *targetData = QQmlData::get(target); - if (targetData && targetData->hasBindingBit(d->propertyIndex())) { - QQmlAbstractBinding *binding = QQmlPropertyPrivate::removeBinding(target, d->propertyIndex(), d->isValueTypeAlias() ? d->valueTypeIndex() : -1); - if (binding) binding->destroy(); - } + if (targetData && targetData->hasBindingBit(d->propertyIndex())) + QQmlPropertyPrivate::removeBinding(target, d->propertyIdx, QQmlPropertyPrivate::DestroyOldBinding); } } diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp index efa182b..43c583c 100644 --- a/src/qml/types/qqmlbind.cpp +++ b/src/qml/types/qqmlbind.cpp @@ -277,20 +277,17 @@ void QQmlBind::eval() if (!d->when) { //restore any previous binding if (d->prevBind) { - QQmlAbstractBinding *tmp = d->prevBind; + QQmlAbstractBinding *b = QQmlPropertyPrivate::binding(d->prop); + if (b != d->prevBind) + QQmlPropertyPrivate::setBinding(d->prevBind, QQmlPropertyPrivate::DestroyOldBinding); d->prevBind = 0; - tmp = QQmlPropertyPrivate::setBinding(d->prop, tmp); - if (tmp) //should this ever be true? - tmp->destroy(); } return; } //save any set binding for restoration - QQmlAbstractBinding *tmp = QQmlPropertyPrivate::removeBinding(d->prop); - if (tmp && d->prevBind) - tmp->destroy(); - else if (!d->prevBind) + QQmlAbstractBinding *tmp = QQmlPropertyPrivate::removeBinding(d->prop, (d->prevBind ? QQmlPropertyPrivate::DestroyOldBinding : QQmlPropertyPrivate::None)); + if (tmp && !d->prevBind) d->prevBind = tmp; } diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index b190557..707323f 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -558,11 +558,7 @@ void QQuickPropertyChanges::changeValue(const QString &name, const QVariant &val if (entry.name == name) { expressionIterator.remove(); if (state() && state()->isStateActive()) { - QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(d->property(name)); - if (oldBinding) { - QQmlPropertyPrivate::removeBinding(d->property(name)); - oldBinding->destroy(); - } + QQmlPropertyPrivate::removeBinding(d->property(name), QQmlPropertyPrivate::DestroyOldBinding); d->property(name).write(value); } @@ -624,15 +620,9 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString if (entry.name == name) { entry.expression = expression; if (state() && state()->isStateActive()) { - QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(d->property(name)); - if (oldBinding) { - QQmlPropertyPrivate::removeBinding(d->property(name)); - oldBinding->destroy(); - } - QQmlBinding *newBinding = new QQmlBinding(expression, object(), qmlContext(this)); newBinding->setTarget(d->property(name)); - QQmlPropertyPrivate::setBinding(d->property(name), newBinding, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor); + QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor); } return; } @@ -651,7 +641,7 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString QQmlBinding *newBinding = new QQmlBinding(expression, object(), qmlContext(this)); newBinding->setTarget(d->property(name)); - QQmlPropertyPrivate::setBinding(d->property(name), newBinding, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor); + QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor); } else { QQuickStateAction action; action.restore = restoreEntryValues(); @@ -668,7 +658,7 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString action.toValue = newBinding->evaluate(); newBinding->destroy(); } else { - newBinding->setTarget(d->property(name)); + newBinding->setTarget(action.property); action.toBinding = QQmlAbstractBinding::getPointer(newBinding); action.deletableToBinding = true; @@ -677,7 +667,7 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString if (oldBinding) oldBinding->setEnabled(false, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor); - QQmlPropertyPrivate::setBinding(action.property, newBinding, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor); + QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::None, QQmlPropertyPrivate::DontRemoveBinding | QQmlPropertyPrivate::BypassInterceptor); } } } diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp index 684b068..483167f 100644 --- a/src/quick/util/qquickstate.cpp +++ b/src/quick/util/qquickstate.cpp @@ -435,15 +435,11 @@ bool QQuickState::removeEntryFromRevertList(QObject *target, const QString &name while (revertListIterator.hasNext()) { QQuickSimpleAction &simpleAction = revertListIterator.next(); if (simpleAction.property().object() == target && simpleAction.property().name() == name) { - QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(simpleAction.property()); - if (oldBinding) { - QQmlPropertyPrivate::removeBinding(simpleAction.property()); - oldBinding->destroy(); - } + QQmlPropertyPrivate::removeBinding(simpleAction.property(), QQmlPropertyPrivate::DestroyOldBinding); simpleAction.property().write(simpleAction.value()); if (simpleAction.binding()) - QQmlPropertyPrivate::setBinding(simpleAction.property(), simpleAction.binding()); + QQmlPropertyPrivate::setBinding(simpleAction.binding()); revertListIterator.remove(); return true; @@ -473,15 +469,11 @@ void QQuickState::removeAllEntriesFromRevertList(QObject *target) while (revertListIterator.hasNext()) { QQuickSimpleAction &simpleAction = revertListIterator.next(); if (simpleAction.property().object() == target) { - QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(simpleAction.property()); - if (oldBinding) { - QQmlPropertyPrivate::removeBinding(simpleAction.property()); - oldBinding->destroy(); - } + QQmlPropertyPrivate::removeBinding(simpleAction.property(), QQmlPropertyPrivate::DestroyOldBinding); simpleAction.property().write(simpleAction.value()); if (simpleAction.binding()) - QQmlPropertyPrivate::setBinding(simpleAction.property(), simpleAction.binding()); + QQmlPropertyPrivate::setBinding(simpleAction.binding()); revertListIterator.remove(); } @@ -500,12 +492,8 @@ void QQuickState::addEntriesToRevertList(const QList &actionL const QQuickStateAction &action = actionListIterator.next(); QQuickSimpleAction simpleAction(action); action.property.write(action.toValue); - if (!action.toBinding.isNull()) { - QQmlAbstractBinding *oldBinding = QQmlPropertyPrivate::binding(simpleAction.property()); - if (oldBinding) - QQmlPropertyPrivate::removeBinding(simpleAction.property()); - QQmlPropertyPrivate::setBinding(simpleAction.property(), action.toBinding.data(), QQmlPropertyPrivate::DontRemoveBinding); - } + if (!action.toBinding.isNull()) + QQmlPropertyPrivate::setBinding(action.toBinding.data()); simpleActionList.append(simpleAction); } @@ -663,10 +651,7 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert) } if (!found) { QVariant cur = d->revertList.at(ii).property().read(); - QQmlAbstractBinding *delBinding = - QQmlPropertyPrivate::removeBinding(d->revertList.at(ii).property()); - if (delBinding) - delBinding->destroy(); + QQmlPropertyPrivate::removeBinding(d->revertList.at(ii).property(), QQmlPropertyPrivate::DestroyOldBinding); QQuickStateAction a; a.property = d->revertList.at(ii).property(); diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp index 81a3c34..ac57ac2 100644 --- a/src/quick/util/qquicktransitionmanager.cpp +++ b/src/quick/util/qquicktransitionmanager.cpp @@ -102,7 +102,7 @@ void QQuickTransitionManagerPrivate::applyBindings() { foreach(const QQuickStateAction &action, bindingsList) { if (!action.toBinding.isNull()) { - QQmlPropertyPrivate::setBinding(action.property, action.toBinding.data()); + QQmlPropertyPrivate::setBinding(action.toBinding.data()); } else if (action.event) { if (action.reverseEvent) action.event->reverse(); @@ -156,7 +156,7 @@ void QQuickTransitionManager::transition(const QList &list, for (int ii = 0; ii < applyList.size(); ++ii) { const QQuickStateAction &action = applyList.at(ii); if (!action.toBinding.isNull()) { - QQmlPropertyPrivate::setBinding(action.property, action.toBinding.data(), QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding); + QQmlPropertyPrivate::setBinding(action.toBinding.data(), QQmlPropertyPrivate::None, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding); } else if (!action.event) { QQmlPropertyPrivate::write(action.property, action.toValue, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding); } else if (action.event->isReversable()) { diff --git a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp index 06fbe94..84f03f6 100644 --- a/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp +++ b/tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp @@ -189,7 +189,7 @@ void tst_qqmlproperty::qmlmetaproperty() QCOMPARE(prop.propertyTypeName(), (const char *)0); QVERIFY(prop.property().name() == 0); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding == 0); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); @@ -440,7 +440,7 @@ void tst_qqmlproperty::qmlmetaproperty_object() QCOMPARE(prop.propertyTypeName(), (const char *)0); QVERIFY(prop.property().name() == 0); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding == 0); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); @@ -489,7 +489,7 @@ void tst_qqmlproperty::qmlmetaproperty_object() QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); QTest::ignoreMessage(QtWarningMsg, ": Unable to assign null to int"); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding != 0); QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data()); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); @@ -543,7 +543,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() QCOMPARE(prop.propertyTypeName(), (const char *)0); QVERIFY(prop.property().name() == 0); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding == 0); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); @@ -592,7 +592,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); QTest::ignoreMessage(QtWarningMsg, ": Unable to assign null to int"); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding != 0); QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data()); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); @@ -641,7 +641,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding == 0); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); @@ -690,7 +690,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string() QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding == 0); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); @@ -744,7 +744,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_context() QCOMPARE(prop.propertyTypeName(), (const char *)0); QVERIFY(prop.property().name() == 0); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding == 0); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); @@ -793,7 +793,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_context() QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); QTest::ignoreMessage(QtWarningMsg, ": Unable to assign null to int"); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding != 0); QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data()); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); @@ -847,7 +847,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.propertyTypeName(), (const char *)0); QVERIFY(prop.property().name() == 0); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding == 0); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); @@ -896,7 +896,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() QCOMPARE(QString(prop.property().name()), QString("defaultProperty")); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); QTest::ignoreMessage(QtWarningMsg, ": Unable to assign null to int"); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding != 0); QVERIFY(QQmlPropertyPrivate::binding(prop) == binding.data()); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); @@ -945,7 +945,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding == 0); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); @@ -994,7 +994,7 @@ void tst_qqmlproperty::qmlmetaproperty_object_string_context() QCOMPARE(prop.propertyTypeName(), (const char *)0); QCOMPARE(prop.property().name(), (const char *)0); QVERIFY(QQmlPropertyPrivate::binding(prop) == 0); - QVERIFY(QQmlPropertyPrivate::setBinding(prop, binding.data()) == 0); + QQmlPropertyPrivate::setBinding(prop, binding.data()); QVERIFY(binding == 0); QVERIFY(QQmlPropertyPrivate::signalExpression(prop) == 0); QVERIFY(QQmlPropertyPrivate::takeSignalExpression(prop, sigExpr) == 0); -- 2.7.4