summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJarek Kobus <jaroslaw.kobus@qt.io>2017-06-12 16:19:08 +0200
committerJarek Kobus <jaroslaw.kobus@qt.io>2017-08-14 09:08:05 +0000
commit8af8db3810ec2d8d2d923f39e23512d30ae234d9 (patch)
tree1d7e2fb3e27eecc3a8868b17494cc3a5c259e63d
parentcbcd1b0c432089777377fb0190a7d86195367bb6 (diff)
Fix emission of state changed signals
The state index is not the same as its changed signal index. The changed signal is not being generated for history states. The current fix is that we create a hash cache of state index into the signal index of its appropriate signal just after we set the table data for the state machine. Task-number: QTBUG-61243 Change-Id: I778adaf6c2d626be17c50b558f93ec0035ea3325 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Paolo Angelelli <paolo.angelelli@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-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>