diff options
Diffstat (limited to 'src/qml')
-rw-r--r-- | src/qml/debugger/qqmlenginedebugservice.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlabstractbinding.cpp | 78 | ||||
-rw-r--r-- | src/qml/qml/qqmlabstractbinding_p.h | 46 | ||||
-rw-r--r-- | src/qml/qml/qqmlbinding.cpp | 8 | ||||
-rw-r--r-- | src/qml/qml/qqmlbinding_p.h | 6 | ||||
-rw-r--r-- | src/qml/qml/qqmldata_p.h | 10 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine.cpp | 24 | ||||
-rw-r--r-- | src/qml/qml/qqmlengine_p.h | 1 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator.cpp | 21 | ||||
-rw-r--r-- | src/qml/qml/qqmlobjectcreator_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlproperty.cpp | 41 | ||||
-rw-r--r-- | src/qml/qml/qqmlproperty_p.h | 9 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypeproxybinding.cpp | 19 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypeproxybinding_p.h | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlvaluetypewrapper.cpp | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmlvmemetaobject.cpp | 2 | ||||
-rw-r--r-- | src/qml/types/qqmlbind.cpp | 17 |
18 files changed, 131 insertions, 164 deletions
diff --git a/src/qml/debugger/qqmlenginedebugservice.cpp b/src/qml/debugger/qqmlenginedebugservice.cpp index 0a2cb2de05..20a9b083bb 100644 --- a/src/qml/debugger/qqmlenginedebugservice.cpp +++ b/src/qml/debugger/qqmlenginedebugservice.cpp @@ -674,7 +674,7 @@ bool QQmlEngineDebugService::resetBinding(int objectId, const QString &propertyN if (object->property(parentProperty.toLatin1()).isValid()) { QQmlProperty property(object, propertyName); - QQmlPropertyPrivate::removeBinding(property, QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::removeBinding(property); 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 e985c62228..ca25d40e4a 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -484,7 +484,7 @@ void QObjectWrapper::setProperty(QObject *object, ExecutionContext *ctx, QQmlPro if (newBinding) QQmlPropertyPrivate::setBinding(newBinding); else - QQmlPropertyPrivate::removeBinding(object, property->encodedIndex(), QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::removeBinding(object, property->encodedIndex()); if (!newBinding && property->isVarProperty()) { // allow assignment of "special" values (null, undefined, function) to var properties diff --git a/src/qml/qml/qqmlabstractbinding.cpp b/src/qml/qml/qqmlabstractbinding.cpp index 4a081ae0e8..0d281b7750 100644 --- a/src/qml/qml/qqmlabstractbinding.cpp +++ b/src/qml/qml/qqmlabstractbinding.cpp @@ -40,15 +40,17 @@ QT_BEGIN_NAMESPACE QQmlAbstractBinding::QQmlAbstractBinding() - : m_nextBinding(0) + : m_nextBinding(0), + m_targetIndex(-1), + m_isAddedToObject(false) { + Q_ASSERT(!isAddedToObject()); } QQmlAbstractBinding::~QQmlAbstractBinding() { - Q_ASSERT(isAddedToObject() == false); - Q_ASSERT(nextBinding() == 0); - Q_ASSERT(*m_mePtr == 0); + Q_ASSERT(!ref); + Q_ASSERT(!isAddedToObject()); } /*! @@ -92,12 +94,17 @@ void QQmlAbstractBinding::addToObject() proxy->addToObject(); } - setNextBinding(proxy->m_bindings); + setNextBinding(proxy->m_bindings.data()); proxy->m_bindings = this; } else { setNextBinding(data->bindings); + if (data->bindings) { + data->bindings->ref.deref(); + Q_ASSERT(data->bindings->ref.refCount > 0); + } data->bindings = this; + ref.ref(); data->setBindingBit(obj, coreIndex); } @@ -113,10 +120,16 @@ void QQmlAbstractBinding::removeFromObject() if (!isAddedToObject()) return; + setAddedToObject(false); + QObject *obj = targetObject(); QQmlData *data = QQmlData::get(obj, false); Q_ASSERT(data); + QQmlAbstractBinding::Ptr next; + next = nextBinding(); + setNextBinding(0); + int coreIndex; if (QQmlPropertyData::decodeValueTypePropertyIndex(targetPropertyIndex(), &coreIndex) != -1) { @@ -131,39 +144,39 @@ void QQmlAbstractBinding::removeFromObject() QQmlValueTypeProxyBinding *vtproxybinding = static_cast<QQmlValueTypeProxyBinding *>(vtbinding); - QQmlAbstractBinding *binding = vtproxybinding->m_bindings; + QQmlAbstractBinding *binding = vtproxybinding->m_bindings.data(); if (binding == this) { - vtproxybinding->m_bindings = nextBinding(); + vtproxybinding->m_bindings = next; } else { while (binding->nextBinding() != this) { binding = binding->nextBinding(); Q_ASSERT(binding); } - binding->setNextBinding(nextBinding()); + binding->setNextBinding(next.data()); } // Value type - we don't remove the proxy from the object. It will sit their happily // doing nothing until it is removed by a write, a binding change or it is reused // to hold more sub-bindings. + return; + } + if (data->bindings == this) { + if (next.data()) + next->ref.ref(); + data->bindings = next.data(); + if (!ref.deref()) + delete this; } else { - - if (data->bindings == this) { - data->bindings = nextBinding(); - } else { - QQmlAbstractBinding *binding = data->bindings; - while (binding->nextBinding() != this) { - binding = binding->nextBinding(); - Q_ASSERT(binding); - } - binding->setNextBinding(nextBinding()); + QQmlAbstractBinding *binding = data->bindings; + while (binding->nextBinding() != this) { + binding = binding->nextBinding(); + Q_ASSERT(binding); } - - data->clearBindingBit(coreIndex); + binding->setNextBinding(next.data()); } - setNextBinding(0); - setAddedToObject(false); + data->clearBindingBit(coreIndex); } void QQmlAbstractBinding::printBindingLoopError(QQmlProperty &prop) @@ -171,27 +184,6 @@ void QQmlAbstractBinding::printBindingLoopError(QQmlProperty &prop) qmlInfo(prop.object()) << QString(QLatin1String("Binding loop detected for property \"%1\"")).arg(prop.name()); } - -static void bindingDummyDeleter(QQmlAbstractBinding *) -{ -} - -QQmlAbstractBinding::Pointer QQmlAbstractBinding::weakPointer() -{ - if (m_mePtr.value().isNull()) - m_mePtr.value() = QSharedPointer<QQmlAbstractBinding>(this, bindingDummyDeleter); - - return m_mePtr.value().toWeakRef(); -} - -void QQmlAbstractBinding::clear() -{ - if (!m_mePtr.isNull()) { - **m_mePtr = 0; - m_mePtr = 0; - } -} - QString QQmlAbstractBinding::expression() const { return QLatin1String("<Unknown>"); diff --git a/src/qml/qml/qqmlabstractbinding_p.h b/src/qml/qml/qqmlabstractbinding_p.h index f72d6918a1..79107bb04c 100644 --- a/src/qml/qml/qqmlabstractbinding_p.h +++ b/src/qml/qml/qqmlabstractbinding_p.h @@ -46,6 +46,7 @@ // #include <QtCore/qsharedpointer.h> +#include <QtCore/qshareddata.h> #include <private/qtqmlglobal_p.h> #include <private/qqmlproperty_p.h> #include <private/qpointervaluepair_p.h> @@ -56,14 +57,12 @@ class QQmlObjectCreator; class Q_QML_PRIVATE_EXPORT QQmlAbstractBinding { +protected: + QQmlAbstractBinding(); public: - typedef QWeakPointer<QQmlAbstractBinding> Pointer; + virtual ~QQmlAbstractBinding(); - void destroy() { - removeFromObject(); - clear(); - delete this; - } + typedef QExplicitlySharedDataPointer<QQmlAbstractBinding> Ptr; virtual QString expression() const; @@ -83,28 +82,26 @@ public: void addToObject(); void removeFromObject(); - static inline Pointer getPointer(QQmlAbstractBinding *p); static void printBindingLoopError(QQmlProperty &prop); inline QQmlAbstractBinding *nextBinding() const; -protected: - QQmlAbstractBinding(); - virtual ~QQmlAbstractBinding(); - void clear(); + + struct RefCount { + RefCount() : refCount(0) {} + int refCount; + void ref() { ++refCount; } + int deref() { return --refCount; } + operator int() const { return refCount; } + }; + RefCount ref; private: friend class QQmlData; friend class QQmlValueTypeProxyBinding; friend class QQmlObjectCreator; - Pointer weakPointer(); - typedef QSharedPointer<QQmlAbstractBinding> SharedPointer; - // To save memory, we also store the rarely used weakPointer() instance in here - // We also use the flag bits: - // m_mePtr.flag1: added to object - QPointerValuePair<QQmlAbstractBinding*, SharedPointer> m_mePtr; inline void setAddedToObject(bool v); inline bool isAddedToObject() const; @@ -112,32 +109,27 @@ private: inline void setNextBinding(QQmlAbstractBinding *); // Pointer to the next binding in the linked list of bindings. - QQmlAbstractBinding *m_nextBinding; + Ptr m_nextBinding; protected: QFlagPointer<QObject> m_target; int m_targetIndex; + bool m_isAddedToObject; }; -QQmlAbstractBinding::Pointer -QQmlAbstractBinding::getPointer(QQmlAbstractBinding *p) -{ - return p ? p->weakPointer() : Pointer(); -} - void QQmlAbstractBinding::setAddedToObject(bool v) { - m_mePtr.setFlagValue(v); + m_isAddedToObject = v; } bool QQmlAbstractBinding::isAddedToObject() const { - return m_mePtr.flag(); + return m_isAddedToObject; } QQmlAbstractBinding *QQmlAbstractBinding::nextBinding() const { - return m_nextBinding; + return m_nextBinding.data(); } void QQmlAbstractBinding::setNextBinding(QQmlAbstractBinding *b) diff --git a/src/qml/qml/qqmlbinding.cpp b/src/qml/qml/qqmlbinding.cpp index 317c4172d7..72f35e17d6 100644 --- a/src/qml/qml/qqmlbinding.cpp +++ b/src/qml/qml/qqmlbinding.cpp @@ -191,7 +191,7 @@ void QQmlBinding::update(QQmlPropertyPrivate::WriteFlags flags) QV4::ScopedValue result(scope, QQmlJavaScriptExpression::evaluate(&isUndefined)); bool error = false; - if (!watcher.wasDeleted() && !hasError()) + if (!watcher.wasDeleted() && m_isAddedToObject && !hasError()) error = !write(pd, result, isUndefined, flags); if (!watcher.wasDeleted()) { @@ -426,6 +426,12 @@ void QQmlBinding::setTarget(const QQmlProperty &prop) void QQmlBinding::setTarget(QObject *object, const QQmlPropertyData &core) { m_target = object; + + if (!object) { + m_targetIndex = -1; + return; + } + QQmlPropertyData pd = core; if (!object) { diff --git a/src/qml/qml/qqmlbinding_p.h b/src/qml/qml/qqmlbinding_p.h index 4d6c67eb47..cb90c757b2 100644 --- a/src/qml/qml/qqmlbinding_p.h +++ b/src/qml/qml/qqmlbinding_p.h @@ -65,6 +65,7 @@ class QQmlContext; class Q_QML_PRIVATE_EXPORT QQmlBinding : public QQmlJavaScriptExpression, public QQmlAbstractBinding { + friend class QQmlAbstractBinding; public: QQmlBinding(const QString &, QObject *, QQmlContext *); QQmlBinding(const QQmlScriptString &, QObject *, QQmlContext *); @@ -72,6 +73,7 @@ public: QQmlBinding(const QString &, QObject *, QQmlContextData *, const QString &url, quint16 lineNumber, quint16 columnNumber); QQmlBinding(const QV4::Value &, QObject *, QQmlContextData *); + ~QQmlBinding(); void setTarget(const QQmlProperty &); void setTarget(QObject *, const QQmlPropertyData &); @@ -94,10 +96,6 @@ public: virtual QString expressionIdentifier(); virtual void expressionChanged(); -protected: - friend class QQmlAbstractBinding; - ~QQmlBinding(); - private: inline bool updatingFlag() const; inline void setUpdatingFlag(bool); diff --git a/src/qml/qml/qqmldata_p.h b/src/qml/qml/qqmldata_p.h index 5cef128e7e..93c7bc6df0 100644 --- a/src/qml/qml/qqmldata_p.h +++ b/src/qml/qml/qqmldata_p.h @@ -73,15 +73,7 @@ class QQmlNotifierEndpoint; class Q_QML_PRIVATE_EXPORT QQmlData : public QAbstractDeclarativeData { public: - QQmlData() - : ownedByQml1(false), ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), - hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false), - hasVMEMetaObject(false), parentFrozen(false), bindingBitsSize(0), bindingBits(0), notifyList(0), context(0), outerContext(0), - bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0), - lineNumber(0), columnNumber(0), jsEngineId(0), compiledData(0), deferredData(0), - propertyCache(0), guards(0), extendedData(0) { - init(); - } + QQmlData(); static inline void init() { static bool initialized = false; diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 768c969373..45f37ead93 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -657,6 +657,17 @@ void QQmlPrivate::qdeclarativeelement_destructor(QObject *o) } } +QQmlData::QQmlData() + : ownedByQml1(false), ownMemory(true), ownContext(false), indestructible(true), explicitIndestructibleSet(false), + hasTaintedV4Object(false), isQueuedForDeletion(false), rootObjectInCreation(false), + hasVMEMetaObject(false), parentFrozen(false), bindingBitsSize(0), bindingBits(0), notifyList(0), context(0), outerContext(0), + bindings(0), signalHandlers(0), nextContextObject(0), prevContextObject(0), + lineNumber(0), columnNumber(0), jsEngineId(0), compiledData(0), deferredData(0), + propertyCache(0), guards(0), extendedData(0) +{ + init(); +} + void QQmlData::destroyed(QAbstractDeclarativeData *d, QObject *o) { QQmlData *ddata = static_cast<QQmlData *>(d); @@ -815,14 +826,12 @@ void QQmlData::flushPendingBindingImpl(int coreIndex) // Find the binding QQmlAbstractBinding *b = bindings; - while (b && *b->m_mePtr && b->targetPropertyIndex() != coreIndex) + while (b && b->targetPropertyIndex() != coreIndex) b = b->nextBinding(); - if (b && b->targetPropertyIndex() == coreIndex) { - b->clear(); + if (b && b->targetPropertyIndex() == coreIndex) b->setEnabled(true, QQmlPropertyPrivate::BypassInterceptor | QQmlPropertyPrivate::DontRemoveBinding); - } } bool QQmlEnginePrivate::baseModulesUninitialized = true; @@ -1642,12 +1651,11 @@ void QQmlData::destroyed(QObject *object) QQmlAbstractBinding *binding = bindings; while (binding) { - QQmlAbstractBinding *next = binding->nextBinding(); binding->setAddedToObject(false); - binding->setNextBinding(0); - binding->destroy(); - binding = next; + binding = binding->nextBinding(); } + if (bindings && !bindings->ref.deref()) + delete bindings; if (compiledData) { compiledData->release(); diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h index ce6b814d90..1021c30f4a 100644 --- a/src/qml/qml/qqmlengine_p.h +++ b/src/qml/qml/qqmlengine_p.h @@ -85,7 +85,6 @@ class QQmlImportDatabase; class QNetworkReply; class QNetworkAccessManager; class QQmlNetworkAccessManagerFactory; -class QQmlAbstractBinding; class QQmlTypeNameCache; class QQmlComponentAttached; class QQmlCleanup; diff --git a/src/qml/qml/qqmlobjectcreator.cpp b/src/qml/qml/qqmlobjectcreator.cpp index 02618549d3..3e13e4247b 100644 --- a/src/qml/qml/qqmlobjectcreator.cpp +++ b/src/qml/qml/qqmlobjectcreator.cpp @@ -129,11 +129,6 @@ QQmlObjectCreator::~QQmlObjectCreator() { QQmlObjectCreatorRecursionWatcher watcher(this); } - for (int i = 0; i < sharedState->allCreatedBindings.count(); ++i) { - QQmlAbstractBinding *b = sharedState->allCreatedBindings.at(i); - if (b) - b->m_mePtr = 0; - } for (int i = 0; i < sharedState->allParserStatusCallbacks.count(); ++i) { QQmlParserStatus *ps = sharedState->allParserStatusCallbacks.at(i); if (ps) @@ -655,7 +650,7 @@ void QQmlObjectCreator::setupBindings(const QBitArray &bindingsToSkip) QQmlAbstractBinding *binding = QQmlPropertyPrivate::binding(_bindingTarget, _valueTypeProperty->coreIndex); if (binding && !binding->isValueTypeProxy()) { - QQmlPropertyPrivate::removeBinding(_bindingTarget, _valueTypeProperty->coreIndex, QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::removeBinding(_bindingTarget, _valueTypeProperty->coreIndex); } else if (binding) { QQmlValueTypeProxyBinding *proxy = static_cast<QQmlValueTypeProxyBinding *>(binding); @@ -789,7 +784,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) - QQmlPropertyPrivate::removeBinding(_bindingTarget, property->coreIndex, QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::removeBinding(_bindingTarget, property->coreIndex); if (binding->type == QV4::CompiledData::Binding::Type_Script) { QV4::Function *runtimeFunction = compiledData->compilationUnit->runtimeFunctions[binding->value.compiledScriptIndex]; @@ -817,13 +812,12 @@ bool QQmlObjectCreator::setPropertyBinding(const QQmlPropertyData *property, con if (_valueTypeProperty) targetCorePropertyData = QQmlPropertyPrivate::saveValueType(*_valueTypeProperty, _qobject->metaObject(), property->coreIndex, engine); - sharedState->allCreatedBindings.push(qmlBinding); - qmlBinding->m_mePtr = &sharedState->allCreatedBindings.top(); + sharedState->allCreatedBindings.push(QQmlAbstractBinding::Ptr(qmlBinding)); qmlBinding->setTarget(_bindingTarget, targetCorePropertyData); if (targetCorePropertyData.isAlias()) { - QQmlPropertyPrivate::setBinding(qmlBinding, QQmlPropertyPrivate::DontEnable|QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::setBinding(qmlBinding, QQmlPropertyPrivate::DontEnable); } else { qmlBinding->addToObject(); @@ -1167,10 +1161,11 @@ QQmlContextData *QQmlObjectCreator::finalize(QQmlInstantiationInterrupt &interru ActiveOCRestorer ocRestorer(this, QQmlEnginePrivate::get(engine)); while (!sharedState->allCreatedBindings.isEmpty()) { - QQmlAbstractBinding *b = sharedState->allCreatedBindings.pop(); - if (!b) + QQmlAbstractBinding::Ptr b = sharedState->allCreatedBindings.pop(); + Q_ASSERT(b); + // skip, if b is not added to an object + if (!b->isAddedToObject()) continue; - b->m_mePtr = 0; QQmlData *data = QQmlData::get(b->targetObject()); Q_ASSERT(data); data->clearPendingBindingBit(b->targetPropertyIndex()); diff --git a/src/qml/qml/qqmlobjectcreator_p.h b/src/qml/qml/qqmlobjectcreator_p.h index 60fefe494f..c88c15b525 100644 --- a/src/qml/qml/qqmlobjectcreator_p.h +++ b/src/qml/qml/qqmlobjectcreator_p.h @@ -55,7 +55,7 @@ struct QQmlObjectCreatorSharedState : public QSharedData { QQmlContextData *rootContext; QQmlContextData *creationContext; - QFiniteStack<QQmlAbstractBinding*> allCreatedBindings; + QFiniteStack<QQmlAbstractBinding::Ptr> allCreatedBindings; QFiniteStack<QQmlParserStatus*> allParserStatusCallbacks; QFiniteStack<QPointer<QObject> > allCreatedObjects; QV4::Value *allJavaScriptObjects; // pointer to vector on JS stack to reference JS wrappers during creation phase. diff --git a/src/qml/qml/qqmlproperty.cpp b/src/qml/qml/qqmlproperty.cpp index e4b2743b9b..0181d138af 100644 --- a/src/qml/qml/qqmlproperty.cpp +++ b/src/qml/qml/qqmlproperty.cpp @@ -725,13 +725,14 @@ QQmlPropertyPrivate::setBinding(const QQmlProperty &that, QQmlAbstractBinding *n } if (!that.d || !that.isProperty() || !that.d->object) { - newBinding->destroy(); + if (!newBinding->ref) + delete newBinding; return; } setBinding(newBinding); } -static QQmlAbstractBinding *removeOldBinding(QObject *object, int index, QQmlPropertyPrivate::BindingFlags flags) +static void removeOldBinding(QObject *object, int index, QQmlPropertyPrivate::BindingFlags flags = QQmlPropertyPrivate::None) { int coreIndex; int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(index, &coreIndex); @@ -739,55 +740,49 @@ static QQmlAbstractBinding *removeOldBinding(QObject *object, int index, QQmlPro QQmlData *data = QQmlData::get(object, false); if (!data || !data->hasBindingBit(coreIndex)) - return 0; + return; - QQmlAbstractBinding *oldBinding = data->bindings; + QQmlAbstractBinding::Ptr oldBinding; + oldBinding = data->bindings; while (oldBinding && oldBinding->targetPropertyIndex() != coreIndex) oldBinding = oldBinding->nextBinding(); if (!oldBinding) - return 0; + return; if (valueTypeIndex != -1 && oldBinding->isValueTypeProxy()) - oldBinding = static_cast<QQmlValueTypeProxyBinding *>(oldBinding)->binding(index); + oldBinding = static_cast<QQmlValueTypeProxyBinding *>(oldBinding.data())->binding(index); if (!oldBinding) - return 0; + return; - oldBinding->removeFromObject(); if (!(flags & QQmlPropertyPrivate::DontEnable)) oldBinding->setEnabled(false, 0); - - if (flags & QQmlPropertyPrivate::DestroyOldBinding) { - oldBinding->destroy(); - return 0; - } - - return oldBinding; + oldBinding->removeFromObject(); } -QQmlAbstractBinding *QQmlPropertyPrivate::removeBinding(QQmlAbstractBinding *b, QQmlPropertyPrivate::BindingFlag flags) +void QQmlPropertyPrivate::removeBinding(QQmlAbstractBinding *b) { - return removeBinding(b->targetObject(), b->targetPropertyIndex(), flags); + removeBinding(b->targetObject(), b->targetPropertyIndex()); } -QQmlAbstractBinding *QQmlPropertyPrivate::removeBinding(QObject *o, int index, QQmlPropertyPrivate::BindingFlag flags) +void QQmlPropertyPrivate::removeBinding(QObject *o, int index) { Q_ASSERT(o); QObject *target; int targetIndex; findAliasTarget(o, index, &target, &targetIndex); - return removeOldBinding(target, targetIndex, flags); + removeOldBinding(target, targetIndex); } -QQmlAbstractBinding *QQmlPropertyPrivate::removeBinding(const QQmlProperty &that, BindingFlag flags) +void QQmlPropertyPrivate::removeBinding(const QQmlProperty &that) { if (!that.d || !that.isProperty() || !that.d->object) - return 0; + return; - return removeBinding(that.d->object, that.d->core.encodedIndex(), flags); + removeBinding(that.d->object, that.d->core.encodedIndex()); } QQmlAbstractBinding * @@ -1164,7 +1159,7 @@ QQmlPropertyPrivate::writeValueProperty(QObject *object, { // Remove any existing bindings on this property if (!(flags & DontRemoveBinding) && object) - removeBinding(object, core.encodedIndex(), DestroyOldBinding); + removeBinding(object, core.encodedIndex()); bool rv = false; if (core.isValueTypeVirtual()) { diff --git a/src/qml/qml/qqmlproperty_p.h b/src/qml/qml/qqmlproperty_p.h index d0ffbe80fc..4a8399a9ab 100644 --- a/src/qml/qml/qqmlproperty_p.h +++ b/src/qml/qml/qqmlproperty_p.h @@ -106,16 +106,15 @@ public: enum BindingFlag { None = 0, - DestroyOldBinding = 0x1, - DontEnable = 0x2 + DontEnable = 0x1 }; 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, QQmlPropertyPrivate::BindingFlag flags = None); - static QQmlAbstractBinding *removeBinding(QQmlAbstractBinding *b, BindingFlag flag = None); + static void removeBinding(const QQmlProperty &that); + static void removeBinding(QObject *o, int index); + static void removeBinding(QQmlAbstractBinding *b); static QQmlAbstractBinding *binding(QObject *, int index); static QQmlPropertyData saveValueType(const QQmlPropertyData &, diff --git a/src/qml/qml/qqmlvaluetypeproxybinding.cpp b/src/qml/qml/qqmlvaluetypeproxybinding.cpp index 0c8dd04910..3bc8493cbb 100644 --- a/src/qml/qml/qqmlvaluetypeproxybinding.cpp +++ b/src/qml/qml/qqmlvaluetypeproxybinding.cpp @@ -45,20 +45,16 @@ QQmlValueTypeProxyBinding::QQmlValueTypeProxyBinding(QObject *o, int index) QQmlValueTypeProxyBinding::~QQmlValueTypeProxyBinding() { - QQmlAbstractBinding *binding = m_bindings; - // This must be identical to the logic in QQmlData::destroyed() + QQmlAbstractBinding *binding = m_bindings.data(); while (binding) { - QQmlAbstractBinding *next = binding->nextBinding(); binding->setAddedToObject(false); - binding->setNextBinding(0); - binding->destroy(); - binding = next; + binding = binding->nextBinding(); } } void QQmlValueTypeProxyBinding::setEnabled(bool e, QQmlPropertyPrivate::WriteFlags flags) { - QQmlAbstractBinding *b = m_bindings; + QQmlAbstractBinding *b = m_bindings.data(); while (b) { b->setEnabled(e, flags); b = b->nextBinding(); @@ -72,7 +68,7 @@ bool QQmlValueTypeProxyBinding::isValueTypeProxy() const QQmlAbstractBinding *QQmlValueTypeProxyBinding::binding(int propertyIndex) { - QQmlAbstractBinding *binding = m_bindings; + QQmlAbstractBinding *binding = m_bindings.data(); while (binding && binding->targetPropertyIndex() != propertyIndex) binding = binding->nextBinding(); @@ -85,23 +81,20 @@ Removes a collection of bindings, corresponding to the set bits in \a mask. */ void QQmlValueTypeProxyBinding::removeBindings(quint32 mask) { - QQmlAbstractBinding *binding = m_bindings; + QQmlAbstractBinding *binding = m_bindings.data(); QQmlAbstractBinding *lastBinding = 0; while (binding) { int valueTypeIndex = QQmlPropertyData::decodeValueTypePropertyIndex(binding->targetPropertyIndex()); if (valueTypeIndex != -1 && (mask & (1 << valueTypeIndex))) { QQmlAbstractBinding *remove = binding; + remove->setAddedToObject(false); binding = remove->nextBinding(); if (lastBinding == 0) m_bindings = remove->nextBinding(); else lastBinding->setNextBinding(remove->nextBinding()); - - remove->setAddedToObject(false); - remove->setNextBinding(0); - remove->destroy(); } else { lastBinding = binding; binding = binding->nextBinding(); diff --git a/src/qml/qml/qqmlvaluetypeproxybinding_p.h b/src/qml/qml/qqmlvaluetypeproxybinding_p.h index 7ddd5c1d93..4afadfc17d 100644 --- a/src/qml/qml/qqmlvaluetypeproxybinding_p.h +++ b/src/qml/qml/qqmlvaluetypeproxybinding_p.h @@ -65,7 +65,7 @@ protected: private: friend class QQmlAbstractBinding; - QQmlAbstractBinding *m_bindings; + Ptr m_bindings; }; QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlvaluetypewrapper.cpp b/src/qml/qml/qqmlvaluetypewrapper.cpp index b4d5faa4cf..8918a76c07 100644 --- a/src/qml/qml/qqmlvaluetypewrapper.cpp +++ b/src/qml/qml/qqmlvaluetypewrapper.cpp @@ -435,11 +435,10 @@ void QQmlValueTypeWrapper::put(Managed *m, String *name, const Value &value) QQmlBinding *newBinding = new QQmlBinding(value, reference->d()->object, context); newBinding->setTarget(reference->d()->object, cacheData); - QQmlPropertyPrivate::setBinding(newBinding, QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::setBinding(newBinding); return; } else { - QQmlPropertyPrivate::removeBinding(reference->d()->object, QQmlPropertyData::encodeValueTypePropertyIndex(reference->d()->property, pd->coreIndex), - QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::removeBinding(reference->d()->object, QQmlPropertyData::encodeValueTypePropertyIndex(reference->d()->property, pd->coreIndex)); } } diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp index 20e3efd008..d617ee18b4 100644 --- a/src/qml/qml/qqmlvmemetaobject.cpp +++ b/src/qml/qml/qqmlvmemetaobject.cpp @@ -875,7 +875,7 @@ int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a) if (flags & QQmlPropertyPrivate::RemoveBindingOnAliasWrite) { QQmlData *targetData = QQmlData::get(target); if (targetData && targetData->hasBindingBit(d->propertyIndex())) - QQmlPropertyPrivate::removeBinding(target, d->propertyIdx, QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::removeBinding(target, d->propertyIdx); } } diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp index 43c583ca84..8b94769772 100644 --- a/src/qml/types/qqmlbind.cpp +++ b/src/qml/types/qqmlbind.cpp @@ -52,8 +52,8 @@ QT_BEGIN_NAMESPACE class QQmlBindPrivate : public QObjectPrivate { public: - QQmlBindPrivate() : componentComplete(true), obj(0), prevBind(0) {} - ~QQmlBindPrivate() { if (prevBind) prevBind->destroy(); } + QQmlBindPrivate() : componentComplete(true), obj(0) {} + ~QQmlBindPrivate() { } QQmlNullableValue<bool> when; bool componentComplete; @@ -61,7 +61,7 @@ public: QString propName; QQmlNullableValue<QVariant> value; QQmlProperty prop; - QQmlAbstractBinding *prevBind; + QQmlAbstractBinding::Ptr prevBind; }; @@ -277,18 +277,17 @@ void QQmlBind::eval() if (!d->when) { //restore any previous binding if (d->prevBind) { - QQmlAbstractBinding *b = QQmlPropertyPrivate::binding(d->prop); - if (b != d->prevBind) - QQmlPropertyPrivate::setBinding(d->prevBind, QQmlPropertyPrivate::DestroyOldBinding); + QQmlAbstractBinding::Ptr p = d->prevBind; d->prevBind = 0; + QQmlPropertyPrivate::setBinding(p.data()); } return; } //save any set binding for restoration - QQmlAbstractBinding *tmp = QQmlPropertyPrivate::removeBinding(d->prop, (d->prevBind ? QQmlPropertyPrivate::DestroyOldBinding : QQmlPropertyPrivate::None)); - if (tmp && !d->prevBind) - d->prevBind = tmp; + if (!d->prevBind) + d->prevBind = QQmlPropertyPrivate::binding(d->prop); + QQmlPropertyPrivate::removeBinding(d->prop); } d->prop.write(d->value.value); |