Enter initial state before QStateMachine::started() is emitted
authorKent Hansen <kent.hansen@nokia.com>
Thu, 31 May 2012 11:33:14 +0000 (13:33 +0200)
committerQt by Nokia <qt-info@nokia.com>
Mon, 4 Jun 2012 14:53:42 +0000 (16:53 +0200)
The documentation says that started() "is emitted when the state
machine has entered its initial state", but the implementation
didn't adhere to that.

The consequence is that if you e.g. emitted a signal from a slot
connected to started(), and that signal was used by a transition
from the initial state, the signal would effectively get ignored and
the state machine would remain in the initial state.

Task-number: QTBUG-24307
Change-Id: Ibbeb627d517eaff821d88e256a949eacf6aae350
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>
src/corelib/statemachine/qstatemachine.cpp
tests/auto/corelib/statemachine/qstatemachine/tst_qstatemachine.cpp

index fd190ab..ffe2e74 100644 (file)
@@ -1203,7 +1203,6 @@ void QStateMachinePrivate::_q_start()
 #endif
     state = Running;
     processingScheduled = true; // we call _q_process() below
-    emit q->started();
 
     QState *start = startState();
     Q_ASSERT(start != 0);
@@ -1230,6 +1229,9 @@ void QStateMachinePrivate::_q_start()
 #ifdef QSTATEMACHINE_DEBUG
     qDebug() << q << ": initial configuration:" << configuration;
 #endif
+
+    emit q->started();
+
     _q_process();
 }
 
index df6ac88..34e9b74 100644 (file)
@@ -175,6 +175,8 @@ private slots:
     void stopInTransitionToFinalState();
     void stopInEventTest_data();
     void stopInEventTest();
+
+    void initialStateIsEnteredBeforeStartedEmitted();
 };
 
 class TestState : public QState
@@ -3906,5 +3908,21 @@ void tst_QStateMachine::stopInEventTest()
     QVERIFY(machine.configuration().contains(s1));
 }
 
+void tst_QStateMachine::initialStateIsEnteredBeforeStartedEmitted()
+{
+    QStateMachine machine;
+    QState *s1 = new QState(&machine);
+    machine.setInitialState(s1);
+    QFinalState *s2 = new QFinalState(&machine);
+
+    // When started() is emitted, s1 should be the active state, and this
+    // transition should trigger.
+    s1->addTransition(&machine, SIGNAL(started()), s2);
+
+    QSignalSpy finishedSpy(&machine, SIGNAL(finished()));
+    machine.start();
+    QTRY_COMPARE(finishedSpy.count(), 1);
+}
+
 QTEST_MAIN(tst_QStateMachine)
 #include "tst_qstatemachine.moc"