summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/scxml/qscxmlstatemachine.cpp26
-rw-r--r--src/scxml/qscxmlstatemachine_p.h4
-rw-r--r--tests/auto/statemachine/historystate.scxml13
-rw-r--r--tests/auto/statemachine/tst_statemachine.cpp19
-rw-r--r--tests/auto/statemachine/tst_statemachine.qrc1
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>