diff options
Diffstat (limited to 'src/corelib/statemachine/qstatemachine.cpp')
-rw-r--r-- | src/corelib/statemachine/qstatemachine.cpp | 42 |
1 files changed, 38 insertions, 4 deletions
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index be48dbc92f..e6dfacc0f5 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -140,6 +140,10 @@ QT_BEGIN_NAMESPACE no error state applies to the erroneous state, the machine will stop executing and an error message will be printed to the console. + \note Important: setting the \l{ChildMode} of a state machine to parallel (\l{ParallelStates}) + results in an invalid state machine. It can only be set to (or kept as) + \l{ExclusiveStates}. + \sa QAbstractState, QAbstractTransition, QState, {The State Machine Framework} */ @@ -519,7 +523,7 @@ bool QStateMachinePrivate::stateExitLessThan(QAbstractState *s1, QAbstractState } } -QState *QStateMachinePrivate::findLCA(const QList<QAbstractState*> &states, bool onlyCompound) const +QState *QStateMachinePrivate::findLCA(const QList<QAbstractState*> &states, bool onlyCompound) { if (states.isEmpty()) return 0; @@ -538,10 +542,16 @@ QState *QStateMachinePrivate::findLCA(const QList<QAbstractState*> &states, bool if (ok) return anc; } - return 0; + + // Oops, this should never happen! The state machine itself is a common ancestor of all states, + // no matter what. But, for the onlyCompound case: we probably have a state machine whose + // childMode is set to parallel, which is illegal. However, we're stuck with it (and with + // exposing this invalid/dangerous API to users), so recover in the least horrible way. + setError(QStateMachine::StateMachineChildModeSetToParallelError, q_func()); + return q_func(); // make the statemachine the LCA/LCCA (which it should have been anyway) } -QState *QStateMachinePrivate::findLCCA(const QList<QAbstractState*> &states) const +QState *QStateMachinePrivate::findLCCA(const QList<QAbstractState*> &states) { return findLCA(states, true); } @@ -903,7 +913,7 @@ function getTransitionDomain(t) */ QAbstractState *QStateMachinePrivate::getTransitionDomain(QAbstractTransition *t, const QList<QAbstractState *> &effectiveTargetStates, - CalculationCache *cache) const + CalculationCache *cache) { Q_ASSERT(cache); @@ -1484,6 +1494,14 @@ void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractSta errorString = QStateMachine::tr("No common ancestor for targets and source of transition from state '%1'") .arg(currentContext->objectName()); break; + + case QStateMachine::StateMachineChildModeSetToParallelError: + Q_ASSERT(currentContext != nullptr); + + errorString = QStateMachine::tr("Child mode of state machine '%1' is not 'ExclusiveStates'!") + .arg(currentContext->objectName()); + break; + default: errorString = QStateMachine::tr("Unknown error"); }; @@ -2445,9 +2463,13 @@ QStateMachine::QStateMachine(QObject *parent) /*! \since 5.0 + \deprecated Constructs a new state machine with the given \a childMode and \a parent. + + \warning Do not set the \a childMode to anything else than \l{ExclusiveStates}, otherwise the + state machine is invalid, and might work incorrectly! */ QStateMachine::QStateMachine(QState::ChildMode childMode, QObject *parent) : QState(*new QStateMachinePrivate, /*parentState=*/0) @@ -2455,6 +2477,18 @@ QStateMachine::QStateMachine(QState::ChildMode childMode, QObject *parent) Q_D(QStateMachine); d->childMode = childMode; setParent(parent); // See comment in constructor above + + if (childMode != ExclusiveStates) { + //### FIXME for Qt6: remove this constructor completely, and hide the childMode property. + // Yes, the StateMachine itself is conceptually a state, but it should only expose a limited + // number of properties. The execution algorithm (in the URL below) treats a state machine + // as a state, but from an API point of view, it's questionable if the QStateMachine should + // inherit from QState. + // + // See function findLCCA in https://www.w3.org/TR/2014/WD-scxml-20140529/#AlgorithmforSCXMLInterpretation + // to see where setting childMode to parallel will break down. + qWarning() << "Invalid childMode for QStateMachine" << this; + } } /*! |