From 9e6311a7fd23a9fb7bb3a8a8edc78cddddc3f807 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Thu, 30 Apr 2009 09:49:09 +0200 Subject: The intuitive interpretation of RestoreProperties is that a value is potentially restored once the state that set it is exited. So if you have a parent state P which sets 'foo' and then several child states of P, the property should not be restored as long as P is active, regardless of which transitions are taken inside P and what properties are being assigned there. Before, we would restore the property when we entered a state that did not assign it, ignoring what properties where being assigned in the parent. --- src/corelib/statemachine/qstatemachine.cpp | 11 +++++ tests/auto/qstatemachine/tst_qstatemachine.cpp | 56 +++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/corelib/statemachine/qstatemachine.cpp b/src/corelib/statemachine/qstatemachine.cpp index 9060f0e..81d65d5 100644 --- a/src/corelib/statemachine/qstatemachine.cpp +++ b/src/corelib/statemachine/qstatemachine.cpp @@ -656,6 +656,17 @@ void QStateMachinePrivate::applyProperties(const QList &tr pendingRestorables.remove(RestorableId(assn.object, assn.propertyName)); propertyAssignmentsForState[s].append(assn); } + + // Remove pending restorables for all parent states to avoid restoring properties + // before the state that assigned them is exited. + QState *parentState = s; + while (parentState = parentState->parentState()) { + assignments = QStatePrivate::get(parentState)->propertyAssignments; + for (int j=0; jsetProperty("foo", 1); + propertyHolder->setProperty("bar", 2); + + QState *s1 = new QState(machine.rootState()); + machine.setInitialState(s1); + + QState *s2 = new QState(machine.rootState()); + s2->assignProperty(propertyHolder, "foo", 3); + + QState *s21 = new QState(s2); + s21->assignProperty(propertyHolder, "bar", 4); + s2->setInitialState(s21); + + QState *s22 = new QState(s2); + s22->assignProperty(propertyHolder, "bar", 5); + + s1->addTransition(new EventTransition(QEvent::User, s2)); + s21->addTransition(new EventTransition(QEvent::User, s22)); + + machine.start(); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 1); + QVERIFY(machine.configuration().contains(s1)); + QCOMPARE(propertyHolder->property("foo").toInt(), 1); + QCOMPARE(propertyHolder->property("bar").toInt(), 2); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s21)); + QCOMPARE(propertyHolder->property("foo").toInt(), 3); + QCOMPARE(propertyHolder->property("bar").toInt(), 4); + + machine.postEvent(new QEvent(QEvent::User)); + QCoreApplication::processEvents(); + + QCOMPARE(machine.configuration().size(), 2); + QVERIFY(machine.configuration().contains(s2)); + QVERIFY(machine.configuration().contains(s22)); + QCOMPARE(propertyHolder->property("foo").toInt(), 3); + QCOMPARE(propertyHolder->property("bar").toInt(), 5); +} + + QTEST_MAIN(tst_QStateMachine) #include "tst_qstatemachine.moc" -- cgit v0.12