From 48489988521b818bda8d76e60cb272508e91b490 Mon Sep 17 00:00:00 2001 From: Thierry Bastian Date: Tue, 25 Aug 2009 15:36:37 +0200 Subject: animations: make sure setCurrentTime is called on all animations The problem was we were iterating over the list of running animations. And when calling setCurrentTime() on one of them they just unregister themselves from the timer and we would miss some of them. Reviewed-by: leo --- src/corelib/animation/qabstractanimation.cpp | 7 ++- .../qpropertyanimation/tst_qpropertyanimation.cpp | 50 ++++++++++++++++++++++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index efe1fb0..617f4db 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -200,8 +200,11 @@ void QUnifiedTimer::timerEvent(QTimerEvent *event) } } else if (event->timerId() == animationTimer.timerId()) { const int delta = lastTick - oldLastTick; - for (int i = 0; i < animations.count(); ++i) { - QAbstractAnimation *animation = animations.at(i); + //we copy the list so that if it is changed we still get to + //call setCurrentTime on all animations. + const QList currentAnimations = animations; + for (int i = 0; i < currentAnimations.count(); ++i) { + QAbstractAnimation *animation = currentAnimations.at(i); int elapsed = QAbstractAnimationPrivate::get(animation)->totalCurrentTime + (animation->direction() == QAbstractAnimation::Forward ? delta : -delta); animation->setCurrentTime(elapsed); diff --git a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp index 3ff177a..04cfe1a 100644 --- a/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp +++ b/tests/auto/qpropertyanimation/tst_qpropertyanimation.cpp @@ -114,6 +114,7 @@ private slots: void updateOnSetKeyValues(); void restart(); void valueChanged(); + void twoAnimations(); }; tst_QPropertyAnimation::tst_QPropertyAnimation() @@ -1079,6 +1080,55 @@ void tst_QPropertyAnimation::valueChanged() } } +//this class will help us make sure that 2 animations started +//at the same time also end at the same time +class MySyncObject : public MyErrorObject +{ + Q_OBJECT +public: + MySyncObject() : anim(this, "ole") + { + anim.setEndValue(1000); + } +public slots: + void checkAnimationFinished() + { + QCOMPARE(anim.state(), QAbstractAnimation::Stopped); + QCOMPARE(ole(), 1000); + } + +public: + QPropertyAnimation anim; +}; + +void tst_QPropertyAnimation::twoAnimations() +{ + MySyncObject o1, o2; + o1.setOle(0); + o2.setOle(0); + + //when the animation in o1 is finished + //the animation in o2 should stop around the same time + //We use a queued connection to check just after the tick from the common timer + //the other way is true too + QObject::connect(&o1.anim, SIGNAL(finished()), + &o2, SLOT(checkAnimationFinished()), Qt::QueuedConnection); + QObject::connect(&o2.anim, SIGNAL(finished()), + &o1, SLOT(checkAnimationFinished()), Qt::QueuedConnection); + + o1.anim.start(); + o2.anim.start(); + + QTest::qWait(o1.anim.duration() + 50); + QCOMPARE(o1.anim.state(), QAbstractAnimation::Stopped); + QCOMPARE(o2.anim.state(), QAbstractAnimation::Stopped); + + QCOMPARE(o1.ole(), 1000); + QCOMPARE(o2.ole(), 1000); + +} + + QTEST_MAIN(tst_QPropertyAnimation) -- cgit v0.12