diff options
author | Lars Knoll <lars.knoll@theqtcompany.com> | 2015-04-21 16:42:56 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@theqtcompany.com> | 2015-06-10 07:55:36 +0000 |
commit | 37d02d62d8d14fdaa0884f96f7840661413a95c2 (patch) | |
tree | 8e3f3dd9dafd574b99ca686e657d7e73f8f7eef5 /src | |
parent | eb7db5934b453eea2946ed7ae9a188c44467cf23 (diff) |
Make bindings refcounted
Refcounting our bindings greatly simplifies our memory management
of the objects and ensures we safely clean them all up. In addition,
it allows us to remove the m_mePtr and weak reference handling from
QQmlAbstractBinding as we can safely handle this through the same
mechanism.
Change-Id: If23ebc8be276096146952b0008b62018f5d57faf
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
Diffstat (limited to 'src')
24 files changed, 222 insertions, 313 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); diff --git a/src/quick/items/qquickstateoperations.cpp b/src/quick/items/qquickstateoperations.cpp index 3ea1c0ecf1..15f8eeab7b 100644 --- a/src/quick/items/qquickstateoperations.cpp +++ b/src/quick/items/qquickstateoperations.cpp @@ -358,7 +358,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() newBinding->setTarget(property); QQuickStateAction xa; xa.property = property; - xa.toBinding = QQmlAbstractBinding::getPointer(newBinding); + xa.toBinding = newBinding; xa.fromValue = xa.property.read(); xa.deletableToBinding = true; actions << xa; @@ -377,7 +377,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() newBinding->setTarget(property); QQuickStateAction ya; ya.property = property; - ya.toBinding = QQmlAbstractBinding::getPointer(newBinding); + ya.toBinding = newBinding; ya.fromValue = ya.property.read(); ya.deletableToBinding = true; actions << ya; @@ -396,7 +396,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() newBinding->setTarget(property); QQuickStateAction sa; sa.property = property; - sa.toBinding = QQmlAbstractBinding::getPointer(newBinding); + sa.toBinding = newBinding; sa.fromValue = sa.property.read(); sa.deletableToBinding = true; actions << sa; @@ -415,7 +415,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() newBinding->setTarget(property); QQuickStateAction ra; ra.property = property; - ra.toBinding = QQmlAbstractBinding::getPointer(newBinding); + ra.toBinding = newBinding; ra.fromValue = ra.property.read(); ra.deletableToBinding = true; actions << ra; @@ -434,7 +434,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() newBinding->setTarget(property); QQuickStateAction wa; wa.property = property; - wa.toBinding = QQmlAbstractBinding::getPointer(newBinding); + wa.toBinding = newBinding; wa.fromValue = wa.property.read(); wa.deletableToBinding = true; actions << wa; @@ -453,7 +453,7 @@ QQuickStateOperation::ActionList QQuickParentChange::actions() newBinding->setTarget(property); QQuickStateAction ha; ha.property = property; - ha.toBinding = QQmlAbstractBinding::getPointer(newBinding); + ha.toBinding = newBinding; ha.fromValue = ha.property.read(); ha.deletableToBinding = true; actions << ha; @@ -765,12 +765,7 @@ class QQuickAnchorChangesPrivate : public QQuickStateOperationPrivate { public: QQuickAnchorChangesPrivate() - : target(0), anchorSet(new QQuickAnchorSet), - leftBinding(0), rightBinding(0), hCenterBinding(0), - topBinding(0), bottomBinding(0), vCenterBinding(0), baselineBinding(0), - origLeftBinding(0), origRightBinding(0), origHCenterBinding(0), - origTopBinding(0), origBottomBinding(0), origVCenterBinding(0), - origBaselineBinding(0) + : target(0), anchorSet(new QQuickAnchorSet) { } @@ -779,21 +774,21 @@ public: QQuickItem *target; QQuickAnchorSet *anchorSet; - QQmlBinding *leftBinding; - QQmlBinding *rightBinding; - QQmlBinding *hCenterBinding; - QQmlBinding *topBinding; - QQmlBinding *bottomBinding; - QQmlBinding *vCenterBinding; - QQmlBinding *baselineBinding; - - QQmlAbstractBinding *origLeftBinding; - QQmlAbstractBinding *origRightBinding; - QQmlAbstractBinding *origHCenterBinding; - QQmlAbstractBinding *origTopBinding; - QQmlAbstractBinding *origBottomBinding; - QQmlAbstractBinding *origVCenterBinding; - QQmlAbstractBinding *origBaselineBinding; + QExplicitlySharedDataPointer<QQmlBinding> leftBinding; + QExplicitlySharedDataPointer<QQmlBinding> rightBinding; + QExplicitlySharedDataPointer<QQmlBinding> hCenterBinding; + QExplicitlySharedDataPointer<QQmlBinding> topBinding; + QExplicitlySharedDataPointer<QQmlBinding> bottomBinding; + QExplicitlySharedDataPointer<QQmlBinding> vCenterBinding; + QExplicitlySharedDataPointer<QQmlBinding> baselineBinding; + + QQmlAbstractBinding::Ptr origLeftBinding; + QQmlAbstractBinding::Ptr origRightBinding; + QQmlAbstractBinding::Ptr origHCenterBinding; + QQmlAbstractBinding::Ptr origTopBinding; + QQmlAbstractBinding::Ptr origBottomBinding; + QQmlAbstractBinding::Ptr origVCenterBinding; + QQmlAbstractBinding::Ptr origBaselineBinding; QQuickAnchorLine rewindLeft; QQuickAnchorLine rewindRight; @@ -831,8 +826,6 @@ public: qreal origX; qreal origY; - QList<QQmlAbstractBinding*> oldBindings; - QQmlProperty leftProp; QQmlProperty rightProp; QQmlProperty hCenterProp; @@ -849,29 +842,6 @@ QQuickAnchorChanges::QQuickAnchorChanges(QObject *parent) QQuickAnchorChanges::~QQuickAnchorChanges() { - /* - if the anchorchanges is active at destruction, any non-active orig - bindings need to be destroyed - - the basic logic is that if both e.g. left and origLeft are present, - then we are active (otherwise left would have been destroyed), and - left is in use and origLeft needs to be cleaned up. - */ - Q_D(QQuickAnchorChanges); - if (d->leftBinding && d->origLeftBinding) - d->origLeftBinding->destroy(); - if (d->rightBinding && d->origRightBinding) - d->origRightBinding->destroy(); - if (d->hCenterBinding && d->origHCenterBinding) - d->origHCenterBinding->destroy(); - if (d->topBinding && d->origTopBinding) - d->origTopBinding->destroy(); - if (d->bottomBinding && d->origBottomBinding) - d->origBottomBinding->destroy(); - if (d->vCenterBinding && d->origVCenterBinding) - d->origVCenterBinding->destroy(); - if (d->baselineBinding && d->origBaselineBinding) - d->origBaselineBinding->destroy(); } QQuickAnchorChanges::ActionList QQuickAnchorChanges::actions() @@ -969,6 +939,8 @@ void QQuickAnchorChanges::setObject(QQuickItem *target) void QQuickAnchorChanges::execute(Reason reason) { + Q_UNUSED(reason); + Q_D(QQuickAnchorChanges); if (!d->target) return; @@ -978,47 +950,37 @@ void QQuickAnchorChanges::execute(Reason reason) if (d->applyOrigLeft) { if (!d->origLeftBinding) targetPrivate->anchors()->resetLeft(); - QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding); + QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding.data()); } if (d->applyOrigRight) { if (!d->origRightBinding) targetPrivate->anchors()->resetRight(); - QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding); + QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding.data()); } if (d->applyOrigHCenter) { if (!d->origHCenterBinding) targetPrivate->anchors()->resetHorizontalCenter(); - QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding); + QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding.data()); } if (d->applyOrigTop) { if (!d->origTopBinding) targetPrivate->anchors()->resetTop(); - QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding); + QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding.data()); } if (d->applyOrigBottom) { if (!d->origBottomBinding) targetPrivate->anchors()->resetBottom(); - QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding); + QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding.data()); } if (d->applyOrigVCenter) { if (!d->origVCenterBinding) targetPrivate->anchors()->resetVerticalCenter(); - QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding); + QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding.data()); } if (d->applyOrigBaseline) { if (!d->origBaselineBinding) targetPrivate->anchors()->resetBaseline(); - QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding); - } - - //destroy old bindings - if (reason == ActualChange) { - for (int i = 0; i < d->oldBindings.size(); ++i) { - QQmlAbstractBinding *binding = d->oldBindings.at(i); - if (binding) - binding->destroy(); - } - d->oldBindings.clear(); + QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding.data()); } //reset any anchors that have been specified as "undefined" @@ -1053,19 +1015,19 @@ void QQuickAnchorChanges::execute(Reason reason) //set any anchors that have been specified if (d->leftBinding) - QQmlPropertyPrivate::setBinding(d->leftBinding); + QQmlPropertyPrivate::setBinding(d->leftBinding.data()); if (d->rightBinding) - QQmlPropertyPrivate::setBinding(d->rightBinding); + QQmlPropertyPrivate::setBinding(d->rightBinding.data()); if (d->hCenterBinding) - QQmlPropertyPrivate::setBinding(d->hCenterBinding); + QQmlPropertyPrivate::setBinding(d->hCenterBinding.data()); if (d->topBinding) - QQmlPropertyPrivate::setBinding(d->topBinding); + QQmlPropertyPrivate::setBinding(d->topBinding.data()); if (d->bottomBinding) - QQmlPropertyPrivate::setBinding(d->bottomBinding); + QQmlPropertyPrivate::setBinding(d->bottomBinding.data()); if (d->vCenterBinding) - QQmlPropertyPrivate::setBinding(d->vCenterBinding); + QQmlPropertyPrivate::setBinding(d->vCenterBinding.data()); if (d->baselineBinding) - QQmlPropertyPrivate::setBinding(d->baselineBinding); + QQmlPropertyPrivate::setBinding(d->baselineBinding.data()); } bool QQuickAnchorChanges::isReversable() @@ -1083,69 +1045,62 @@ void QQuickAnchorChanges::reverse(Reason reason) //reset any anchors set by the state if (d->leftBinding) { targetPrivate->anchors()->resetLeft(); - QQmlPropertyPrivate::removeBinding(d->leftBinding); - if (reason == ActualChange) { - d->leftBinding->destroy(); d->leftBinding = 0; - } + QQmlPropertyPrivate::removeBinding(d->leftBinding.data()); + if (reason == ActualChange) + d->leftBinding = 0; } if (d->rightBinding) { targetPrivate->anchors()->resetRight(); - QQmlPropertyPrivate::removeBinding(d->rightBinding); - if (reason == ActualChange) { - d->rightBinding->destroy(); d->rightBinding = 0; - } + QQmlPropertyPrivate::removeBinding(d->rightBinding.data()); + if (reason == ActualChange) + d->rightBinding = 0; } if (d->hCenterBinding) { targetPrivate->anchors()->resetHorizontalCenter(); - QQmlPropertyPrivate::removeBinding(d->hCenterBinding); - if (reason == ActualChange) { - d->hCenterBinding->destroy(); d->hCenterBinding = 0; - } + QQmlPropertyPrivate::removeBinding(d->hCenterBinding.data()); + if (reason == ActualChange) + d->hCenterBinding = 0; } if (d->topBinding) { targetPrivate->anchors()->resetTop(); - QQmlPropertyPrivate::removeBinding(d->topBinding); - if (reason == ActualChange) { - d->topBinding->destroy(); d->topBinding = 0; - } + QQmlPropertyPrivate::removeBinding(d->topBinding.data()); + if (reason == ActualChange) + d->topBinding = 0; } if (d->bottomBinding) { targetPrivate->anchors()->resetBottom(); - QQmlPropertyPrivate::removeBinding(d->bottomBinding); - if (reason == ActualChange) { - d->bottomBinding->destroy(); d->bottomBinding = 0; - } + QQmlPropertyPrivate::removeBinding(d->bottomBinding.data()); + if (reason == ActualChange) + d->bottomBinding = 0; } if (d->vCenterBinding) { targetPrivate->anchors()->resetVerticalCenter(); - QQmlPropertyPrivate::removeBinding(d->vCenterBinding); - if (reason == ActualChange) { - d->vCenterBinding->destroy(); d->vCenterBinding = 0; - } + QQmlPropertyPrivate::removeBinding(d->vCenterBinding.data()); + if (reason == ActualChange) + d->vCenterBinding = 0; } if (d->baselineBinding) { targetPrivate->anchors()->resetBaseline(); - QQmlPropertyPrivate::removeBinding(d->baselineBinding); - if (reason == ActualChange) { - d->baselineBinding->destroy(); d->baselineBinding = 0; - } + QQmlPropertyPrivate::removeBinding(d->baselineBinding.data()); + if (reason == ActualChange) + d->baselineBinding = 0; } //restore previous anchors if (d->origLeftBinding) - QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding); + QQmlPropertyPrivate::setBinding(d->leftProp, d->origLeftBinding.data()); if (d->origRightBinding) - QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding); + QQmlPropertyPrivate::setBinding(d->rightProp, d->origRightBinding.data()); if (d->origHCenterBinding) - QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding); + QQmlPropertyPrivate::setBinding(d->hCenterProp, d->origHCenterBinding.data()); if (d->origTopBinding) - QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding); + QQmlPropertyPrivate::setBinding(d->topProp, d->origTopBinding.data()); if (d->origBottomBinding) - QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding); + QQmlPropertyPrivate::setBinding(d->bottomProp, d->origBottomBinding.data()); if (d->origVCenterBinding) - QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding); + QQmlPropertyPrivate::setBinding(d->vCenterProp, d->origVCenterBinding.data()); if (d->origBaselineBinding) - QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding); + QQmlPropertyPrivate::setBinding(d->baselineProp, d->origBaselineBinding.data()); //restore any absolute geometry changed by the state's anchors QQuickAnchors::Anchors stateVAnchors = d->anchorSet->d_func()->usedAnchors & QQuickAnchors::Vertical_Mask; @@ -1289,10 +1244,6 @@ void QQuickAnchorChanges::copyOriginals(QQuickStateActionEvent *other) d->origX = acp->origX; d->origY = acp->origY; - d->oldBindings.clear(); - d->oldBindings << acp->leftBinding << acp->rightBinding << acp->hCenterBinding - << acp->topBinding << acp->bottomBinding << acp->vCenterBinding << acp->baselineBinding; - //clear old values from other //### could this be generalized for all QQuickStateActionEvents, and called after copyOriginals? acp->leftBinding = 0; diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 707323f2e2..bb8b5250a0 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -464,10 +464,10 @@ QQuickPropertyChanges::ActionList QQuickPropertyChanges::actions() // XXX TODO: add a static QQmlJavaScriptExpression::evaluate(QString) // so that we can avoid creating then destroying the binding in this case. a.toValue = newBinding->evaluate(); - newBinding->destroy(); + delete newBinding; } else { newBinding->setTarget(prop); - a.toBinding = QQmlAbstractBinding::getPointer(newBinding); + a.toBinding = newBinding; a.deletableToBinding = true; } @@ -558,7 +558,7 @@ void QQuickPropertyChanges::changeValue(const QString &name, const QVariant &val if (entry.name == name) { expressionIterator.remove(); if (state() && state()->isStateActive()) { - QQmlPropertyPrivate::removeBinding(d->property(name), QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::removeBinding(d->property(name)); d->property(name).write(value); } @@ -656,10 +656,10 @@ void QQuickPropertyChanges::changeExpression(const QString &name, const QString // XXX TODO: add a static QQmlJavaScriptExpression::evaluate(QString) // so that we can avoid creating then destroying the binding in this case. action.toValue = newBinding->evaluate(); - newBinding->destroy(); + delete newBinding; } else { newBinding->setTarget(action.property); - action.toBinding = QQmlAbstractBinding::getPointer(newBinding); + action.toBinding = newBinding; action.deletableToBinding = true; state()->addEntryToRevertList(action); diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp index 6c57bdc171..c018399396 100644 --- a/src/quick/util/qquickstate.cpp +++ b/src/quick/util/qquickstate.cpp @@ -157,11 +157,6 @@ QQuickState::~QQuickState() Q_D(QQuickState); if (d->group) d->group->removeState(this); - - foreach (const QQuickSimpleAction &action, d->revertList) { - if (action.binding()) - action.binding()->destroy(); - } } /*! @@ -362,7 +357,6 @@ void QQuickStateAction::deleteFromBinding() { if (fromBinding) { QQmlPropertyPrivate::removeBinding(property); - fromBinding->destroy(); fromBinding = 0; } } @@ -413,9 +407,6 @@ bool QQuickState::changeBindingInRevertList(QObject *target, const QString &name while (revertListIterator.hasNext()) { QQuickSimpleAction &simpleAction = revertListIterator.next(); if (simpleAction.specifiedObject() == target && simpleAction.specifiedProperty() == name) { - if (simpleAction.binding()) - simpleAction.binding()->destroy(); - simpleAction.setBinding(binding); return true; } @@ -435,7 +426,7 @@ bool QQuickState::removeEntryFromRevertList(QObject *target, const QString &name while (revertListIterator.hasNext()) { QQuickSimpleAction &simpleAction = revertListIterator.next(); if (simpleAction.property().object() == target && simpleAction.property().name() == name) { - QQmlPropertyPrivate::removeBinding(simpleAction.property(), QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::removeBinding(simpleAction.property()); simpleAction.property().write(simpleAction.value()); if (simpleAction.binding()) @@ -469,7 +460,7 @@ void QQuickState::removeAllEntriesFromRevertList(QObject *target) while (revertListIterator.hasNext()) { QQuickSimpleAction &simpleAction = revertListIterator.next(); if (simpleAction.property().object() == target) { - QQmlPropertyPrivate::removeBinding(simpleAction.property(), QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::removeBinding(simpleAction.property()); simpleAction.property().write(simpleAction.value()); if (simpleAction.binding()) @@ -493,7 +484,7 @@ void QQuickState::addEntriesToRevertList(const QList<QQuickStateAction> &actionL const QQuickStateAction &action = actionListIterator.next(); QQuickSimpleAction simpleAction(action); action.property.write(action.toValue); - if (!action.toBinding.isNull()) + if (action.toBinding) QQmlPropertyPrivate::setBinding(action.toBinding.data()); simpleActionList.append(simpleAction); @@ -608,7 +599,7 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert) for (int jj = 0; jj < d->revertList.count(); ++jj) { if (d->revertList.at(jj).property() == action.property) { found = true; - if (d->revertList.at(jj).binding() != action.fromBinding) { + if (d->revertList.at(jj).binding() != action.fromBinding.data()) { action.deleteFromBinding(); } break; @@ -652,13 +643,13 @@ void QQuickState::apply(QQuickTransition *trans, QQuickState *revert) } if (!found) { QVariant cur = d->revertList.at(ii).property().read(); - QQmlPropertyPrivate::removeBinding(d->revertList.at(ii).property(), QQmlPropertyPrivate::DestroyOldBinding); + QQmlPropertyPrivate::removeBinding(d->revertList.at(ii).property()); QQuickStateAction a; a.property = d->revertList.at(ii).property(); a.fromValue = cur; a.toValue = d->revertList.at(ii).value(); - a.toBinding = QQmlAbstractBinding::getPointer(d->revertList.at(ii).binding()); + a.toBinding = d->revertList.at(ii).binding(); a.specifiedObject = d->revertList.at(ii).specifiedObject(); a.specifiedProperty = d->revertList.at(ii).specifiedProperty(); a.event = d->revertList.at(ii).event(); diff --git a/src/quick/util/qquickstate_p.h b/src/quick/util/qquickstate_p.h index 0c774635d8..26069caa34 100644 --- a/src/quick/util/qquickstate_p.h +++ b/src/quick/util/qquickstate_p.h @@ -39,13 +39,14 @@ #include <QtCore/qobject.h> #include <QtCore/qsharedpointer.h> #include <private/qtquickglobal_p.h> +#include <private/qqmlabstractbinding_p.h> QT_BEGIN_NAMESPACE class QQuickStateActionEvent; -class QQmlAbstractBinding; class QQmlBinding; class QQmlExpression; + class QQuickStateAction { public: @@ -63,8 +64,8 @@ public: QVariant fromValue; QVariant toValue; - QQmlAbstractBinding *fromBinding; - QWeakPointer<QQmlAbstractBinding> toBinding; + QQmlAbstractBinding::Ptr fromBinding; + QQmlAbstractBinding::Ptr toBinding; QQuickStateActionEvent *event; //strictly for matching diff --git a/src/quick/util/qquickstate_p_p.h b/src/quick/util/qquickstate_p_p.h index fc589f0d2d..e6ecb424e5 100644 --- a/src/quick/util/qquickstate_p_p.h +++ b/src/quick/util/qquickstate_p_p.h @@ -71,7 +71,7 @@ public: if (state == StartState) { m_value = a.fromValue; if (QQmlPropertyPrivate::binding(m_property)) { - m_binding = QQmlAbstractBinding::getPointer(QQmlPropertyPrivate::binding(m_property)); + m_binding = QQmlPropertyPrivate::binding(m_property); } m_reverseEvent = true; } else { @@ -88,7 +88,7 @@ public: QQuickSimpleAction(const QQuickSimpleAction &other) : m_property(other.m_property), m_value(other.m_value), - m_binding(QQmlAbstractBinding::getPointer(other.binding())), + m_binding(other.binding()), m_specifiedObject(other.m_specifiedObject), m_specifiedProperty(other.m_specifiedProperty), m_event(other.m_event), @@ -100,7 +100,7 @@ public: { m_property = other.m_property; m_value = other.m_value; - m_binding = QQmlAbstractBinding::getPointer(other.binding()); + m_binding = other.binding(); m_specifiedObject = other.m_specifiedObject; m_specifiedProperty = other.m_specifiedProperty; m_event = other.m_event; @@ -131,7 +131,7 @@ public: void setBinding(QQmlAbstractBinding *binding) { - m_binding = QQmlAbstractBinding::getPointer(binding); + m_binding = binding; } QQmlAbstractBinding *binding() const @@ -162,7 +162,7 @@ public: private: QQmlProperty m_property; QVariant m_value; - QQmlAbstractBinding::Pointer m_binding; + QQmlAbstractBinding::Ptr m_binding; QObject *m_specifiedObject; QString m_specifiedProperty; QQuickStateActionEvent *m_event; diff --git a/src/quick/util/qquicktransitionmanager.cpp b/src/quick/util/qquicktransitionmanager.cpp index ac57ac20a4..14480ac1bf 100644 --- a/src/quick/util/qquicktransitionmanager.cpp +++ b/src/quick/util/qquicktransitionmanager.cpp @@ -101,7 +101,7 @@ void QQuickTransitionManager::complete() void QQuickTransitionManagerPrivate::applyBindings() { foreach(const QQuickStateAction &action, bindingsList) { - if (!action.toBinding.isNull()) { + if (action.toBinding) { QQmlPropertyPrivate::setBinding(action.toBinding.data()); } else if (action.event) { if (action.reverseEvent) @@ -155,7 +155,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list, // Apply all the property and binding changes for (int ii = 0; ii < applyList.size(); ++ii) { const QQuickStateAction &action = applyList.at(ii); - if (!action.toBinding.isNull()) { + if (action.toBinding) { 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); @@ -175,7 +175,7 @@ void QQuickTransitionManager::transition(const QList<QQuickStateAction> &list, continue; } const QQmlProperty &prop = action->property; - if (!action->toBinding.isNull() || !action->toValue.isValid()) { + if (action->toBinding || !action->toValue.isValid()) { action->toValue = prop.read(); } } @@ -269,10 +269,9 @@ void QQuickTransitionManager::cancel() for(int i = 0; i < d->bindingsList.count(); ++i) { QQuickStateAction action = d->bindingsList[i]; - if (!action.toBinding.isNull() && action.deletableToBinding) { + if (action.toBinding && action.deletableToBinding) { QQmlPropertyPrivate::removeBinding(action.property); - action.toBinding.data()->destroy(); - action.toBinding.clear(); + action.toBinding = 0; action.deletableToBinding = false; } else if (action.event) { //### what do we do here? |