diff options
Diffstat (limited to 'src/corelib/animation')
-rw-r--r-- | src/corelib/animation/qabstractanimation.cpp | 4 | ||||
-rw-r--r-- | src/corelib/animation/qanimationgroup.cpp | 25 | ||||
-rw-r--r-- | src/corelib/animation/qanimationgroup_p.h | 2 | ||||
-rw-r--r-- | src/corelib/animation/qsequentialanimationgroup.cpp | 3 | ||||
-rw-r--r-- | src/corelib/animation/qvariantanimation.cpp | 4 |
5 files changed, 33 insertions, 5 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 0be37b7dca..46b01449d4 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -1063,10 +1063,12 @@ QAbstractAnimation::~QAbstractAnimation() if (d->state != Stopped) { QAbstractAnimation::State oldState = d->state; d->state = Stopped; - emit stateChanged(oldState, d->state); + emit stateChanged(d->state, oldState); if (oldState == QAbstractAnimation::Running) QAnimationTimer::unregisterAnimation(this); } + if (d->group) + d->group->removeAnimation(this); } /*! diff --git a/src/corelib/animation/qanimationgroup.cpp b/src/corelib/animation/qanimationgroup.cpp index f47d99eb68..ed40817222 100644 --- a/src/corelib/animation/qanimationgroup.cpp +++ b/src/corelib/animation/qanimationgroup.cpp @@ -113,6 +113,11 @@ QAnimationGroup::QAnimationGroup(QAnimationGroupPrivate &dd, QObject *parent) */ QAnimationGroup::~QAnimationGroup() { + Q_D(QAnimationGroup); + // We need to clear the animations now while we are still a valid QAnimationGroup. + // If we wait until ~QObject() the QAbstractAnimation's pointer back to us would + // point to a QObject, not a valid QAnimationGroup. + d->clear(true); } /*! @@ -256,7 +261,7 @@ QAbstractAnimation *QAnimationGroup::takeAnimation(int index) void QAnimationGroup::clear() { Q_D(QAnimationGroup); - qDeleteAll(d->animations); + d->clear(false); } /*! @@ -284,6 +289,24 @@ bool QAnimationGroup::event(QEvent *event) return QAbstractAnimation::event(event); } +void QAnimationGroupPrivate::clear(bool onDestruction) +{ + const QList<QAbstractAnimation *> animationsCopy = animations; // taking a copy + animations.clear(); + // Clearing backwards so the indices doesn't change while we remove animations. + for (int i = animationsCopy.count() - 1; i >= 0; --i) { + QAbstractAnimation *animation = animationsCopy.at(i); + animation->setParent(nullptr); + QAbstractAnimationPrivate::get(animation)->group = nullptr; + // If we are in ~QAnimationGroup() it is not safe to called the virtual + // animationRemoved method, which can still be a method in a + // QAnimationGroupPrivate derived class that assumes q_ptr is still + // a valid derived class of QAnimationGroup. + if (!onDestruction) + animationRemoved(i, animation); + delete animation; + } +} void QAnimationGroupPrivate::animationRemoved(int index, QAbstractAnimation *) { diff --git a/src/corelib/animation/qanimationgroup_p.h b/src/corelib/animation/qanimationgroup_p.h index 215734b656..4d1d690e69 100644 --- a/src/corelib/animation/qanimationgroup_p.h +++ b/src/corelib/animation/qanimationgroup_p.h @@ -73,6 +73,8 @@ public: virtual void animationInsertedAt(int) { } virtual void animationRemoved(int, QAbstractAnimation *); + void clear(bool onDestruction); + void disconnectUncontrolledAnimation(QAbstractAnimation *anim) { //0 for the signal here because we might be called from the animation destructor diff --git a/src/corelib/animation/qsequentialanimationgroup.cpp b/src/corelib/animation/qsequentialanimationgroup.cpp index 150e74d7d6..66e346a2fe 100644 --- a/src/corelib/animation/qsequentialanimationgroup.cpp +++ b/src/corelib/animation/qsequentialanimationgroup.cpp @@ -532,7 +532,8 @@ void QSequentialAnimationGroupPrivate::animationRemoved(int index, QAbstractAnim Q_Q(QSequentialAnimationGroup); QAnimationGroupPrivate::animationRemoved(index, anim); - Q_ASSERT(currentAnimation); // currentAnimation should always be set + if (!currentAnimation) + return; if (actualDuration.size() > index) actualDuration.removeAt(index); diff --git a/src/corelib/animation/qvariantanimation.cpp b/src/corelib/animation/qvariantanimation.cpp index ac81f89ed4..01a699c5dc 100644 --- a/src/corelib/animation/qvariantanimation.cpp +++ b/src/corelib/animation/qvariantanimation.cpp @@ -283,11 +283,11 @@ void QVariantAnimationPrivate::setCurrentValueForProgress(const qreal progress) qSwap(currentValue, ret); q->updateCurrentValue(currentValue); static QBasicAtomicInt changedSignalIndex = Q_BASIC_ATOMIC_INITIALIZER(0); - if (!changedSignalIndex.load()) { + if (!changedSignalIndex.loadRelaxed()) { //we keep the mask so that we emit valueChanged only when needed (for performance reasons) changedSignalIndex.testAndSetRelaxed(0, signalIndex("valueChanged(QVariant)")); } - if (isSignalConnected(changedSignalIndex.load()) && currentValue != ret) { + if (isSignalConnected(changedSignalIndex.loadRelaxed()) && currentValue != ret) { //the value has changed emit q->valueChanged(currentValue); } |