statemachine: Make states exit order spec-compliant
authorKent Hansen <kent.hansen@nokia.com>
Wed, 1 Aug 2012 08:28:10 +0000 (10:28 +0200)
committerQt by Nokia <qt-info@nokia.com>
Wed, 1 Aug 2012 13:37:46 +0000 (15:37 +0200)
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>
src/corelib/statemachine/qstatemachine.cpp
tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp

index b697388..1fe7f96 100644 (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));
     }
 }
 
index e4a26d6..dd03664 100644 (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()