Simplify binding setup code further
authorLars Knoll <lars.knoll@theqtcompany.com>
Wed, 15 Apr 2015 12:26:50 +0000 (14:26 +0200)
committerSimon Hausmann <simon.hausmann@theqtcompany.com>
Mon, 27 Apr 2015 05:20:12 +0000 (05:20 +0000)
Reduce the number of setBinding/removeBinding overloads and
simplify their internal handling.

Change-Id: I87174a3b2dc0ecb8380e8fc28f8969fbf475c728
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
13 files changed:
src/qml/debugger/qqmlenginedebugservice.cpp
src/qml/jsruntime/qv4qobjectwrapper.cpp
src/qml/qml/qqmlabstractbinding_p.h
src/qml/qml/qqmlobjectcreator.cpp
src/qml/qml/qqmlproperty.cpp
src/qml/qml/qqmlproperty_p.h
src/qml/qml/qqmlvaluetypewrapper.cpp
src/qml/qml/qqmlvmemetaobject.cpp
src/qml/types/qqmlbind.cpp
src/quick/util/qquickpropertychanges.cpp
src/quick/util/qquickstate.cpp
src/quick/util/qquicktransitionmanager.cpp
tests/auto/qml/qqmlproperty/tst_qqmlproperty.cpp

index 7067a78..a7ef450 100644 (file)
@@ -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
index f74ed15..c421fae 100644 (file)
@@ -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
index b9275dc..0d8766a 100644 (file)
@@ -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.
index 5a1dbdf..cf438cd 100644 (file)
@@ -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<QQmlValueTypeProxyBinding *>(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();
 
index f003bf8..cd59c2d 100644 (file)
@@ -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<QQmlValueTypeProxyBinding *>(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<QQmlValueTypeProxyBinding *>(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<QQmlValueTypeProxyBinding *>(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()) {
index 4b51128..b6b5421 100644 (file)
@@ -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
 
index 93df3a6..3d54833 100644 (file)
@@ -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<QQmlBindingFunction> bindingFunction(scope, (const Value &)f);
-        bindingFunction->initBindingLocation();
+            QV4::Scoped<QQmlBindingFunction> 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());
 
index 1260022..586d4aa 100644 (file)
@@ -874,10 +874,8 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
                     int flags = *reinterpret_cast<int*>(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);
                     }
                 }
 
index efa182b..43c583c 100644 (file)
@@ -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;
     }
 
index b190557..707323f 100644 (file)
@@ -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);
             }
         }
     }
index 684b068..483167f 100644 (file)
@@ -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<QQuickStateAction> &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();
index 81a3c34..ac57ac2 100644 (file)
@@ -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<QQuickStateAction> &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()) {
index 06fbe94..84f03f6 100644 (file)
@@ -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, "<Unknown File>: 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, "<Unknown File>: 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, "<Unknown File>: 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, "<Unknown File>: 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);