src/corelib/animation/qabstractanimation.cpp
changeset 30 5dc02b23752f
parent 18 2f34d5167611
child 33 3e2da88830cd
--- a/src/corelib/animation/qabstractanimation.cpp	Wed Jun 23 19:07:03 2010 +0300
+++ b/src/corelib/animation/qabstractanimation.cpp	Tue Jul 06 15:10:48 2010 +0300
@@ -161,31 +161,46 @@
 
 QT_BEGIN_NAMESPACE
 
+#ifndef QT_NO_THREAD
 Q_GLOBAL_STATIC(QThreadStorage<QUnifiedTimer *>, unifiedTimer)
+#endif
 
 QUnifiedTimer::QUnifiedTimer() :
     QObject(), lastTick(0), timingInterval(DEFAULT_TIMER_INTERVAL),
     currentAnimationIdx(0), consistentTiming(false), slowMode(false),
     isPauseTimerActive(false), runningLeafAnimations(0)
 {
+    time.invalidate();
 }
 
-QUnifiedTimer *QUnifiedTimer::instance()
+
+QUnifiedTimer *QUnifiedTimer::instance(bool create)
 {
     QUnifiedTimer *inst;
-    if (!unifiedTimer()->hasLocalData()) {
+#ifndef QT_NO_THREAD
+    if (create && !unifiedTimer()->hasLocalData()) {
         inst = new QUnifiedTimer;
         unifiedTimer()->setLocalData(inst);
     } else {
         inst = unifiedTimer()->localData();
     }
+#else
+    static QUnifiedTimer unifiedTimer;
+    inst = &unifiedTimer;
+#endif
     return inst;
 }
 
+QUnifiedTimer *QUnifiedTimer::instance()
+{
+    return instance(true);
+}
+
 void QUnifiedTimer::ensureTimerUpdate()
 {
-    if (isPauseTimerActive)
-        updateAnimationsTime();
+    QUnifiedTimer *inst = QUnifiedTimer::instance(false);
+    if (inst && inst->isPauseTimerActive)
+        inst->updateAnimationsTime();
 }
 
 void QUnifiedTimer::updateAnimationsTime()
@@ -211,6 +226,13 @@
     }
 }
 
+void QUnifiedTimer::updateAnimationTimer()
+{
+    QUnifiedTimer *inst = QUnifiedTimer::instance(false);
+    if (inst)
+        inst->restartAnimationTimer();
+}
+
 void QUnifiedTimer::restartAnimationTimer()
 {
     if (runningLeafAnimations == 0 && !runningPauseAnimations.isEmpty()) {
@@ -242,7 +264,7 @@
             animationTimer.stop();
             isPauseTimerActive = false;
             // invalidate the start reference time
-            time = QTime();
+            time.invalidate();
         } else {
             restartAnimationTimer();
             if (!time.isValid()) {
@@ -261,34 +283,41 @@
 
 void QUnifiedTimer::registerAnimation(QAbstractAnimation *animation, bool isTopLevel)
 {
-    registerRunningAnimation(animation);
+    QUnifiedTimer *inst = instance(true); //we create the instance if needed
+    inst->registerRunningAnimation(animation);
     if (isTopLevel) {
         Q_ASSERT(!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer);
         QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer = true;
-        animationsToStart << animation;
-        if (!startStopAnimationTimer.isActive())
-            startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, this);
+        inst->animationsToStart << animation;
+        if (!inst->startStopAnimationTimer.isActive())
+            inst->startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, inst);
     }
 }
 
 void QUnifiedTimer::unregisterAnimation(QAbstractAnimation *animation)
 {
-    unregisterRunningAnimation(animation);
+    QUnifiedTimer *inst = QUnifiedTimer::instance(false);
+    if (inst) {
+        //at this point the unified timer should have been created
+        //but it might also have been already destroyed in case the application is shutting down
 
-    if (!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer)
-        return;
+        inst->unregisterRunningAnimation(animation);
+
+        if (!QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer)
+            return;
 
-    int idx = animations.indexOf(animation);
-    if (idx != -1) {
-        animations.removeAt(idx);
-        // this is needed if we unregister an animation while its running
-        if (idx <= currentAnimationIdx)
-            --currentAnimationIdx;
+        int idx = inst->animations.indexOf(animation);
+        if (idx != -1) {
+            inst->animations.removeAt(idx);
+            // this is needed if we unregister an animation while its running
+            if (idx <= inst->currentAnimationIdx)
+                --inst->currentAnimationIdx;
 
-        if (animations.isEmpty() && !startStopAnimationTimer.isActive())
-            startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, this);
-    } else {
-        animationsToStart.removeOne(animation);
+            if (inst->animations.isEmpty() && !inst->startStopAnimationTimer.isActive())
+                inst->startStopAnimationTimer.start(STARTSTOP_TIMER_DELAY, inst);
+        } else {
+            inst->animationsToStart.removeOne(animation);
+        }
     }
     QAbstractAnimationPrivate::get(animation)->hasRegisteredTimer = false;
 }
@@ -340,6 +369,9 @@
     if (state == newState)
         return;
 
+    if (loopCount == 0)
+        return;
+
     QAbstractAnimation::State oldState = state;
     int oldCurrentTime = currentTime;
     int oldCurrentLoop = currentLoop;
@@ -363,11 +395,11 @@
     bool isTopLevel = !group || group->state() == QAbstractAnimation::Stopped;
     if (oldState == QAbstractAnimation::Running) {
         if (newState == QAbstractAnimation::Paused && hasRegisteredTimer)
-            QUnifiedTimer::instance()->ensureTimerUpdate();
+            QUnifiedTimer::ensureTimerUpdate();
         //the animation, is not running any more
-        QUnifiedTimer::instance()->unregisterAnimation(q);
+        QUnifiedTimer::unregisterAnimation(q);
     } else if (newState == QAbstractAnimation::Running) {
-        QUnifiedTimer::instance()->registerAnimation(q, isTopLevel);
+        QUnifiedTimer::registerAnimation(q, isTopLevel);
     }
 
     q->updateState(newState, oldState);
@@ -389,7 +421,7 @@
             if (oldState == QAbstractAnimation::Stopped) {
                 if (isTopLevel) {
                     // currentTime needs to be updated if pauseTimer is active
-                    QUnifiedTimer::instance()->ensureTimerUpdate();
+                    QUnifiedTimer::ensureTimerUpdate();
                     q->setCurrentTime(totalCurrentTime);
                 }
             }
@@ -448,7 +480,7 @@
         d->state = Stopped;
         emit stateChanged(oldState, d->state);
         if (oldState == QAbstractAnimation::Running)
-            QUnifiedTimer::instance()->unregisterAnimation(this);
+            QUnifiedTimer::unregisterAnimation(this);
     }
 }
 
@@ -547,14 +579,14 @@
     // the commands order below is important: first we need to setCurrentTime with the old direction,
     // then update the direction on this and all children and finally restart the pauseTimer if needed
     if (d->hasRegisteredTimer)
-        QUnifiedTimer::instance()->ensureTimerUpdate();
+        QUnifiedTimer::ensureTimerUpdate();
 
     d->direction = direction;
     updateDirection(direction);
 
     if (d->hasRegisteredTimer)
         // needed to update the timer interval in case of a pause animation
-        QUnifiedTimer::instance()->restartAnimationTimer();
+        QUnifiedTimer::updateAnimationTimer();
 
     emit directionChanged(direction);
 }