aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMatthew Vogt <matthew.vogt@nokia.com>2012-07-18 10:16:12 +1000
committerQt by Nokia <qt-info@nokia.com>2012-07-20 05:35:13 +0200
commitfa3dcc0efb2696612bf9db54a7ed4e26a2cf4765 (patch)
tree1a571292334edd0ea10fda559b8c84862a51b58b /src
parent9018c236c73884ea706ac1d04a306467454e6243 (diff)
Update var property to null on object deletion
When a var property contains a pointer to a QObject-derived instance, ensure that object deletion causes the property to be updated. Task-number: QTBUG-26542 Change-Id: I67a59ffd7f09063328d45dc84889add55a5428e4 Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml/qml/qqmlvmemetaobject.cpp53
-rw-r--r--src/qml/qml/qqmlvmemetaobject_p.h10
2 files changed, 52 insertions, 11 deletions
diff --git a/src/qml/qml/qqmlvmemetaobject.cpp b/src/qml/qml/qqmlvmemetaobject.cpp
index 5dcff3ea24..ce574875e3 100644
--- a/src/qml/qml/qqmlvmemetaobject.cpp
+++ b/src/qml/qml/qqmlvmemetaobject.cpp
@@ -57,8 +57,8 @@ Q_DECLARE_METATYPE(QJSValue);
QT_BEGIN_NAMESPACE
-QQmlVMEVariantQObjectPtr::QQmlVMEVariantQObjectPtr()
- : QQmlGuard<QObject>(0), m_target(0), m_index(-1)
+QQmlVMEVariantQObjectPtr::QQmlVMEVariantQObjectPtr(bool isVar)
+ : QQmlGuard<QObject>(0), m_target(0), m_isVar(isVar), m_index(-1)
{
}
@@ -66,10 +66,16 @@ QQmlVMEVariantQObjectPtr::~QQmlVMEVariantQObjectPtr()
{
}
-void QQmlVMEVariantQObjectPtr::objectDestroyed(QObject *)
+void QQmlVMEVariantQObjectPtr::objectDestroyed(QObject *o)
{
- if (m_target && m_index >= 0)
+ if (m_target && m_index >= 0) {
+ if (m_isVar && m_target->varPropertiesInitialized && !m_target->varProperties.IsEmpty()) {
+ // Set the var property to NULL
+ m_target->varProperties->Set(m_index - m_target->firstVarPropertyIndex, v8::Null());
+ }
+
m_target->activate(m_target->object, m_target->methodOffset() + m_index, 0);
+ }
}
void QQmlVMEVariantQObjectPtr::setGuardedValue(QObject *obj, QQmlVMEMetaObject *target, int index)
@@ -336,7 +342,7 @@ void QQmlVMEVariant::setValue(QObject *v, QQmlVMEMetaObject *target, int index)
if (type != QMetaType::QObjectStar) {
cleanup();
type = QMetaType::QObjectStar;
- new (dataPtr()) QQmlVMEVariantQObjectPtr;
+ new (dataPtr()) QQmlVMEVariantQObjectPtr(false);
}
reinterpret_cast<QQmlVMEVariantQObjectPtr*>(dataPtr())->setGuardedValue(v, target, index);
}
@@ -602,6 +608,8 @@ QQmlVMEMetaObject::~QQmlVMEMetaObject()
if (metaData->varPropertyCount)
qPersistentDispose(varProperties); // if not weak, will not have been cleaned up by the callback.
+
+ qDeleteAll(varObjectGuards);
}
int QQmlVMEMetaObject::metaCall(QMetaObject::Call c, int _id, void **a)
@@ -1036,15 +1044,30 @@ void QQmlVMEMetaObject::writeVarProperty(int id, v8::Handle<v8::Value> value)
}
}
- // And, if the new value is a scarce resource, we need to ensure that it does not get
- // automatically released by the engine until no other references to it exist.
+ QObject *valueObject = 0;
+ QQmlVMEVariantQObjectPtr *guard = getQObjectGuardForProperty(id);
+
if (value->IsObject()) {
- QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(value));
- if (r) {
+ // And, if the new value is a scarce resource, we need to ensure that it does not get
+ // automatically released by the engine until no other references to it exist.
+ if (QV8VariantResource *r = v8_resource_cast<QV8VariantResource>(v8::Handle<v8::Object>::Cast(value))) {
r->addVmePropertyReference();
+ } else if (QV8QObjectResource *r = v8_resource_cast<QV8QObjectResource>(v8::Handle<v8::Object>::Cast(value))) {
+ // We need to track this QObject to signal its deletion
+ valueObject = r->object;
+
+ // Do we already have a QObject guard for this property?
+ if (valueObject && !guard) {
+ guard = new QQmlVMEVariantQObjectPtr(true);
+ varObjectGuards.append(guard);
+ }
}
}
+ if (guard) {
+ guard->setGuardedValue(valueObject, this, id);
+ }
+
// Write the value and emit change signal as appropriate.
varProperties->Set(id - firstVarPropertyIndex, value);
activate(object, methodOffset() + id, 0);
@@ -1367,4 +1390,16 @@ QQmlVMEMetaObject *QQmlVMEMetaObject::getForSignal(QObject *o, int coreIndex)
return vme;
}
+QQmlVMEVariantQObjectPtr *QQmlVMEMetaObject::getQObjectGuardForProperty(int index) const
+{
+ QList<QQmlVMEVariantQObjectPtr *>::ConstIterator it = varObjectGuards.constBegin(), end = varObjectGuards.constEnd();
+ for ( ; it != end; ++it) {
+ if ((*it)->m_index == index) {
+ return *it;
+ }
+ }
+
+ return 0;
+}
+
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlvmemetaobject_p.h b/src/qml/qml/qqmlvmemetaobject_p.h
index 7a01b70b06..5751989b0c 100644
--- a/src/qml/qml/qqmlvmemetaobject_p.h
+++ b/src/qml/qml/qqmlvmemetaobject_p.h
@@ -141,13 +141,15 @@ class QQmlVMEMetaObject;
class QQmlVMEVariantQObjectPtr : public QQmlGuard<QObject>
{
public:
- inline QQmlVMEVariantQObjectPtr();
+ inline QQmlVMEVariantQObjectPtr(bool isVar);
inline ~QQmlVMEVariantQObjectPtr();
+
inline void objectDestroyed(QObject *);
inline void setGuardedValue(QObject *obj, QQmlVMEMetaObject *target, int index);
QQmlVMEMetaObject *m_target;
- int m_index;
+ unsigned m_isVar : 1;
+ int m_index : 31;
};
class QV8QObjectWrapper;
@@ -238,6 +240,10 @@ public:
void activate(QObject *, int, void **);
+ QList<QQmlVMEVariantQObjectPtr *> varObjectGuards;
+
+ QQmlVMEVariantQObjectPtr *getQObjectGuardForProperty(int) const;
+
friend class QV8GCCallback;
friend class QV8QObjectWrapper;
};