From 2dfa486ee951b8fa0a9ea942ebcd6cfca1f3d780 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 21 Jan 2021 12:06:26 +0100 Subject: QAnimationGroupJob: Don't call virtual functions from dtor The subclasses are already dead at that point. We don't need to notify them anymore. Rather, refactor the code so that we can clean up QAnimationGroupJob itself without virtual calls. Task-number: QTBUG-90401 Change-Id: I6917bf299ceb1383b9d29687e5bf53ae36803ecf Reviewed-by: Fabian Kosmale Reviewed-by: Andrei Golubev (cherry picked from commit 75437f824d4c3a608af9eb1afddcb4d8c1a25944) Reviewed-by: Qt Cherry-pick Bot --- src/qml/animations/qanimationgroupjob.cpp | 62 +++++++++++++++++++------------ src/qml/animations/qanimationgroupjob_p.h | 3 ++ 2 files changed, 42 insertions(+), 23 deletions(-) diff --git a/src/qml/animations/qanimationgroupjob.cpp b/src/qml/animations/qanimationgroupjob.cpp index 66599561fc..60b3003d0a 100644 --- a/src/qml/animations/qanimationgroupjob.cpp +++ b/src/qml/animations/qanimationgroupjob.cpp @@ -47,9 +47,45 @@ QAnimationGroupJob::QAnimationGroupJob() m_isGroup = true; } +void QAnimationGroupJob::ungroupChild(QAbstractAnimationJob *animation) +{ + Q_ASSERT(animation); + Q_ASSERT(animation->m_group == this); + QAbstractAnimationJob *prev = animation->previousSibling(); + QAbstractAnimationJob *next = animation->nextSibling(); + + if (prev) + prev->m_nextSibling = next; + else + m_firstChild = next; + + if (next) + next->m_previousSibling = prev; + else + m_lastChild = prev; + + animation->m_previousSibling = nullptr; + animation->m_nextSibling = nullptr; + + animation->m_group = nullptr; +} + +void QAnimationGroupJob::handleAnimationRemoved(QAbstractAnimationJob *animation) +{ + resetUncontrolledAnimationFinishTime(animation); + if (!firstChild()) { + m_currentTime = 0; + stop(); + } +} + QAnimationGroupJob::~QAnimationGroupJob() { - clear(); + while (QAbstractAnimationJob *animation = firstChild()) { + ungroupChild(animation); + handleAnimationRemoved(animation); + delete animation; + } } void QAnimationGroupJob::topLevelAnimationLoopChanged() @@ -96,25 +132,9 @@ void QAnimationGroupJob::prependAnimation(QAbstractAnimationJob *animation) void QAnimationGroupJob::removeAnimation(QAbstractAnimationJob *animation) { - Q_ASSERT(animation); - Q_ASSERT(animation->m_group == this); QAbstractAnimationJob *prev = animation->previousSibling(); QAbstractAnimationJob *next = animation->nextSibling(); - - if (prev) - prev->m_nextSibling = next; - else - m_firstChild = next; - - if (next) - next->m_previousSibling = prev; - else - m_lastChild = prev; - - animation->m_previousSibling = nullptr; - animation->m_nextSibling = nullptr; - - animation->m_group = nullptr; + ungroupChild(animation); animationRemoved(animation, prev, next); } @@ -154,11 +174,7 @@ void QAnimationGroupJob::uncontrolledAnimationFinished(QAbstractAnimationJob *an void QAnimationGroupJob::animationRemoved(QAbstractAnimationJob* anim, QAbstractAnimationJob* , QAbstractAnimationJob* ) { - resetUncontrolledAnimationFinishTime(anim); - if (!firstChild()) { - m_currentTime = 0; - stop(); - } + handleAnimationRemoved(anim); } void QAnimationGroupJob::debugChildren(QDebug d) const diff --git a/src/qml/animations/qanimationgroupjob_p.h b/src/qml/animations/qanimationgroupjob_p.h index a27c9195dd..6a0941db65 100644 --- a/src/qml/animations/qanimationgroupjob_p.h +++ b/src/qml/animations/qanimationgroupjob_p.h @@ -91,6 +91,9 @@ protected: void debugChildren(QDebug d) const; private: + void ungroupChild(QAbstractAnimationJob *animation); + void handleAnimationRemoved(QAbstractAnimationJob *animation); + //definition QAbstractAnimationJob *m_firstChild = nullptr; QAbstractAnimationJob *m_lastChild = nullptr; -- cgit v1.2.3