diff options
Diffstat (limited to 'src/corelib/animation')
-rw-r--r-- | src/corelib/animation/qabstractanimation.cpp | 121 | ||||
-rw-r--r-- | src/corelib/animation/qabstractanimation.h | 2 | ||||
-rw-r--r-- | src/corelib/animation/qabstractanimation_p.h | 10 |
3 files changed, 95 insertions, 38 deletions
diff --git a/src/corelib/animation/qabstractanimation.cpp b/src/corelib/animation/qabstractanimation.cpp index 95d7713cfe..8263e056fb 100644 --- a/src/corelib/animation/qabstractanimation.cpp +++ b/src/corelib/animation/qabstractanimation.cpp @@ -222,7 +222,8 @@ QUnifiedTimer::QUnifiedTimer() : QObject(), defaultDriver(this), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL), currentAnimationIdx(0), insideTick(false), insideRestart(false), consistentTiming(false), slowMode(false), startTimersPending(false), stopTimerPending(false), - slowdownFactor(5.0f), profilerCallback(0) + slowdownFactor(5.0f), profilerCallback(0), + driverStartTime(0), temporalDrift(0) { time.invalidate(); driver = &defaultDriver; @@ -253,18 +254,56 @@ QUnifiedTimer *QUnifiedTimer::instance() void QUnifiedTimer::maybeUpdateAnimationsToCurrentTime() { - qint64 elapsed = driver->elapsed(); - if (elapsed - lastTick > 50) - updateAnimationTimers(elapsed); + if (elapsed() - lastTick > 50) + updateAnimationTimers(-1); +} + +qint64 QUnifiedTimer::elapsed() const +{ + if (driver->isRunning()) + return driverStartTime + driver->elapsed(); + else if (time.isValid()) + return time.elapsed() + temporalDrift; + + // Reaching here would normally indicate that the function is called + // under the wrong circumstances as neither pauses nor actual animations + // are running and there should be no need to query for elapsed(). + return 0; +} + +void QUnifiedTimer::startAnimationDriver() +{ + if (driver->isRunning()) { + qWarning("QUnifiedTimer::startAnimationDriver: driver is already running..."); + return; + } + // Set the start time to the currently elapsed() value before starting. + // This means we get the animation system time including the temporal drift + // which is what we want. + driverStartTime = elapsed(); + driver->start(); +} + +void QUnifiedTimer::stopAnimationDriver() +{ + if (!driver->isRunning()) { + qWarning("QUnifiedTimer::stopAnimationDriver: driver is not running"); + return; + } + // Update temporal drift. Since the driver is running, elapsed() will + // return the total animation time in driver-time. Subtract the current + // wall time to get the delta. + temporalDrift = elapsed() - time.elapsed(); + driver->stop(); } -void QUnifiedTimer::updateAnimationTimers(qint64 currentTick) +void QUnifiedTimer::updateAnimationTimers(qint64) { //setCurrentTime can get this called again while we're the for loop. At least with pauseAnimations if(insideTick) return; - qint64 totalElapsed = currentTick >= 0 ? currentTick : driver->elapsed(); + qint64 totalElapsed = elapsed(); // ignore consistentTiming in case the pause timer is active qint64 delta = (consistentTiming && !pauseTimer.isActive()) ? @@ -323,8 +362,7 @@ void QUnifiedTimer::localRestart() } else if (!driver->isRunning()) { if (pauseTimer.isActive()) pauseTimer.stop(); - driver->setStartTime(time.isValid() ? time.elapsed() : 0); - driver->start(); + startAnimationDriver(); } } @@ -345,35 +383,39 @@ void QUnifiedTimer::setTimingInterval(int interval) if (driver->isRunning() && !pauseTimer.isActive()) { //we changed the timing interval - driver->stop(); - driver->setStartTime(time.isValid() ? time.elapsed() : 0); - driver->start(); + stopAnimationDriver(); + startAnimationDriver(); } } void QUnifiedTimer::startTimers() { startTimersPending = false; + + // Initialize the wall clock right away as we need this for + // both localRestart and updateAnimationTimers() down below.. + if (!time.isValid()) { + lastTick = 0; + time.start(); + temporalDrift = 0; + driverStartTime = 0; + } + if (!animationTimers.isEmpty()) updateAnimationTimers(-1); //we transfer the waiting animations into the "really running" state animationTimers += animationTimersToStart; animationTimersToStart.clear(); - if (!animationTimers.isEmpty()) { + if (!animationTimers.isEmpty()) localRestart(); - if (!time.isValid()) { - lastTick = 0; - time.start(); - } - } } void QUnifiedTimer::stopTimer() { stopTimerPending = false; if (animationTimers.isEmpty()) { - driver->stop(); + stopAnimationDriver(); pauseTimer.stop(); // invalidate the start reference time time.invalidate(); @@ -483,14 +525,12 @@ void QUnifiedTimer::installAnimationDriver(QAnimationDriver *d) return; } - if (driver->isRunning()) { - driver->stop(); - d->setStartTime(time.isValid() ? time.elapsed() : 0); - d->start(); - } - + bool running = driver->isRunning(); + if (running) + stopAnimationDriver(); driver = d; - + if (running) + startAnimationDriver(); } void QUnifiedTimer::uninstallAnimationDriver(QAnimationDriver *d) @@ -500,13 +540,12 @@ void QUnifiedTimer::uninstallAnimationDriver(QAnimationDriver *d) return; } + bool running = driver->isRunning(); + if (running) + stopAnimationDriver(); driver = &defaultDriver; - - if (d->isRunning()) { - d->stop(); - driver->setStartTime(time.isValid() ? time.elapsed() : 0); - driver->start(); - } + if (running) + startAnimationDriver(); } /*! @@ -604,6 +643,7 @@ void QAnimationTimer::restartAnimationTimer() void QAnimationTimer::startAnimations() { startAnimationPending = false; + //force timer to update, which prevents large deltas for our newly added animations if (!animations.isEmpty()) QUnifiedTimer::instance()->maybeUpdateAnimationsToCurrentTime(); @@ -749,20 +789,25 @@ QAnimationDriver::~QAnimationDriver() This is to take into account that pauses can occur in running animations which will stop the driver, but the time still increases. + + \obsolete + + This logic is now handled internally in the animation system. */ -void QAnimationDriver::setStartTime(qint64 startTime) +void QAnimationDriver::setStartTime(qint64) { - Q_D(QAnimationDriver); - d->startTime = startTime; } /*! Returns the start time of the animation. + + \obsolete + + This logic is now handled internally in the animation system. */ qint64 QAnimationDriver::startTime() const { - Q_D(const QAnimationDriver); - return d->startTime; + return 0; } @@ -772,6 +817,10 @@ qint64 QAnimationDriver::startTime() const If \a timeStep is positive, it will be used as the current time in the calculations; otherwise, the current clock time will be used. + + Since 5.4, the timeStep argument is ignored and elapsed() will be + used instead in combination with the internal time offsets of the + animation system. */ void QAnimationDriver::advanceAnimation(qint64 timeStep) diff --git a/src/corelib/animation/qabstractanimation.h b/src/corelib/animation/qabstractanimation.h index f1aa6c0d78..2d0a88e45f 100644 --- a/src/corelib/animation/qabstractanimation.h +++ b/src/corelib/animation/qabstractanimation.h @@ -149,6 +149,7 @@ public: virtual qint64 elapsed() const; + // ### Qt6: Remove these two functions void setStartTime(qint64 startTime); qint64 startTime() const; @@ -157,6 +158,7 @@ Q_SIGNALS: void stopped(); protected: + // ### Qt6: Remove timestep argument void advanceAnimation(qint64 timeStep = -1); virtual void start(); virtual void stop(); diff --git a/src/corelib/animation/qabstractanimation_p.h b/src/corelib/animation/qabstractanimation_p.h index 39d9cf0fe6..6e71356c4c 100644 --- a/src/corelib/animation/qabstractanimation_p.h +++ b/src/corelib/animation/qabstractanimation_p.h @@ -132,9 +132,8 @@ private: class Q_CORE_EXPORT QAnimationDriverPrivate : public QObjectPrivate { public: - QAnimationDriverPrivate() : running(false), startTime(0) {} + QAnimationDriverPrivate() : running(false) {} bool running; - qint64 startTime; }; class Q_CORE_EXPORT QAbstractAnimationTimer : public QObject @@ -193,6 +192,10 @@ public: int runningAnimationCount(); void registerProfilerCallback(void (*cb)(qint64)); + void startAnimationDriver(); + void stopAnimationDriver(); + qint64 elapsed() const; + protected: void timerEvent(QTimerEvent *); @@ -233,6 +236,9 @@ private: int closestPausedAnimationTimerTimeToFinish(); void (*profilerCallback)(qint64); + + qint64 driverStartTime; // The time the animation driver was started + qint64 temporalDrift; // The delta between animation driver time and wall time. }; class QAnimationTimer : public QAbstractAnimationTimer |