diff options
-rw-r--r-- | src/scxml/qscxmlstatemachine.cpp | 26 | ||||
-rw-r--r-- | src/scxml/qscxmlstatemachine_p.h | 4 | ||||
-rw-r--r-- | tests/auto/statemachine/historystate.scxml | 13 | ||||
-rw-r--r-- | tests/auto/statemachine/tst_statemachine.cpp | 19 | ||||
-rw-r--r-- | tests/auto/statemachine/tst_statemachine.qrc | 1 |
5 files changed, 62 insertions, 1 deletions
diff --git a/src/scxml/qscxmlstatemachine.cpp b/src/scxml/qscxmlstatemachine.cpp index e57630f..9767a03 100644 --- a/src/scxml/qscxmlstatemachine.cpp +++ b/src/scxml/qscxmlstatemachine.cpp @@ -731,7 +731,9 @@ void QScxmlStateMachinePrivate::emitStateActive(int stateIndex, bool active) { Q_Q(QScxmlStateMachine); void *args[] = { Q_NULLPTR, const_cast<void*>(reinterpret_cast<const void*>(&active)) }; - QMetaObject::activate(q, m_metaObject, stateIndex, args); + const int signalIndex = m_stateIndexToSignalIndex.value(stateIndex, -1); + if (signalIndex >= 0) + QMetaObject::activate(q, m_metaObject, signalIndex, args); } void QScxmlStateMachinePrivate::emitInvokedServicesChanged() @@ -755,6 +757,26 @@ void QScxmlStateMachinePrivate::attach(QScxmlStateMachineInfo *info) info, &QScxmlStateMachineInfo::transitionsTriggered); } +void QScxmlStateMachinePrivate::updateMetaCache() +{ + m_stateIndexToSignalIndex.clear(); + + if (!m_tableData) + return; + + if (!m_stateTable) + return; + + int signalIndex = 0; + for (int i = 0; i < m_stateTable->stateCount; ++i) { + const auto &s = m_stateTable->state(i); + if (!s.isHistoryState() && s.type != StateTable::State::Invalid) { + m_stateIndexToSignalIndex.insert(i, signalIndex); + ++signalIndex; + } + } +} + QStringList QScxmlStateMachinePrivate::stateNames(const std::vector<int> &stateIndexes) const { QStringList names; @@ -1767,6 +1789,8 @@ void QScxmlStateMachine::setTableData(QScxmlTableData *tableData) == QScxmlExecutableContent::StateTable::terminator); } + d->updateMetaCache(); + emit tableDataChanged(tableData); } diff --git a/src/scxml/qscxmlstatemachine_p.h b/src/scxml/qscxmlstatemachine_p.h index bfa7bc1..388dd8d 100644 --- a/src/scxml/qscxmlstatemachine_p.h +++ b/src/scxml/qscxmlstatemachine_p.h @@ -283,6 +283,8 @@ public: void attach(QScxmlStateMachineInfo *info); const OrderedSet &configuration() const { return m_configuration; } + void updateMetaCache(); + private: QStringList stateNames(const std::vector<int> &stateIndexes) const; std::vector<int> historyStates(int stateIdx) const; @@ -379,6 +381,8 @@ private: bool isPaused() const { return m_runningState == Paused; } QScxmlInternal::StateMachineInfoProxy *m_infoSignalProxy; + + QHash<int, int> m_stateIndexToSignalIndex; }; QT_END_NAMESPACE diff --git a/tests/auto/statemachine/historystate.scxml b/tests/auto/statemachine/historystate.scxml new file mode 100644 index 0000000..4b3a5e4 --- /dev/null +++ b/tests/auto/statemachine/historystate.scxml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" binding="early" name="HistoryState"> + <state id="Working"> + <state id="State1"> + <onentry> + <send event="timeout" delay="1s"/> + </onentry> + </state> + <history type="shallow" id="HistoryState"/> + <transition type="external" event="timeout" target="State2"/> + </state> + <state id="State2"/> +</scxml> diff --git a/tests/auto/statemachine/tst_statemachine.cpp b/tests/auto/statemachine/tst_statemachine.cpp index ed1f424..69d38b6 100644 --- a/tests/auto/statemachine/tst_statemachine.cpp +++ b/tests/auto/statemachine/tst_statemachine.cpp @@ -48,6 +48,7 @@ private Q_SLOTS: void activeStateNames_data(); void activeStateNames(); void connections(); + void historyState(); void onExit(); void eventOccurred(); @@ -251,6 +252,24 @@ void tst_StateMachine::connections() #endif } +void tst_StateMachine::historyState() +{ + QScopedPointer<QScxmlStateMachine> stateMachine( + QScxmlStateMachine::fromFile(QString(":/tst_statemachine/historystate.scxml"))); + QVERIFY(!stateMachine.isNull()); + + bool state2Reached = false; + QMetaObject::Connection state2Connection = stateMachine->connectToState("State2", + [&state2Reached](bool enabled) { + state2Reached = state2Reached || enabled; + }); + QVERIFY(state2Connection); + + stateMachine->start(); + + QTRY_VERIFY(state2Reached); +} + void tst_StateMachine::onExit() { #if defined(__cpp_return_type_deduction) && __cpp_return_type_deduction == 201304 diff --git a/tests/auto/statemachine/tst_statemachine.qrc b/tests/auto/statemachine/tst_statemachine.qrc index c31fe4c..78c1f00 100644 --- a/tests/auto/statemachine/tst_statemachine.qrc +++ b/tests/auto/statemachine/tst_statemachine.qrc @@ -6,5 +6,6 @@ <file>ids1.scxml</file> <file>stateDotDoneEvent.scxml</file> <file>invoke.scxml</file> + <file>historystate.scxml</file> </qresource> </RCC> |