diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-11-02 09:48:57 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2017-12-11 10:21:45 +0000 |
commit | 53d3a0779663285baaaf13a05afc4a7d11f6ed29 (patch) | |
tree | c2e9f7ca9ca865c15f7df6888b157ac12238d963 | |
parent | 894211971ebf8b53ed3a78d771764021f7de2de6 (diff) |
Make deletion of transitions safe
Task-number: QTBUG-63844
Change-Id: I65029e9039ea3db85152fc3cdefaac3deee0db6c
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r-- | src/quick/items/qquickitemviewtransition_p.h | 18 | ||||
-rw-r--r-- | src/quick/util/qquicktransition.cpp | 29 | ||||
-rw-r--r-- | 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 <QtCore/qobject.h> #include <QtCore/qpoint.h> #include <QtQml/qqml.h> +#include <private/qqmlguard_p.h> +#include <private/qquicktransition_p.h> QT_BEGIN_NAMESPACE @@ -115,14 +117,14 @@ public: QList<QObject *> moveTransitionTargets; QList<QObject *> removeTransitionTargets; - QQuickTransition *populateTransition; - QQuickTransition *addTransition; - QQuickTransition *addDisplacedTransition; - QQuickTransition *moveTransition; - QQuickTransition *moveDisplacedTransition; - QQuickTransition *removeTransition; - QQuickTransition *removeDisplacedTransition; - QQuickTransition *displacedTransition; + QQmlGuard<QQuickTransition> populateTransition; + QQmlGuard<QQuickTransition> addTransition; + QQmlGuard<QQuickTransition> addDisplacedTransition; + QQmlGuard<QQuickTransition> moveTransition; + QQmlGuard<QQuickTransition> moveDisplacedTransition; + QQmlGuard<QQuickTransition> removeTransition; + QQmlGuard<QQuickTransition> removeDisplacedTransition; + QQmlGuard<QQuickTransition> 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<QQuickAbstractAnimation> *list, QQuickAbstractAnimation *a); static int animation_count(QQmlListProperty<QQuickAbstractAnimation> *list); @@ -171,7 +167,16 @@ void QQuickTransitionPrivate::clear_animations(QQmlListProperty<QQuickAbstractAn } } -void QQuickTransitionPrivate::animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State) +void QQuickTransitionInstance::animationStateChanged(QAbstractAnimationJob *, QAbstractAnimationJob::State newState, QAbstractAnimationJob::State) +{ + if (!m_transition) + return; + + QQuickTransitionPrivate *transition = QQuickTransitionPrivate::get(m_transition); + transition->animationStateChanged(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 <private/qabstractanimationjob_p.h> +#include <private/qqmlguard_p.h> #include <qqml.h> #include <QtCore/qobject.h> @@ -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<QQuickTransition> m_transition; QAbstractAnimationJob *m_anim; friend class QQuickTransition; }; |