diff options
author | Louis du Verdier <louis.du.verdier@free.fr> | 2019-12-28 14:53:03 +0100 |
---|---|---|
committer | Louis du Verdier <louis.du.verdier@free.fr> | 2020-01-07 19:39:09 +0100 |
commit | 64ab935e0a69b1ad5bdb6f59dbe3f9304716c02a (patch) | |
tree | 57478a0a56913d53aabd5dad488527f1890c020a /tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp | |
parent | 6dfbbc2a5435d2e9542e9cf2eb039147db0ff29b (diff) |
Stabilize QQuickItemParticle
This commit fixes two crashes and a memory leak in QQuickItemParticle.
The first crash was caused by the list m_loadables that kept pointers on
QQuickParticleData, that could in the meantime become dangling pointers
if the associated particle expired or got deleted by a call to the
reset() method of the particle system. Its role was to keep a list of
particles that did not have a delegate instantiated yet, in order to
create them in the tick() method. This list is removed and the list of
particles to handle is directly deduced in the tick() method.
The second crash was caused by the list m_deletables that could in some
situations (generally due to a reset()) contain multiple times the same
delegate, and therefore cause a double delete in processDeletables().
This list is changed to a set to avoid this situation with a minimum
impact on the rest of the code.
The memory leak was caused by the m_managed list of delegates that was
not freed when QQuickItemParticle gets deleted.
Task-number: QTBUG-71193
Change-Id: I6fe30ee59a9a0bb90c14c62c7a48a50f465a9e0c
Reviewed-by: Mikhail Svetkin <mikhail.svetkin@gmail.com>
Diffstat (limited to 'tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp')
-rw-r--r-- | tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp b/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp index d9791cdb33..ea4e7a97a6 100644 --- a/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp +++ b/tests/auto/particles/qquickitemparticle/tst_qquickitemparticle.cpp @@ -45,6 +45,8 @@ private slots: void test_basic(); void test_deletion(); void test_noDeletion(); + void test_noCrashOnReset(); + void test_noLeakWhenDeleted(); }; void tst_qquickitemparticle::initTestCase() @@ -107,6 +109,41 @@ void tst_qquickitemparticle::test_noDeletion() delete view; } +void tst_qquickitemparticle::test_noCrashOnReset() +{ + QQuickView* view = createView(testFileUrl("basic.qml"), 600); + QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system"); + + for (int i = 0; i < 10; ++i) { + ensureAnimTime(16, system->m_animation); + system->reset(); + } + + delete view; +} + +void tst_qquickitemparticle::test_noLeakWhenDeleted() +{ + QQuickView* view = createView(testFileUrl("loader.qml"), 500); + QQuickParticleSystem* system = view->rootObject()->findChild<QQuickParticleSystem*>("system"); + ensureAnimTime(100, system->m_animation); + + auto particles = qAsConst(system->groupData[0]->data); + QVERIFY(!particles.isEmpty()); + + QQuickParticleData* firstParticleData = particles.first(); + QPointer<QQuickItem> firstParticleDelegate = firstParticleData->delegate; + QVERIFY(!firstParticleDelegate.isNull()); + + QQuickItem* loader = view->rootObject()->findChild<QQuickItem*>("loader"); + loader->setProperty("active", false); //This should destroy the ParticleSystem, ItemParticle and Emitter + + QTest::qWait(1); //Process events to make sure the loader is properly unloaded + QVERIFY(firstParticleDelegate.isNull()); //Delegates should be deleted + + delete view; +} + QTEST_MAIN(tst_qquickitemparticle); #include "tst_qquickitemparticle.moc" |