diff options
author | Juha Vuolle <juha.vuolle@insta.fi> | 2021-03-05 11:57:30 +0200 |
---|---|---|
committer | Juha Vuolle <juha.vuolle@insta.fi> | 2021-05-03 13:52:02 +0300 |
commit | 61dbf282ba718771e432dfbbd618cad2dc728c5b (patch) | |
tree | 5253b37274276d1dd65df4d12e2a7d90c676af7e /src | |
parent | 4e28b3753e297541baaa45ef6c5651989ff7ce82 (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.cpp | 100 | ||||
-rw-r--r-- | src/scxml/qscxmlstatemachine.h | 20 | ||||
-rw-r--r-- | src/scxml/qscxmlstatemachine_p.h | 43 |
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; |