From 016695c7c79b05392daa09c1b9e07417f764e909 Mon Sep 17 00:00:00 2001 From: Kent Hansen Date: Thu, 5 Jul 2012 00:03:41 +0200 Subject: [PATCH] statemachine: Refactor {enter,exit}States() functions Move the computation of the sets of entered/exited states to separate functions. This separation is done in order to facilitate the integration of property assignments (QState::assignProperty()) into the core state machine algorithm. Change-Id: I5b7084e0e37037eb64909d217856746d81bf1878 Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/corelib/statemachine/qstatemachine.cpp | 45 ++++++++++++++-------- src/corelib/statemachine/qstatemachine_p.h | 8 +++- 2 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index b64a0f5eb3..8d5e26312f 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -371,12 +371,15 @@ void QStateMachinePrivate::microstep(QEvent *event, const QList exitedStates = exitStates(event, enabledTransitions); + QList exitedStates = computeStatesToExit(enabledTransitions); + QSet statesForDefaultEntry; + QList enteredStates = computeStatesToEnter(enabledTransitions, statesForDefaultEntry); + exitStates(event, exitedStates); #ifdef QSTATEMACHINE_DEBUG qDebug() << q_func() << ": configuration after exiting states:" << configuration; #endif executeTransitionContent(event, enabledTransitions); - QList enteredStates = enterStates(event, enabledTransitions); + enterStates(event, enteredStates, statesForDefaultEntry); #ifndef QT_NO_PROPERTIES if (!enteredStates.isEmpty()) // Ignore transitions with no targets applyProperties(enabledTransitions, exitedStates, enteredStates); @@ -387,9 +390,8 @@ void QStateMachinePrivate::microstep(QEvent *event, const QList QStateMachinePrivate::exitStates(QEvent *event, const QList &enabledTransitions) +QList QStateMachinePrivate::computeStatesToExit(const QList &enabledTransitions) { -// qDebug() << "exitStates(" << enabledTransitions << ')'; QSet statesToExit; // QSet statesToSnapshot; for (int i = 0; i < enabledTransitions.size(); ++i) { @@ -403,7 +405,7 @@ QList QStateMachinePrivate::exitStates(QEvent *event, const QLi setError(QStateMachine::NoCommonAncestorForTransitionError, t->sourceState()); lst = pendingErrorStates.toList(); lst.prepend(t->sourceState()); - + lca = findLCA(lst); Q_ASSERT(lca != 0); } @@ -419,6 +421,11 @@ QList QStateMachinePrivate::exitStates(QEvent *event, const QLi } QList statesToExit_sorted = statesToExit.toList(); qSort(statesToExit_sorted.begin(), statesToExit_sorted.end(), stateExitLessThan); + return statesToExit_sorted; +} + +void QStateMachinePrivate::exitStates(QEvent *event, const QList &statesToExit_sorted) +{ for (int i = 0; i < statesToExit_sorted.size(); ++i) { QAbstractState *s = statesToExit_sorted.at(i); if (QState *grp = toStandardState(s)) { @@ -452,7 +459,6 @@ QList QStateMachinePrivate::exitStates(QEvent *event, const QLi configuration.remove(s); QAbstractStatePrivate::get(s)->emitExited(); } - return statesToExit_sorted; } void QStateMachinePrivate::executeTransitionContent(QEvent *event, const QList &enabledTransitions) @@ -467,15 +473,10 @@ void QStateMachinePrivate::executeTransitionContent(QEvent *event, const QList QStateMachinePrivate::enterStates(QEvent *event, const QList &enabledTransitions) +QList QStateMachinePrivate::computeStatesToEnter(const QList &enabledTransitions, + QSet &statesForDefaultEntry) { -#ifdef QSTATEMACHINE_DEBUG - Q_Q(QStateMachine); -#endif -// qDebug() << "enterStates(" << enabledTransitions << ')'; QSet statesToEnter; - QSet statesForDefaultEntry; - if (pendingErrorStates.isEmpty()) { for (int i = 0; i < enabledTransitions.size(); ++i) { QAbstractTransition *t = enabledTransitions.at(i); @@ -486,12 +487,12 @@ QList QStateMachinePrivate::enterStates(QEvent *event, const QL QState *lca = findLCA(lst); for (int j = 1; j < lst.size(); ++j) { QAbstractState *s = lst.at(j); - addStatesToEnter(s, lca, statesToEnter, statesForDefaultEntry); + addStatesToEnter(s, lca, statesToEnter, statesForDefaultEntry); if (isParallel(lca)) { QList lcac = QStatePrivate::get(lca)->childStates(); foreach (QAbstractState* child,lcac) { if (!statesToEnter.contains(child)) - addStatesToEnter(child,lca,statesToEnter,statesForDefaultEntry); + addStatesToEnter(child,lca,statesToEnter,statesForDefaultEntry); } } } @@ -509,7 +510,15 @@ QList QStateMachinePrivate::enterStates(QEvent *event, const QL QList statesToEnter_sorted = statesToEnter.toList(); qSort(statesToEnter_sorted.begin(), statesToEnter_sorted.end(), stateEntryLessThan); + return statesToEnter_sorted; +} +void QStateMachinePrivate::enterStates(QEvent *event, const QList &statesToEnter_sorted, + const QSet &statesForDefaultEntry) +{ +#ifdef QSTATEMACHINE_DEBUG + Q_Q(QStateMachine); +#endif for (int i = 0; i < statesToEnter_sorted.size(); ++i) { QAbstractState *s = statesToEnter_sorted.at(i); #ifdef QSTATEMACHINE_DEBUG @@ -563,7 +572,6 @@ QList QStateMachinePrivate::enterStates(QEvent *event, const QL } } // qDebug() << "configuration:" << configuration.toList(); - return statesToEnter_sorted; } void QStateMachinePrivate::addStatesToEnter(QAbstractState *s, QState *root, @@ -1241,7 +1249,10 @@ void QStateMachinePrivate::_q_start() QEvent nullEvent(QEvent::None); executeTransitionContent(&nullEvent, transitions); - QList enteredStates = enterStates(&nullEvent, transitions); + QSet statesForDefaultEntry; + QList enteredStates = computeStatesToEnter(transitions, + statesForDefaultEntry); + enterStates(&nullEvent, enteredStates, statesForDefaultEntry); #ifndef QT_NO_PROPERTIES applyProperties(transitions, QList() << start, enteredStates); diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 333ec062b3..1dc5a266f6 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -135,9 +135,13 @@ public: void microstep(QEvent *event, const QList &transitionList); bool isPreempted(const QAbstractState *s, const QSet &transitions) const; QSet selectTransitions(QEvent *event) const; - QList exitStates(QEvent *event, const QList &transitionList); + void exitStates(QEvent *event, const QList &statesToExit_sorted); + QList computeStatesToExit(const QList &enabledTransitions); void executeTransitionContent(QEvent *event, const QList &transitionList); - QList enterStates(QEvent *event, const QList &enabledTransitions); + void enterStates(QEvent *event, const QList &statesToEnter_sorted, + const QSet &statesForDefaultEntry); + QList computeStatesToEnter(const QList &enabledTransitions, + QSet &statesForDefaultEntry); void addStatesToEnter(QAbstractState *s, QState *root, QSet &statesToEnter, QSet &statesForDefaultEntry);