--- 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);
}