From 53d3a0779663285baaaf13a05afc4a7d11f6ed29 Mon Sep 17 00:00:00 2001 From: Lars Knoll Date: Thu, 2 Nov 2017 09:48:57 +0100 Subject: Make deletion of transitions safe Task-number: QTBUG-63844 Change-Id: I65029e9039ea3db85152fc3cdefaac3deee0db6c Reviewed-by: Simon Hausmann --- src/quick/items/qquickitemviewtransition_p.h | 18 +++++++++-------- src/quick/util/qquicktransition.cpp | 29 ++++++++++++++++------------ src/quick/util/qquicktransition_p.h | 15 +++++++++++--- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/src/quick/items/qquickitemviewtransition_p.h b/src/quick/items/qquickitemviewtransition_p.h index 3d2f5361b1..29a62f7f10 100644 --- a/src/quick/items/qquickitemviewtransition_p.h +++ b/src/quick/items/qquickitemviewtransition_p.h @@ -58,6 +58,8 @@ QT_REQUIRE_CONFIG(quick_viewtransitions); #include #include #include +#include +#include QT_BEGIN_NAMESPACE @@ -115,14 +117,14 @@ public: QList moveTransitionTargets; QList removeTransitionTargets; - QQuickTransition *populateTransition; - QQuickTransition *addTransition; - QQuickTransition *addDisplacedTransition; - QQuickTransition *moveTransition; - QQuickTransition *moveDisplacedTransition; - QQuickTransition *removeTransition; - QQuickTransition *removeDisplacedTransition; - QQuickTransition *displacedTransition; + QQmlGuard populateTransition; + QQmlGuard addTransition; + QQmlGuard addDisplacedTransition; + QQmlGuard moveTransition; + QQmlGuard moveDisplacedTransition; + QQmlGuard removeTransition; + QQmlGuard removeDisplacedTransition; + QQmlGuard displacedTransition; private: friend class QQuickItemViewTransitionJob; diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp index 29690a4857..6ae89c4ed4 100644 --- a/src/quick/util/qquicktransition.cpp +++ b/src/quick/util/qquicktransition.cpp @@ -109,7 +109,7 @@ protected: void updateState(QAbstractAnimationJob::State newState, QAbstractAnimationJob::State oldState) override; }; -class QQuickTransitionPrivate : public QObjectPrivate, QAnimationJobChangeListener +class QQuickTransitionPrivate : public QObjectPrivate { Q_DECLARE_PUBLIC(QQuickTransition) public: @@ -120,11 +120,8 @@ public: { } - void removeStateChangeListener(QAbstractAnimationJob *anim) - { - if (anim) - anim->removeAnimationChangeListener(this, QAbstractAnimationJob::StateChange); - } + static QQuickTransitionPrivate *get(QQuickTransition *q) { return q->d_func(); } + void animationStateChanged(QAbstractAnimationJob::State newState); QString fromState; QString toState; @@ -134,7 +131,6 @@ public: bool reversible; bool enabled; protected: - void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State, QAbstractAnimationJob::State) override; static void append_animation(QQmlListProperty *list, QQuickAbstractAnimation *a); static int animation_count(QQmlListProperty *list); @@ -171,7 +167,16 @@ void QQuickTransitionPrivate::clear_animations(QQmlListPropertyanimationStateChanged(newState); +} + +void QQuickTransitionPrivate::animationStateChanged(QAbstractAnimationJob::State newState) { Q_Q(QQuickTransition); @@ -197,15 +202,16 @@ void ParallelAnimationWrapper::updateState(QAbstractAnimationJob::State newState } } -QQuickTransitionInstance::QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim) +QQuickTransitionInstance::QQuickTransitionInstance(QQuickTransition *transition, QAbstractAnimationJob *anim) : m_transition(transition) , m_anim(anim) { + anim->addAnimationChangeListener(this, QAbstractAnimationJob::StateChange); } QQuickTransitionInstance::~QQuickTransitionInstance() { - m_transition->removeStateChangeListener(m_anim); + removeStateChangeListener(); delete m_anim; } @@ -270,8 +276,7 @@ QQuickTransitionInstance *QQuickTransition::prepare(QQuickStateOperation::Action group->setDirection(d->reversed ? QAbstractAnimationJob::Backward : QAbstractAnimationJob::Forward); - group->addAnimationChangeListener(d, QAbstractAnimationJob::StateChange); - QQuickTransitionInstance *wrapper = new QQuickTransitionInstance(d, group); + QQuickTransitionInstance *wrapper = new QQuickTransitionInstance(this, group); return wrapper; } diff --git a/src/quick/util/qquicktransition_p.h b/src/quick/util/qquicktransition_p.h index d6f365f99e..6d2e41fc9d 100644 --- a/src/quick/util/qquicktransition_p.h +++ b/src/quick/util/qquicktransition_p.h @@ -53,6 +53,7 @@ #include "qquickstate_p.h" #include +#include #include #include @@ -64,10 +65,10 @@ class QQuickTransitionPrivate; class QQuickTransitionManager; class QQuickTransition; -class QQuickTransitionInstance +class QQuickTransitionInstance : QAnimationJobChangeListener { public: - QQuickTransitionInstance(QQuickTransitionPrivate *transition, QAbstractAnimationJob *anim); + QQuickTransitionInstance(QQuickTransition *transition, QAbstractAnimationJob *anim); ~QQuickTransitionInstance(); void start(); @@ -75,8 +76,16 @@ public: bool isRunning() const; +protected: + void animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State, QAbstractAnimationJob::State) override; + + void removeStateChangeListener() + { + m_anim->removeAnimationChangeListener(this, QAbstractAnimationJob::StateChange); + } + private: - QQuickTransitionPrivate *m_transition; + QQmlGuard m_transition; QAbstractAnimationJob *m_anim; friend class QQuickTransition; }; -- cgit v1.2.3