QT_BEGIN_NAMESPACE
+QQmlVMEVariantQObjectPtr::QQmlVMEVariantQObjectPtr()
+ : QQmlGuard<QObject>(0), m_target(0), m_index(-1)
+{
+}
+
+QQmlVMEVariantQObjectPtr::~QQmlVMEVariantQObjectPtr()
+{
+}
+
+void QQmlVMEVariantQObjectPtr::objectDestroyed(QObject *)
+{
+ if (m_target && m_index >= 0)
+ m_target->activate(m_target->object, m_target->methodOffset + m_index, 0);
+}
+
+void QQmlVMEVariantQObjectPtr::setGuardedValue(QObject *obj, QQmlVMEMetaObject *target, int index)
+{
+ m_target = target;
+ m_index = index;
+ setObject(obj);
+}
+
class QQmlVMEVariant
{
public:
inline const QDateTime &asQDateTime();
inline const QJSValue &asQJSValue();
- inline void setValue(QObject *);
+ inline void setValue(QObject *v, QQmlVMEMetaObject *target, int index);
inline void setValue(const QVariant &);
inline void setValue(int);
inline void setValue(bool);
inline void setValue(const QJSValue &);
private:
int type;
- void *data[4]; // Large enough to hold all types
+ void *data[6]; // Large enough to hold all types
inline void cleanup();
};
type == QMetaType::Double) {
type = QVariant::Invalid;
} else if (type == QMetaType::QObjectStar) {
- ((QQmlGuard<QObject>*)dataPtr())->~QQmlGuard<QObject>();
+ ((QQmlVMEVariantQObjectPtr*)dataPtr())->~QQmlVMEVariantQObjectPtr();
type = QVariant::Invalid;
} else if (type == QMetaType::QString) {
((QString *)dataPtr())->~QString();
QObject *QQmlVMEVariant::asQObject()
{
- if (type != QMetaType::QObjectStar)
- setValue((QObject *)0);
+ if (type != QMetaType::QObjectStar)
+ setValue((QObject *)0, 0, -1);
return *(QQmlGuard<QObject> *)(dataPtr());
}
return *(QJSValue *)(dataPtr());
}
-void QQmlVMEVariant::setValue(QObject *v)
+void QQmlVMEVariant::setValue(QObject *v, QQmlVMEMetaObject *target, int index)
{
if (type != QMetaType::QObjectStar) {
cleanup();
type = QMetaType::QObjectStar;
- new (dataPtr()) QQmlGuard<QObject>();
+ new (dataPtr()) QQmlVMEVariantQObjectPtr;
}
- *(QQmlGuard<QObject>*)(dataPtr()) = v;
+ reinterpret_cast<QQmlVMEVariantQObjectPtr*>(dataPtr())->setGuardedValue(v, target, index);
}
void QQmlVMEVariant::setValue(const QVariant &v)
break;
case QMetaType::QObjectStar:
needActivate = *reinterpret_cast<QObject **>(a[0]) != data[id].asQObject();
- data[id].setValue(*reinterpret_cast<QObject **>(a[0]));
+ data[id].setValue(*reinterpret_cast<QObject **>(a[0]), this, id);
break;
case QMetaType::QVariant:
writeProperty(id, *reinterpret_cast<QVariant *>(a[0]));
if (value.userType() == QMetaType::QObjectStar) {
QObject *o = qvariant_cast<QObject *>(value);
needActivate = (data[id].dataType() != QMetaType::QObjectStar || data[id].asQObject() != o);
- data[id].setValue(qvariant_cast<QObject *>(value));
+ data[id].setValue(qvariant_cast<QObject *>(value), this, id);
} else {
needActivate = (data[id].dataType() != qMetaTypeId<QVariant>() ||
data[id].asQVariant().userType() != value.userType() ||
delete o;
}
+
+ {
+ // QTBUG-23451
+ QQmlGuard<QObject> createdQmlObject = 0;
+ QQmlComponent component(&engine, testFileUrl("dynamicDeletion.3.qml"));
+ QObject *o = component.create();
+ QVERIFY(o != 0);
+ QVERIFY(qvariant_cast<QObject*>(o->property("objectProperty")) == 0);
+ QMetaObject::invokeMethod(o, "create");
+ createdQmlObject = qvariant_cast<QObject*>(o->property("objectProperty"));
+ QVERIFY(createdQmlObject);
+ QMetaObject::invokeMethod(o, "destroy");
+ QVERIFY(qvariant_cast<bool>(o->property("test")) == false);
+ for (int ii = 0; createdQmlObject && ii < 50; ++ii) { // After 5 seconds we should give up
+ QTest::qWait(100);
+ QCoreApplication::sendPostedEvents(0, QEvent::DeferredDelete);
+ QCoreApplication::processEvents();
+ }
+ QVERIFY(qvariant_cast<QObject*>(o->property("objectProperty")) == 0);
+ QVERIFY(qvariant_cast<bool>(o->property("test")) == true);
+ delete o;
+ }
}
/*