summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJuha Vuolle <juha.vuolle@insta.fi>2021-03-05 11:57:30 +0200
committerJuha Vuolle <juha.vuolle@insta.fi>2021-05-03 13:52:02 +0300
commit61dbf282ba718771e432dfbbd618cad2dc728c5b (patch)
tree5253b37274276d1dd65df4d12e2a7d90c676af7e /src
parent4e28b3753e297541baaa45ef6c5651989ff7ce82 (diff)
QtScxml QML-facing properties bindable support additions part 1
This commit adds the bindable support to following QScxmlStateMachine properties: initialized, initialValues, loader, dataModel and tableData Task-number: QTBUG-89895 Change-Id: I33545d9d45a4fbf52a4a220d559b7ee75351a268 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/scxml/qscxmlstatemachine.cpp100
-rw-r--r--src/scxml/qscxmlstatemachine.h20
-rw-r--r--src/scxml/qscxmlstatemachine_p.h43
3 files changed, 115 insertions, 48 deletions
diff --git a/src/scxml/qscxmlstatemachine.cpp b/src/scxml/qscxmlstatemachine.cpp
index 721dbfe..fdc5140 100644
--- a/src/scxml/qscxmlstatemachine.cpp
+++ b/src/scxml/qscxmlstatemachine.cpp
@@ -429,12 +429,8 @@ QScxmlStateMachinePrivate::QScxmlStateMachinePrivate(const QMetaObject *metaObje
: QObjectPrivate()
, m_sessionId(QScxmlStateMachinePrivate::generateSessionId(QStringLiteral("session-")))
, m_isInvoked(false)
- , m_isInitialized(false)
, m_isProcessingEvents(false)
- , m_dataModel(nullptr)
- , m_loader(&m_defaultLoader)
, m_executionEngine(nullptr)
- , m_tableData(nullptr)
, m_parentStateMachine(nullptr)
, m_eventLoopHook(this)
, m_metaObject(metaObject)
@@ -442,6 +438,7 @@ QScxmlStateMachinePrivate::QScxmlStateMachinePrivate(const QMetaObject *metaObje
{
static int metaType = qRegisterMetaType<QScxmlStateMachine *>();
Q_UNUSED(metaType);
+ m_loader.setValueBypassingBindings(&m_defaultLoader);
}
QScxmlStateMachinePrivate::~QScxmlStateMachinePrivate()
@@ -502,13 +499,13 @@ QScxmlInvokableServiceFactory *QScxmlStateMachinePrivate::serviceFactory(int id)
Q_ASSERT(id <= m_stateTable->maxServiceId && id >= 0);
QScxmlInvokableServiceFactory *& factory = m_cachedFactories[size_t(id)];
if (factory == nullptr)
- factory = m_tableData->serviceFactory(id);
+ factory = m_tableData.value()->serviceFactory(id);
return factory;
}
bool QScxmlStateMachinePrivate::executeInitialSetup()
{
- return m_executionEngine->execute(m_tableData->initialSetup());
+ return m_executionEngine->execute(m_tableData.value()->initialSetup());
}
void QScxmlStateMachinePrivate::routeEvent(QScxmlEvent *event)
@@ -727,12 +724,12 @@ void QScxmlStateMachinePrivate::processEvents()
void QScxmlStateMachinePrivate::setEvent(QScxmlEvent *event)
{
Q_ASSERT(event);
- m_dataModel->setScxmlEvent(*event);
+ m_dataModel.value()->setScxmlEvent(*event);
}
void QScxmlStateMachinePrivate::resetEvent()
{
- m_dataModel->setScxmlEvent(QScxmlEvent());
+ m_dataModel.value()->setScxmlEvent(QScxmlEvent());
}
void QScxmlStateMachinePrivate::emitStateActive(int stateIndex, bool active)
@@ -770,7 +767,7 @@ void QScxmlStateMachinePrivate::updateMetaCache()
m_stateIndexToSignalIndex.clear();
m_stateNameToSignalIndex.clear();
- if (!m_tableData)
+ if (!m_tableData.value())
return;
if (!m_stateTable)
@@ -782,7 +779,7 @@ void QScxmlStateMachinePrivate::updateMetaCache()
const auto &s = m_stateTable->state(i);
if (!s.isHistoryState() && s.type != StateTable::State::Invalid) {
m_stateIndexToSignalIndex.insert(i, signalIndex);
- m_stateNameToSignalIndex.insert(m_tableData->string(s.name),
+ m_stateNameToSignalIndex.insert(m_tableData.value()->string(s.name),
signalIndex + methodOffset);
++signalIndex;
@@ -794,7 +791,7 @@ QStringList QScxmlStateMachinePrivate::stateNames(const std::vector<int> &stateI
{
QStringList names;
for (int idx : stateIndexes)
- names.append(m_tableData->string(m_stateTable->state(idx).name));
+ names.append(m_tableData.value()->string(m_stateTable->state(idx).name));
return names;
}
@@ -852,7 +849,7 @@ bool QScxmlStateMachinePrivate::nameMatch(const StateTable::Array &patterns,
const QString eventName = event->name();
bool selected = false;
for (int eventSelectorIter = 0; eventSelectorIter < patterns.size(); ++eventSelectorIter) {
- QString eventStr = m_tableData->string(patterns[eventSelectorIter]);
+ QString eventStr = m_tableData.value()->string(patterns[eventSelectorIter]);
if (eventStr == QStringLiteral("*")) {
selected = true;
break;
@@ -913,7 +910,7 @@ void QScxmlStateMachinePrivate::selectTransitions(OrderedSet &enabledTransitions
enabled = true;
} else {
bool ok = false;
- enabled = m_dataModel->evaluateToBool(t.condition, &ok) && ok;
+ enabled = m_dataModel.value()->evaluateToBool(t.condition, &ok) && ok;
}
}
} else {
@@ -922,7 +919,7 @@ void QScxmlStateMachinePrivate::selectTransitions(OrderedSet &enabledTransitions
enabled = true;
} else {
bool ok = false;
- enabled = m_dataModel->evaluateToBool(t.condition, &ok) && ok;
+ enabled = m_dataModel.value()->evaluateToBool(t.condition, &ok) && ok;
}
}
}
@@ -1037,13 +1034,13 @@ void QScxmlStateMachinePrivate::microstep(const OrderedSet &enabledTransitions)
const auto &transition = m_stateTable->transition(t);
QString from = QStringLiteral("(none)");
if (transition.source != StateTable::InvalidIndex)
- from = m_tableData->string(m_stateTable->state(transition.source).name);
+ from = m_tableData.value()->string(m_stateTable->state(transition.source).name);
QStringList to;
if (transition.targets == StateTable::InvalidIndex) {
to.append(QStringLiteral("(none)"));
} else {
for (int t : m_stateTable->array(transition.targets))
- to.append(m_tableData->string(m_stateTable->state(t).name));
+ to.append(m_tableData.value()->string(m_stateTable->state(t).name));
}
qCDebug(qscxmlLog) << q_func() << "\t" << t << ":" << from << "->"
<< to.join(QLatin1Char(','));
@@ -1176,7 +1173,7 @@ void QScxmlStateMachinePrivate::enterStates(const OrderedSet &enabledTransitions
emit q->runningChanged(false);
} else {
const auto &parent = m_stateTable->state(state.parent);
- m_executionEngine->execute(state.doneData, m_tableData->string(parent.name));
+ m_executionEngine->execute(state.doneData, m_tableData.value()->string(parent.name));
if (parent.parent != StateTable::InvalidIndex) {
const auto &grandParent = m_stateTable->state(parent.parent);
if (grandParent.isParallel()) {
@@ -1184,7 +1181,7 @@ void QScxmlStateMachinePrivate::enterStates(const OrderedSet &enabledTransitions
auto e = new QScxmlEvent;
e->setEventType(QScxmlEvent::InternalEvent);
e->setName(QStringLiteral("done.state.")
- + m_tableData->string(grandParent.name));
+ + m_tableData.value()->string(grandParent.name));
q->submitEvent(e);
}
}
@@ -1729,6 +1726,12 @@ bool QScxmlStateMachine::isInitialized() const
return d->m_isInitialized;
}
+QBindable<bool> QScxmlStateMachine::bindableInitialized() const
+{
+ Q_D(const QScxmlStateMachine);
+ return &d->m_isInitialized;
+}
+
/*!
* Sets the data model for this state machine to \a model. There is a 1:1
* relation between state machines and models. After setting the model once you
@@ -1739,10 +1742,12 @@ void QScxmlStateMachine::setDataModel(QScxmlDataModel *model)
{
Q_D(QScxmlStateMachine);
- if (d->m_dataModel == nullptr && model != nullptr) {
+ if (d->m_dataModel.value() == nullptr && model != nullptr) {
+ // the binding is removed only on the first valid set
+ // as the later attempts are ignored (removed when value is set below)
d->m_dataModel = model;
- if (model)
- model->setStateMachine(this);
+ model->setStateMachine(this);
+ d->m_dataModel.notify();
emit dataModelChanged(model);
}
}
@@ -1757,14 +1762,16 @@ QScxmlDataModel *QScxmlStateMachine::dataModel() const
return d->m_dataModel;
}
-void QScxmlStateMachine::setLoader(QScxmlCompiler::Loader *loader)
+QBindable<QScxmlDataModel*> QScxmlStateMachine::bindableDataModel()
{
Q_D(QScxmlStateMachine);
+ return &d->m_dataModel;
+}
- if (loader != d->m_loader) {
- d->m_loader = loader;
- emit loaderChanged(loader);
- }
+void QScxmlStateMachine::setLoader(QScxmlCompiler::Loader *loader)
+{
+ Q_D(QScxmlStateMachine);
+ d->m_loader.setValue(loader);
}
QScxmlCompiler::Loader *QScxmlStateMachine::loader() const
@@ -1774,6 +1781,12 @@ QScxmlCompiler::Loader *QScxmlStateMachine::loader() const
return d->m_loader;
}
+QBindable<QScxmlCompiler::Loader*> QScxmlStateMachine::bindableLoader()
+{
+ Q_D(QScxmlStateMachine);
+ return &d->m_loader;
+}
+
QScxmlTableData *QScxmlStateMachine::tableData() const
{
Q_D(const QScxmlStateMachine);
@@ -1785,8 +1798,10 @@ void QScxmlStateMachine::setTableData(QScxmlTableData *tableData)
{
Q_D(QScxmlStateMachine);
- if (d->m_tableData == tableData)
+ if (d->m_tableData.value() == tableData) {
+ d->m_tableData.removeBindingUnlessInWrapper();
return;
+ }
d->m_tableData = tableData;
if (tableData) {
@@ -1812,9 +1827,16 @@ void QScxmlStateMachine::setTableData(QScxmlTableData *tableData)
d->updateMetaCache();
+ d->m_tableData.notify();
emit tableDataChanged(tableData);
}
+QBindable<QScxmlTableData*> QScxmlStateMachine::bindableTableData()
+{
+ Q_D(QScxmlStateMachine);
+ return &d->m_tableData;
+}
+
/*!
\qmlmethod ScxmlStateMachine::stateNames(bool compress)
@@ -1851,7 +1873,7 @@ QStringList QScxmlStateMachine::stateNames(bool compress) const
for (int i = 0; i < d->m_stateTable->stateCount; ++i) {
const auto &state = d->m_stateTable->state(i);
if (!compress || state.isAtomic())
- names.append(d->m_tableData->string(state.name));
+ names.append(d->m_tableData.value()->string(state.name));
}
return names;
}
@@ -1882,7 +1904,7 @@ QStringList QScxmlStateMachine::activeStateNames(bool compress) const
for (int stateIdx : d->m_configuration) {
const auto &state = d->m_stateTable->state(stateIdx);
if (state.isAtomic() || !compress)
- result.append(d->m_tableData->string(state.name));
+ result.append(d->m_tableData.value()->string(state.name));
}
return result;
}
@@ -1903,7 +1925,7 @@ bool QScxmlStateMachine::isActive(const QString &scxmlStateName) const
for (int stateIndex : d->m_configuration) {
const auto &state = d->m_stateTable->state(stateIndex);
- if (d->m_tableData->string(state.name) == scxmlStateName)
+ if (d->m_tableData.value()->string(state.name) == scxmlStateName)
return true;
}
@@ -2009,20 +2031,19 @@ bool QScxmlStateMachine::init()
{
Q_D(QScxmlStateMachine);
- if (d->m_isInitialized)
+ if (d->m_isInitialized.value())
return false;
if (!parseErrors().isEmpty())
return false;
- if (!dataModel() || !dataModel()->setup(d->m_initialValues))
+ if (!dataModel() || !dataModel()->setup(d->m_initialValues.value()))
return false;
if (!d->executeInitialSetup())
return false;
- d->m_isInitialized = true;
- emit initializedChanged(true);
+ d->m_isInitialized.setValue(true);
return true;
}
@@ -2060,10 +2081,13 @@ QVariantMap QScxmlStateMachine::initialValues()
void QScxmlStateMachine::setInitialValues(const QVariantMap &initialValues)
{
Q_D(QScxmlStateMachine);
- if (initialValues != d->m_initialValues) {
- d->m_initialValues = initialValues;
- emit initialValuesChanged(initialValues);
- }
+ d->m_initialValues.setValue(initialValues);
+}
+
+QBindable<QVariantMap> QScxmlStateMachine::bindableInitialValues()
+{
+ Q_D(QScxmlStateMachine);
+ return &d->m_initialValues;
}
QString QScxmlStateMachine::name() const
diff --git a/src/scxml/qscxmlstatemachine.h b/src/scxml/qscxmlstatemachine.h
index 45e6b74..36da66b 100644
--- a/src/scxml/qscxmlstatemachine.h
+++ b/src/scxml/qscxmlstatemachine.h
@@ -68,16 +68,21 @@ class Q_SCXML_EXPORT QScxmlStateMachine: public QObject
Q_DECLARE_PRIVATE(QScxmlStateMachine)
Q_OBJECT
Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged)
- Q_PROPERTY(bool initialized READ isInitialized NOTIFY initializedChanged)
- Q_PROPERTY(QScxmlDataModel *dataModel READ dataModel WRITE setDataModel NOTIFY dataModelChanged)
- Q_PROPERTY(QVariantMap initialValues READ initialValues WRITE setInitialValues NOTIFY initialValuesChanged)
+ Q_PROPERTY(bool initialized READ isInitialized
+ NOTIFY initializedChanged BINDABLE bindableInitialized)
+ Q_PROPERTY(QScxmlDataModel *dataModel READ dataModel WRITE setDataModel
+ NOTIFY dataModelChanged BINDABLE bindableDataModel)
+ Q_PROPERTY(QVariantMap initialValues READ initialValues WRITE setInitialValues
+ NOTIFY initialValuesChanged BINDABLE bindableInitialValues)
Q_PROPERTY(QList<QScxmlInvokableService*> invokedServices READ invokedServices NOTIFY invokedServicesChanged)
Q_PROPERTY(QString sessionId READ sessionId CONSTANT)
Q_PROPERTY(QString name READ name CONSTANT)
Q_PROPERTY(bool invoked READ isInvoked CONSTANT)
Q_PROPERTY(QList<QScxmlError> parseErrors READ parseErrors CONSTANT)
- Q_PROPERTY(QScxmlCompiler::Loader *loader READ loader WRITE setLoader NOTIFY loaderChanged)
- Q_PROPERTY(QScxmlTableData *tableData READ tableData WRITE setTableData NOTIFY tableDataChanged)
+ Q_PROPERTY(QScxmlCompiler::Loader *loader READ loader WRITE setLoader
+ NOTIFY loaderChanged BINDABLE bindableLoader)
+ Q_PROPERTY(QScxmlTableData *tableData READ tableData WRITE setTableData
+ NOTIFY tableDataChanged BINDABLE bindableTableData)
protected:
explicit QScxmlStateMachine(const QMetaObject *metaObject, QObject *parent = nullptr);
@@ -92,18 +97,22 @@ public:
bool isInvoked() const;
bool isInitialized() const;
+ QBindable<bool> bindableInitialized() const;
void setDataModel(QScxmlDataModel *model);
QScxmlDataModel *dataModel() const;
+ QBindable<QScxmlDataModel*> bindableDataModel();
void setLoader(QScxmlCompiler::Loader *loader);
QScxmlCompiler::Loader *loader() const;
+ QBindable<QScxmlCompiler::Loader*> bindableLoader();
bool isRunning() const;
void setRunning(bool running);
QVariantMap initialValues();
void setInitialValues(const QVariantMap &initialValues);
+ QBindable<QVariantMap> bindableInitialValues();
QString name() const;
Q_INVOKABLE QStringList stateNames(bool compress = true) const;
@@ -281,6 +290,7 @@ public:
QScxmlTableData *tableData() const;
void setTableData(QScxmlTableData *tableData);
+ QBindable<QScxmlTableData*> bindableTableData();
Q_SIGNALS:
void runningChanged(bool running);
diff --git a/src/scxml/qscxmlstatemachine_p.h b/src/scxml/qscxmlstatemachine_p.h
index 5d9c758..60964d9 100644
--- a/src/scxml/qscxmlstatemachine_p.h
+++ b/src/scxml/qscxmlstatemachine_p.h
@@ -56,6 +56,7 @@
#include <QtScxml/private/qscxmlstatemachineinfo_p.h>
#include <QtCore/private/qobject_p.h>
#include <QtCore/private/qmetaobject_p.h>
+#include <QtCore/private/qproperty_p.h>
#include <QtCore/qmetaobject.h>
#include "qscxmlglobals_p.h"
@@ -329,14 +330,46 @@ private:
public: // types & data fields:
QString m_sessionId;
bool m_isInvoked;
- bool m_isInitialized;
+
+ void isInitializedChanged()
+ {
+ emit q_func()->initializedChanged(m_isInitialized.value());
+ }
+ Q_OBJECT_BINDABLE_PROPERTY_WITH_ARGS(QScxmlStateMachinePrivate,
+ bool, m_isInitialized, false,
+ &QScxmlStateMachinePrivate::isInitializedChanged);
+
+ void initialValuesChanged()
+ {
+ emit q_func()->initialValuesChanged(m_initialValues.value());
+ }
+ Q_OBJECT_BINDABLE_PROPERTY(QScxmlStateMachinePrivate, QVariantMap, m_initialValues,
+ &QScxmlStateMachinePrivate::initialValuesChanged);
+
+ void loaderChanged()
+ {
+ emit q_func()->loaderChanged(m_loader.value());
+ }
+ Q_OBJECT_BINDABLE_PROPERTY(QScxmlStateMachinePrivate, QScxmlCompiler::Loader*, m_loader,
+ &QScxmlStateMachinePrivate::loaderChanged);
+
+ void setDataModel(QScxmlDataModel* loader)
+ {
+ q_func()->setDataModel(loader);
+ }
+ Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QScxmlStateMachinePrivate, QScxmlDataModel*, m_dataModel,
+ &QScxmlStateMachinePrivate::setDataModel, nullptr);
+
+ void setTableData(QScxmlTableData* tableData)
+ {
+ q_func()->setTableData(tableData);
+ }
+ Q_OBJECT_COMPAT_PROPERTY_WITH_ARGS(QScxmlStateMachinePrivate, QScxmlTableData*, m_tableData,
+ &QScxmlStateMachinePrivate::setTableData, nullptr);
+
bool m_isProcessingEvents;
- QVariantMap m_initialValues;
- QScxmlDataModel *m_dataModel;
QScxmlCompilerPrivate::DefaultLoader m_defaultLoader;
- QScxmlCompiler::Loader *m_loader;
QScxmlExecutionEngine *m_executionEngine;
- QScxmlTableData *m_tableData;
const StateTable *m_stateTable;
QScxmlStateMachine *m_parentStateMachine;
QScxmlInternal::EventLoopHook m_eventLoopHook;