diff options
author | Albert Astals Cid <albert.astals@canonical.com> | 2014-03-13 17:09:39 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2014-03-19 10:13:00 +0100 |
commit | 354d3a17e2a772c467343a47f7b328ea8482f7fa (patch) | |
tree | 858013f8d1e3ce8f34d2508e7f02ca0730886c29 | |
parent | c9456432dc8f06da94c51fde8a834ce563d8843a (diff) |
Clear the chain of incubated objects in QQmlIncubatorPrivate::clear
Change-Id: I432310c0e6006d567fd59b4b1021a9e1538ef78f
Reviewed-by: Alan Alpert <aalpert@blackberry.com>
-rw-r--r-- | src/qml/qml/qqmlincubator.cpp | 28 | ||||
-rw-r--r-- | tests/auto/qml/qqmlincubator/data/objectDeleted.qml | 6 | ||||
-rw-r--r-- | tests/auto/qml/qqmlincubator/testtypes.cpp | 20 | ||||
-rw-r--r-- | tests/auto/qml/qqmlincubator/testtypes.h | 21 | ||||
-rw-r--r-- | tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp | 63 |
5 files changed, 101 insertions, 37 deletions
diff --git a/src/qml/qml/qqmlincubator.cpp b/src/qml/qml/qqmlincubator.cpp index 4c9c99f1f6..480e61b0f4 100644 --- a/src/qml/qml/qqmlincubator.cpp +++ b/src/qml/qml/qqmlincubator.cpp @@ -169,6 +169,20 @@ void QQmlIncubatorPrivate::clear() nextWaitingFor.remove(); waitingOnMe = 0; } + + // if we're waiting on any incubators then they should be cleared too. + while (waitingFor.first()) { + QQmlIncubator * i = static_cast<QQmlIncubatorPrivate*>(waitingFor.first())->q; + if (i) + i->clear(); + } + + bool guardOk = vmeGuard.isOK(); + + vmeGuard.clear(); + if (creator && guardOk) + creator->clear(); + creator.reset(0); } /*! @@ -562,20 +576,6 @@ void QQmlIncubator::clear() d->clear(); - // if we're waiting on any incubators then they should be cleared too. - while (d->waitingFor.first()) { - QQmlIncubator * i = static_cast<QQmlIncubatorPrivate*>(d->waitingFor.first())->q; - if (i) - i->clear(); - } - - bool guardOk = d->vmeGuard.isOK(); - - d->vmeGuard.clear(); - if (d->creator && guardOk) - d->creator->clear(); - d->creator.reset(0); - Q_ASSERT(d->compiledData == 0); Q_ASSERT(d->waitingOnMe.data() == 0); Q_ASSERT(d->waitingFor.isEmpty()); diff --git a/tests/auto/qml/qqmlincubator/data/objectDeleted.qml b/tests/auto/qml/qqmlincubator/data/objectDeleted.qml index f00f975923..c9f6f8b564 100644 --- a/tests/auto/qml/qqmlincubator/data/objectDeleted.qml +++ b/tests/auto/qml/qqmlincubator/data/objectDeleted.qml @@ -2,7 +2,9 @@ import QtQuick 2.0 import Qt.test 1.0 Item { - SelfRegistering { - value: 11 + SelfRegisteringOuter { + value: SelfRegistering { + value: 11 + } } } diff --git a/tests/auto/qml/qqmlincubator/testtypes.cpp b/tests/auto/qml/qqmlincubator/testtypes.cpp index d926b6ae9b..b35636dd86 100644 --- a/tests/auto/qml/qqmlincubator/testtypes.cpp +++ b/tests/auto/qml/qqmlincubator/testtypes.cpp @@ -58,6 +58,25 @@ void SelfRegisteringType::clearMe() m_me = 0; } +SelfRegisteringOuterType *SelfRegisteringOuterType::m_me = 0; +bool SelfRegisteringOuterType::beenDeleted = false; +SelfRegisteringOuterType::SelfRegisteringOuterType() +: m_v(0) +{ + m_me = this; + beenDeleted = false; +} + +SelfRegisteringOuterType::~SelfRegisteringOuterType() +{ + beenDeleted = true; +} + +SelfRegisteringOuterType *SelfRegisteringOuterType::me() +{ + return m_me; +} + CompletionRegisteringType *CompletionRegisteringType::m_me = 0; CompletionRegisteringType::CompletionRegisteringType() { @@ -131,6 +150,7 @@ void CompletionCallbackType::registerCallback(callback c, void *d) void registerTypes() { qmlRegisterType<SelfRegisteringType>("Qt.test", 1,0, "SelfRegistering"); + qmlRegisterType<SelfRegisteringOuterType>("Qt.test", 1,0, "SelfRegisteringOuter"); qmlRegisterType<CompletionRegisteringType>("Qt.test", 1,0, "CompletionRegistering"); qmlRegisterType<CallbackRegisteringType>("Qt.test", 1,0, "CallbackRegistering"); qmlRegisterType<CompletionCallbackType>("Qt.test", 1,0, "CompletionCallback"); diff --git a/tests/auto/qml/qqmlincubator/testtypes.h b/tests/auto/qml/qqmlincubator/testtypes.h index fedff61510..8202cdd9dc 100644 --- a/tests/auto/qml/qqmlincubator/testtypes.h +++ b/tests/auto/qml/qqmlincubator/testtypes.h @@ -63,6 +63,27 @@ private: int m_v; }; +class SelfRegisteringOuterType : public QObject +{ +Q_OBJECT +Q_PROPERTY(QObject* value READ value WRITE setValue); +public: + SelfRegisteringOuterType(); + ~SelfRegisteringOuterType(); + + static bool beenDeleted; + + QObject *value() const { return m_v; } + void setValue(QObject *v) { m_v = v; } + + static SelfRegisteringOuterType *me(); + +private: + static SelfRegisteringOuterType *m_me; + + QObject *m_v; +}; + class CallbackRegisteringType : public QObject { Q_OBJECT diff --git a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp index d6d0b0402a..0b9872f94c 100644 --- a/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp +++ b/tests/auto/qml/qqmlincubator/tst_qqmlincubator.cpp @@ -52,6 +52,8 @@ #include <QQmlComponent> #include <QQmlIncubator> #include "../../shared/util.h" +#include <private/qqmlincubator_p.h> +#include <private/qqmlobjectcreator_p.h> class tst_qqmlincubator : public QQmlDataTest { @@ -141,35 +143,50 @@ void tst_qqmlincubator::incubationMode() void tst_qqmlincubator::objectDeleted() { - SelfRegisteringType::clearMe(); + { + QQmlEngine engine; + QQmlIncubationController controller; + engine.setIncubationController(&controller); + SelfRegisteringType::clearMe(); - QQmlComponent component(&engine, testFileUrl("objectDeleted.qml")); - QVERIFY(component.isReady()); + QQmlComponent component(&engine, testFileUrl("objectDeleted.qml")); + QVERIFY(component.isReady()); - QQmlIncubator incubator; - component.create(incubator); + QQmlIncubator incubator; + component.create(incubator); - QCOMPARE(incubator.status(), QQmlIncubator::Loading); - QVERIFY(SelfRegisteringType::me() == 0); + QCOMPARE(incubator.status(), QQmlIncubator::Loading); + QVERIFY(SelfRegisteringType::me() == 0); - while (SelfRegisteringType::me() == 0 && incubator.isLoading()) { - bool b = false; - controller.incubateWhile(&b); - } + while (SelfRegisteringOuterType::me() == 0 && incubator.isLoading()) { + bool b = false; + controller.incubateWhile(&b); + } - QVERIFY(SelfRegisteringType::me() != 0); - QVERIFY(incubator.isLoading()); + QVERIFY(SelfRegisteringOuterType::me() != 0); + QVERIFY(incubator.isLoading()); - delete SelfRegisteringType::me(); + while (SelfRegisteringType::me() == 0 && incubator.isLoading()) { + bool b = false; + controller.incubateWhile(&b); + } - { - bool b = true; - controller.incubateWhile(&b); - } + // We have to cheat and manually remove it from the creator->allCreatedObjects + // otherwise we will do a double delete + QQmlIncubatorPrivate *incubatorPriv = QQmlIncubatorPrivate::get(&incubator); + incubatorPriv->creator->allCreatedObjects().pop(); + delete SelfRegisteringType::me(); - QVERIFY(incubator.isError()); - VERIFY_ERRORS(incubator, "objectDeleted.errors.txt"); - QVERIFY(incubator.object() == 0); + { + bool b = true; + controller.incubateWhile(&b); + } + + QVERIFY(incubator.isError()); + VERIFY_ERRORS(incubator, "objectDeleted.errors.txt"); + QVERIFY(incubator.object() == 0); + } + QVERIFY(SelfRegisteringOuterType::beenDeleted); } void tst_qqmlincubator::clear() @@ -1111,6 +1128,10 @@ void tst_qqmlincubator::selfDelete() QVERIFY(SelfRegisteringType::me() != 0); QVERIFY(incubator->isLoading()); + // We have to cheat and manually remove it from the creator->allCreatedObjects + // otherwise we will do a double delete + QQmlIncubatorPrivate *incubatorPriv = QQmlIncubatorPrivate::get(incubator); + incubatorPriv->creator->allCreatedObjects().pop(); delete SelfRegisteringType::me(); { |