Add a method to detect when the state-machine can exit.

According to the SCXML specification, the state-machine can exit the
interpreter loop when a final state has been reached. This happens after
finishing a macro-step or when it ends up in a final state right after
startup (e.g. when the only state is a final state). This patch adds a
virtual method which can be used to detect this reliably.

Change-Id: I594e952a4972dd70d4089a2c4ce1c86880568eb9
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
This commit is contained in:
Erik Verbruggen 2015-09-08 15:17:50 +02:00
parent 0e342fce4c
commit be55ecac61
2 changed files with 9 additions and 0 deletions

View File

@ -1834,6 +1834,7 @@ void QStateMachinePrivate::_q_start()
unregisterAllTransitions();
emitFinished();
emit q->runningChanged(false);
exitInterpreter();
} else {
_q_process();
}
@ -1928,6 +1929,8 @@ void QStateMachinePrivate::_q_process()
break;
}
endMacrostep(didChange);
if (stopProcessingReason == Finished)
exitInterpreter();
}
void QStateMachinePrivate::_q_startDelayedEventTimer(int id, int delay)
@ -2057,6 +2060,8 @@ void QStateMachinePrivate::noMicrostep()
4) the state machine either enters an infinite loop, or stops (runningChanged(false),
and either finished or stopped are emitted), or processedPendingEvents() is called.
5) if the machine is not in an infinite loop endMacrostep is called
6) when the machine is finished and all processing (like signal emission) is done,
exitInterpreter() is called. (This is the same name as the SCXML specification uses.)
didChange is set to true if at least one microstep was performed, it is possible
that the machine returned to exactly the same state as before, but some transitions
@ -2077,6 +2082,9 @@ void QStateMachinePrivate::endMacrostep(bool didChange)
Q_UNUSED(didChange);
}
void QStateMachinePrivate::exitInterpreter()
{
}
void QStateMachinePrivate::emitStateFinished(QState *forState, QFinalState *guiltyState)
{

View File

@ -133,6 +133,7 @@ public:
virtual void processedPendingEvents(bool didChange);
virtual void beginMacrostep();
virtual void endMacrostep(bool didChange);
virtual void exitInterpreter();
void exitStates(QEvent *event, const QList<QAbstractState *> &statesToExit_sorted,
const QHash<QAbstractState*, QVector<QPropertyAssignment> > &assignmentsForEnteredStates);
QList<QAbstractState*> computeExitSet(const QList<QAbstractTransition*> &enabledTransitions, CalculationCache *cache);