statemachine: Make states exit order spec-compliant

The SCXML spec states that entry order should be equivalent to
"document order" and exit order should be "reverse document order".
Since QStateMachine uses child order for the entry order, the exit
order should be reverse child order.

Change-Id: Ia7b05fdd5c9261ccf202f64f8d23f5c88b20a8c3
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
bb10
Kent Hansen 2012-08-01 10:28:10 +02:00 committed by Qt by Nokia
parent 305cdc7355
commit 3a2bc9530e
2 changed files with 18 additions and 9 deletions

View File

@ -274,8 +274,8 @@ bool QStateMachinePrivate::stateEntryLessThan(QAbstractState *s1, QAbstractState
bool QStateMachinePrivate::stateExitLessThan(QAbstractState *s1, QAbstractState *s2)
{
if (s1->parent() == s2->parent()) {
return s1->parent()->children().indexOf(s1)
< s2->parent()->children().indexOf(s2);
return s2->parent()->children().indexOf(s2)
< s1->parent()->children().indexOf(s1);
} else if (isDescendantOf(s1, s2)) {
return true;
} else if (isDescendantOf(s2, s1)) {
@ -285,7 +285,7 @@ bool QStateMachinePrivate::stateExitLessThan(QAbstractState *s1, QAbstractState
QStateMachinePrivate *mach = QStateMachinePrivate::get(s1->machine());
QState *lca = mach->findLCA(QList<QAbstractState*>() << s1 << s2);
Q_ASSERT(lca != 0);
return (indexOfDescendant(lca, s1) < indexOfDescendant(lca, s2));
return (indexOfDescendant(lca, s2) < indexOfDescendant(lca, s1));
}
}

View File

@ -222,6 +222,8 @@ public:
};
TestState(QState *parent)
: QState(parent) {}
TestState(ChildMode mode)
: QState(mode) {}
QList<QPair<int, Event> > events;
protected:
virtual void onEntry(QEvent *) {
@ -1857,7 +1859,7 @@ void tst_QStateMachine::parallelStates()
{
QStateMachine machine;
QState *s1 = new QState(QState::ParallelStates);
TestState *s1 = new TestState(QState::ParallelStates);
QCOMPARE(s1->childMode(), QState::ParallelStates);
TestState *s1_1 = new TestState(s1);
QState *s1_1_1 = new QState(s1_1);
@ -1891,19 +1893,26 @@ void tst_QStateMachine::parallelStates()
QCOMPARE(machine.configuration().size(), 1);
QVERIFY(machine.configuration().contains(s2));
QCOMPARE(s1->events.count(), 2);
// s1 is entered
QCOMPARE(s1->events.at(0).first, 0);
QCOMPARE(s1->events.at(0).second, TestState::Entry);
// s1_1 is entered
QCOMPARE(s1_1->events.count(), 2);
QCOMPARE(s1_1->events.at(0).first, 0);
QCOMPARE(s1_1->events.at(0).first, 1);
QCOMPARE(s1_1->events.at(0).second, TestState::Entry);
// s1_2 is entered
QCOMPARE(s1_2->events.at(0).first, 1);
QCOMPARE(s1_2->events.at(0).first, 2);
QCOMPARE(s1_2->events.at(0).second, TestState::Entry);
// s1_1 is exited
QCOMPARE(s1_1->events.at(1).first, 2);
QCOMPARE(s1_1->events.at(1).second, TestState::Exit);
// s1_2 is exited
QCOMPARE(s1_2->events.at(1).first, 3);
QCOMPARE(s1_2->events.at(1).second, TestState::Exit);
// s1_1 is exited
QCOMPARE(s1_1->events.at(1).first, 4);
QCOMPARE(s1_1->events.at(1).second, TestState::Exit);
// s1 is exited
QCOMPARE(s1->events.at(1).first, 5);
QCOMPARE(s1->events.at(1).second, TestState::Exit);
}
void tst_QStateMachine::parallelRootState()