From be55ecac61d88beb250ae6deedef405c031bcdac Mon Sep 17 00:00:00 2001 From: Erik Verbruggen Date: Tue, 8 Sep 2015 15:17:50 +0200 Subject: [PATCH] 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 --- src/corelib/statemachine/qstatemachine.cpp | 8 ++++++++ src/corelib/statemachine/qstatemachine_p.h | 1 + 2 files changed, 9 insertions(+) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 687f676819..c5e251b37b 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -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) { diff --git a/src/corelib/statemachine/qstatemachine_p.h b/src/corelib/statemachine/qstatemachine_p.h index 4419ebc7f3..fe7a06d16b 100644 --- a/src/corelib/statemachine/qstatemachine_p.h +++ b/src/corelib/statemachine/qstatemachine_p.h @@ -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 &statesToExit_sorted, const QHash > &assignmentsForEnteredStates); QList computeExitSet(const QList &enabledTransitions, CalculationCache *cache);