diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-11-30 05:13:42 (GMT) |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2010-11-30 05:13:42 (GMT) |
commit | 16cbe54f41ff4ff9a03ce3973c52be32d63b7138 (patch) | |
tree | a1254ae25a648834d405dd39b52e78f0f078c4ba | |
parent | 46213b30d639505849d079b30e72ef8393e9a748 (diff) | |
download | Qt-16cbe54f41ff4ff9a03ce3973c52be32d63b7138.zip Qt-16cbe54f41ff4ff9a03ce3973c52be32d63b7138.tar.gz Qt-16cbe54f41ff4ff9a03ce3973c52be32d63b7138.tar.bz2 |
Correct ownership semantics for QObject derived types
Task-number: QTBUG-15697
-rw-r--r-- | src/declarative/qml/qdeclarativeobjectscriptclass.cpp | 11 | ||||
-rw-r--r-- | tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp | 37 |
2 files changed, 46 insertions, 2 deletions
diff --git a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp index eff59df..b0bc5bb 100644 --- a/src/declarative/qml/qdeclarativeobjectscriptclass.cpp +++ b/src/declarative/qml/qdeclarativeobjectscriptclass.cpp @@ -69,7 +69,7 @@ struct ObjectData : public QScriptDeclarativeClass::Object { virtual ~ObjectData() { if (object && !object->parent()) { QDeclarativeData *ddata = QDeclarativeData::get(object, false); - if (ddata && !ddata->indestructible && 0 == --ddata->objectDataRefCount) + if (ddata && !ddata->indestructible && 0 == --ddata->objectDataRefCount) object->deleteLater(); } } @@ -808,7 +808,14 @@ QScriptDeclarativeClass::Value MetaCallArgument::toValue(QDeclarativeEngine *e) } return QScriptDeclarativeClass::Value(engine, rv); } else if (type == -1 || type == qMetaTypeId<QVariant>()) { - return QScriptDeclarativeClass::Value(engine, QDeclarativeEnginePrivate::get(e)->scriptValueFromVariant(*((QVariant *)&data))); + QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(e); + QScriptValue rv = ep->scriptValueFromVariant(*((QVariant *)&data)); + if (rv.isQObject()) { + QObject *object = rv.toQObject(); + if (object) + QDeclarativeData::get(object, true)->setImplicitDestructible(); + } + return QScriptDeclarativeClass::Value(engine, rv); } else { return QScriptDeclarativeClass::Value(); } diff --git a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp index 7c0a316..77fab91 100644 --- a/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp +++ b/tests/auto/declarative/qdeclarativeecmascript/tst_qdeclarativeecmascript.cpp @@ -136,6 +136,7 @@ private slots: void scriptDisconnect(); void ownership(); void cppOwnershipReturnValue(); + void ownershipCustomReturnValue(); void qlistqobjectMethods(); void strictlyEquals(); void compiled(); @@ -2106,6 +2107,7 @@ class CppOwnershipReturnValue : public QObject Q_OBJECT public: CppOwnershipReturnValue() : value(0) {} + ~CppOwnershipReturnValue() { delete value; } Q_INVOKABLE QObject *create() { Q_ASSERT(value == 0); @@ -2115,6 +2117,14 @@ public: return value; } + Q_INVOKABLE MyQmlObject *createQmlObject() { + Q_ASSERT(value == 0); + + MyQmlObject *rv = new MyQmlObject; + value = rv; + return rv; + } + QPointer<QObject> value; }; @@ -2146,6 +2156,33 @@ void tst_qdeclarativeecmascript::cppOwnershipReturnValue() QVERIFY(source.value != 0); } +// QTBUG-15697 +void tst_qdeclarativeecmascript::ownershipCustomReturnValue() +{ + CppOwnershipReturnValue source; + + { + QDeclarativeEngine engine; + engine.rootContext()->setContextProperty("source", &source); + + QVERIFY(source.value == 0); + + QDeclarativeComponent component(&engine); + component.setData("import QtQuick 1.0\nQtObject {\nComponent.onCompleted: { var a = source.createQmlObject(); }\n}\n", QUrl()); + + QObject *object = component.create(); + + QVERIFY(object != 0); + QVERIFY(source.value != 0); + + delete object; + } + + QCoreApplication::instance()->processEvents(QEventLoop::DeferredDeletion); + + QVERIFY(source.value == 0); +} + class QListQObjectMethodsObject : public QObject { Q_OBJECT |