summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/statemachine/qstatemachine.cpp48
-rw-r--r--src/corelib/statemachine/qstatemachine.h1
-rw-r--r--tests/auto/qstatemachine/tst_qstatemachine.cpp5
3 files changed, 36 insertions, 18 deletions
diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp
index 41d4c6c..efcf707 100644
--- a/src/corelib/statemachine/qstatemachine.cpp
+++ b/src/corelib/statemachine/qstatemachine.cpp
@@ -409,6 +409,15 @@ QList<QAbstractState*> QStateMachinePrivate::exitStates(QEvent *event, const QLi
continue;
lst.prepend(t->sourceState());
QAbstractState *lca = findLCA(lst);
+ if (lca == 0) {
+ setError(QStateMachine::NoCommonAncestorForTransitionError, t->sourceState());
+ lst = pendingErrorStates.toList();
+ lst.prepend(t->sourceState());
+
+ lca = findLCA(lst);
+ Q_ASSERT(lca != 0);
+ }
+
{
QSet<QAbstractState*>::const_iterator it;
for (it = configuration.constBegin(); it != configuration.constEnd(); ++it) {
@@ -476,21 +485,23 @@ QList<QAbstractState*> QStateMachinePrivate::enterStates(QEvent *event, const QL
QSet<QAbstractState*> statesToEnter;
QSet<QAbstractState*> statesForDefaultEntry;
- for (int i = 0; i < enabledTransitions.size(); ++i) {
- QAbstractTransition *t = enabledTransitions.at(i);
- QList<QAbstractState*> lst = t->targetStates();
- if (lst.isEmpty())
- continue;
- lst.prepend(t->sourceState());
- QState *lca = findLCA(lst);
- for (int j = 1; j < lst.size(); ++j) {
- QAbstractState *s = lst.at(j);
- addStatesToEnter(s, lca, statesToEnter, statesForDefaultEntry);
- if (isParallel(lca)) {
- QList<QAbstractState*> lcac = QStatePrivate::get(lca)->childStates();
- foreach (QAbstractState* child,lcac) {
- if (!statesToEnter.contains(child))
- addStatesToEnter(child,lca,statesToEnter,statesForDefaultEntry);
+ if (pendingErrorStates.isEmpty()) {
+ for (int i = 0; i < enabledTransitions.size(); ++i) {
+ QAbstractTransition *t = enabledTransitions.at(i);
+ QList<QAbstractState*> lst = t->targetStates();
+ if (lst.isEmpty())
+ continue;
+ lst.prepend(t->sourceState());
+ QState *lca = findLCA(lst);
+ for (int j = 1; j < lst.size(); ++j) {
+ QAbstractState *s = lst.at(j);
+ addStatesToEnter(s, lca, statesToEnter, statesForDefaultEntry);
+ if (isParallel(lca)) {
+ QList<QAbstractState*> lcac = QStatePrivate::get(lca)->childStates();
+ foreach (QAbstractState* child,lcac) {
+ if (!statesToEnter.contains(child))
+ addStatesToEnter(child,lca,statesToEnter,statesForDefaultEntry);
+ }
}
}
}
@@ -976,6 +987,13 @@ void QStateMachinePrivate::setError(QStateMachine::Error errorCode, QAbstractSta
errorString = QStateMachine::tr("Missing default state in history state '%1'")
.arg(currentContext->objectName());
break;
+
+ case QStateMachine::NoCommonAncestorForTransitionError:
+ Q_ASSERT(currentContext != 0);
+
+ errorString = QStateMachine::tr("No common ancestor for targets and source of transition from state '%1'")
+ .arg(currentContext->objectName());
+ break;
default:
errorString = QStateMachine::tr("Unknown error");
};
diff --git a/src/corelib/statemachine/qstatemachine.h b/src/corelib/statemachine/qstatemachine.h
index 10bd443..d0927a3 100644
--- a/src/corelib/statemachine/qstatemachine.h
+++ b/src/corelib/statemachine/qstatemachine.h
@@ -87,6 +87,7 @@ public:
NoError,
NoInitialStateError,
NoDefaultStateInHistoryState,
+ NoCommonAncestorForTransitionError
};
QStateMachine(QObject *parent = 0);
diff --git a/tests/auto/qstatemachine/tst_qstatemachine.cpp b/tests/auto/qstatemachine/tst_qstatemachine.cpp
index 8026d6e..e7ea403 100644
--- a/tests/auto/qstatemachine/tst_qstatemachine.cpp
+++ b/tests/auto/qstatemachine/tst_qstatemachine.cpp
@@ -919,8 +919,6 @@ void tst_QStateMachine::brokenStateIsNeverEntered()
void tst_QStateMachine::transitionToStateNotInGraph()
{
- QSKIP("Hangs", SkipAll);
-
s_countWarnings = false;
QStateMachine machine;
@@ -930,13 +928,14 @@ void tst_QStateMachine::transitionToStateNotInGraph()
machine.setInitialState(initialState);
QState *independentState = new QState();
+ independentState->setObjectName("independentState");
initialState->addTransition(independentState);
machine.start();
QCoreApplication::processEvents();
QCOMPARE(machine.configuration().count(), 1);
- QVERIFY(machine.configuration().contains(initialState));
+ QVERIFY(machine.configuration().contains(qobject_cast<QState*>(machine.rootState())->errorState()));
}
void tst_QStateMachine::customErrorStateNotInGraph()