aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml/qqmlabstractbinding.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@theqtcompany.com>2015-04-21 16:42:56 +0200
committerSimon Hausmann <simon.hausmann@theqtcompany.com>2015-06-10 07:55:36 +0000
commit37d02d62d8d14fdaa0884f96f7840661413a95c2 (patch)
tree8e3f3dd9dafd574b99ca686e657d7e73f8f7eef5 /src/qml/qml/qqmlabstractbinding.cpp
parenteb7db5934b453eea2946ed7ae9a188c44467cf23 (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/qml/qml/qqmlabstractbinding.cpp')
-rw-r--r--src/qml/qml/qqmlabstractbinding.cpp78
1 files changed, 35 insertions, 43 deletions
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>");