diff options
author | Kent Hansen <khansen@trolltech.com> | 2009-09-29 09:59:01 (GMT) |
---|---|---|
committer | Kent Hansen <khansen@trolltech.com> | 2009-09-29 10:02:09 (GMT) |
commit | 39604894946c3c0d623c0073ccf027a8e6df120a (patch) | |
tree | cb6fa13f922365d151cbc5597343560a56f19037 /src/corelib/statemachine | |
parent | d557d6e5dc73c88f9de26bf2e3dd2c6955400467 (diff) | |
download | Qt-39604894946c3c0d623c0073ccf027a8e6df120a.zip Qt-39604894946c3c0d623c0073ccf027a8e6df120a.tar.gz Qt-39604894946c3c0d623c0073ccf027a8e6df120a.tar.bz2 |
Do synchronous processing of events in state machine if possible
Avoid delayed scheduling in the cases where there's no need to
delay it (e.g. when the state machine intercepts a signal or event).
Task-number: QTBUG-4491
Reviewed-by: Eskil Abrahamsen Blomfeldt
Diffstat (limited to 'src/corelib/statemachine')
-rw-r--r-- | src/corelib/statemachine/qstatemachine.cpp | 46 | ||||
-rw-r--r-- | src/corelib/statemachine/qstatemachine_p.h | 7 |
2 files changed, 40 insertions, 13 deletions
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 503eec0..8d50870c 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -804,6 +804,14 @@ void QStateMachinePrivate::applyProperties(const QList<QAbstractTransition*> &tr } if (hasValidEndValue) { + if (anim->state() == QAbstractAnimation::Running) { + // The animation is still running. This can happen if the + // animation is a group, and one of its children just finished, + // and that caused a state to emit its polished() signal, and + // that triggered a transition in the machine. + // Just stop the animation so it is correctly restarted again. + anim->stop(); + } anim->start(); } } @@ -1268,12 +1276,19 @@ void QStateMachinePrivate::_q_process() } } -void QStateMachinePrivate::scheduleProcess() +void QStateMachinePrivate::processEvents(EventProcessingMode processingMode) { if ((state != Running) || processing || processingScheduled) return; - processingScheduled = true; - QMetaObject::invokeMethod(q_func(), "_q_process", Qt::QueuedConnection); + switch (processingMode) { + case DirectProcessing: + _q_process(); + break; + case QueuedProcessing: + processingScheduled = true; + QMetaObject::invokeMethod(q_func(), "_q_process", Qt::QueuedConnection); + break; + } } namespace { @@ -1335,7 +1350,7 @@ void QStateMachinePrivate::goToState(QAbstractState *targetState) trans->setTargetState(targetState); } - scheduleProcess(); + processEvents(QueuedProcessing); } void QStateMachinePrivate::registerTransitions(QAbstractState *state) @@ -1512,6 +1527,15 @@ void QStateMachinePrivate::unregisterEventTransition(QEventTransition *transitio } QEventTransitionPrivate::get(transition)->registered = false; } + +void QStateMachinePrivate::handleFilteredEvent(QObject *watched, QEvent *event) +{ + Q_ASSERT(qobjectEvents.contains(watched)); + if (qobjectEvents[watched].contains(event->type())) { + internalEventQueue.append(new QStateMachine::WrappedEvent(watched, handler->cloneEvent(event))); + processEvents(DirectProcessing); + } +} #endif void QStateMachinePrivate::handleTransitionSignal(QObject *sender, int signalIndex, @@ -1533,7 +1557,7 @@ void QStateMachinePrivate::handleTransitionSignal(QObject *sender, int signalInd << ", signal =" << sender->metaObject()->method(signalIndex).signature() << ')'; #endif internalEventQueue.append(new QStateMachine::SignalEvent(sender, signalIndex, vargs)); - scheduleProcess(); + processEvents(DirectProcessing); } /*! @@ -1768,7 +1792,7 @@ void QStateMachine::stop() break; case QStateMachinePrivate::Running: d->stop = true; - d->scheduleProcess(); + d->processEvents(QStateMachinePrivate::QueuedProcessing); break; } } @@ -1798,7 +1822,7 @@ void QStateMachine::postEvent(QEvent *event, int delay) d->delayedEvents[tid] = event; } else { d->externalEventQueue.append(event); - d->scheduleProcess(); + d->processEvents(QStateMachinePrivate::QueuedProcessing); } } @@ -1814,7 +1838,7 @@ void QStateMachine::postInternalEvent(QEvent *event) qDebug() << this << ": posting internal event" << event; #endif d->internalEventQueue.append(event); - d->scheduleProcess(); + d->processEvents(QStateMachinePrivate::QueuedProcessing); } /*! @@ -1862,7 +1886,7 @@ bool QStateMachine::event(QEvent *e) killTimer(tid); QEvent *ee = d->delayedEvents.take(tid); d->externalEventQueue.append(ee); - d->scheduleProcess(); + d->processEvents(QStateMachinePrivate::DirectProcessing); return true; } } @@ -1876,9 +1900,7 @@ bool QStateMachine::event(QEvent *e) bool QStateMachine::eventFilter(QObject *watched, QEvent *event) { Q_D(QStateMachine); - Q_ASSERT(d->qobjectEvents.contains(watched)); - if (d->qobjectEvents[watched].contains(event->type())) - postEvent(new QStateMachine::WrappedEvent(watched, d->handler->cloneEvent(event))); + d->handleFilteredEvent(watched, event); return false; } #endif diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index a1b6de2..141bc5c 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -88,6 +88,10 @@ public: Starting, Running }; + enum EventProcessingMode { + DirectProcessing, + QueuedProcessing + }; enum StopProcessingReason { EventQueueEmpty, Finished, @@ -149,12 +153,13 @@ public: #ifndef QT_NO_STATEMACHINE_EVENTFILTER void registerEventTransition(QEventTransition *transition); void unregisterEventTransition(QEventTransition *transition); + void handleFilteredEvent(QObject *watched, QEvent *event); #endif void unregisterTransition(QAbstractTransition *transition); void unregisterAllTransitions(); void handleTransitionSignal(QObject *sender, int signalIndex, void **args); - void scheduleProcess(); + void processEvents(EventProcessingMode processingMode); #ifndef QT_NO_PROPERTIES typedef QPair<QObject *, QByteArray> RestorableId; |