diff options
author | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2016-03-10 11:16:52 +0100 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@theqtcompany.com> | 2016-03-30 11:56:34 +0000 |
commit | 2f2e803aa720e8a60b18eab7e4c41e67cd449457 (patch) | |
tree | 6807c3d6a8140e04e70d805f2e046eacda4c846f /src | |
parent | 40914b6c47945dbce11f4993cd0dcf4f640161b3 (diff) |
Drop the stateMachine parameter from data model constructors
Instead, make the data model a Q_PROPERTY of state machines. This makes
it much easier to independently instantiate state machines and data
models from QML and connect them via properties.
Change-Id: I62d712dd0ad7817c39432204ced431b8041e442d
Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/scxml/qscxmlcppdatamodel.cpp | 6 | ||||
-rw-r--r-- | src/scxml/qscxmlcppdatamodel.h | 2 | ||||
-rw-r--r-- | src/scxml/qscxmlcppdatamodel_p.h | 2 | ||||
-rw-r--r-- | src/scxml/qscxmldatamodel.cpp | 57 | ||||
-rw-r--r-- | src/scxml/qscxmldatamodel.h | 9 | ||||
-rw-r--r-- | src/scxml/qscxmldatamodel_p.h | 11 | ||||
-rw-r--r-- | src/scxml/qscxmlecmascriptdatamodel.cpp | 11 | ||||
-rw-r--r-- | src/scxml/qscxmlecmascriptdatamodel.h | 2 | ||||
-rw-r--r-- | src/scxml/qscxmlnulldatamodel.cpp | 10 | ||||
-rw-r--r-- | src/scxml/qscxmlnulldatamodel.h | 2 | ||||
-rw-r--r-- | src/scxml/qscxmlparser.cpp | 9 | ||||
-rw-r--r-- | src/scxml/qscxmlstatemachine.cpp | 34 | ||||
-rw-r--r-- | src/scxml/qscxmlstatemachine.h | 3 |
13 files changed, 104 insertions, 54 deletions
diff --git a/src/scxml/qscxmlcppdatamodel.cpp b/src/scxml/qscxmlcppdatamodel.cpp index be2fce8..9f00b75 100644 --- a/src/scxml/qscxmlcppdatamodel.cpp +++ b/src/scxml/qscxmlcppdatamodel.cpp @@ -128,10 +128,10 @@ void TheDataModel::evaluateToVoid(QScxmlExecutableContent::EvaluatorId id, bool */ /*! - * Creates a new C++ data model with the state machine \a stateMachine. + * Creates a new C++ data model with the parent object \a parent. */ -QScxmlCppDataModel::QScxmlCppDataModel(QScxmlStateMachine *stateMachine) - : QScxmlDataModel(*(new QScxmlCppDataModelPrivate(stateMachine))) +QScxmlCppDataModel::QScxmlCppDataModel(QObject *parent) + : QScxmlDataModel(*(new QScxmlCppDataModelPrivate), parent) {} /*! diff --git a/src/scxml/qscxmlcppdatamodel.h b/src/scxml/qscxmlcppdatamodel.h index c6366e3..f6e344d 100644 --- a/src/scxml/qscxmlcppdatamodel.h +++ b/src/scxml/qscxmlcppdatamodel.h @@ -58,7 +58,7 @@ class Q_SCXML_EXPORT QScxmlCppDataModel: public QScxmlDataModel Q_OBJECT Q_DECLARE_PRIVATE(QScxmlCppDataModel) public: - QScxmlCppDataModel(QScxmlStateMachine *stateMachine); + QScxmlCppDataModel(QObject *parent = 0); bool setup(const QVariantMap &initialDataValues) Q_DECL_OVERRIDE; diff --git a/src/scxml/qscxmlcppdatamodel_p.h b/src/scxml/qscxmlcppdatamodel_p.h index 5a779e2..1712a73 100644 --- a/src/scxml/qscxmlcppdatamodel_p.h +++ b/src/scxml/qscxmlcppdatamodel_p.h @@ -60,8 +60,6 @@ QT_BEGIN_NAMESPACE class Q_SCXML_EXPORT QScxmlCppDataModelPrivate : public QScxmlDataModelPrivate { public: - QScxmlCppDataModelPrivate(QScxmlStateMachine *stateMachine) : - QScxmlDataModelPrivate(stateMachine) {} QScxmlEvent event; }; diff --git a/src/scxml/qscxmldatamodel.cpp b/src/scxml/qscxmldatamodel.cpp index fd1ce9b..6e6d62b 100644 --- a/src/scxml/qscxmldatamodel.cpp +++ b/src/scxml/qscxmldatamodel.cpp @@ -69,21 +69,49 @@ QScxmlDataModel::ForeachLoopBody::~ForeachLoopBody() */ /*! - * Creates a new data model for the state machine \a stateMachine. + \property QScxmlDataModel::stateMachine + + \brief The state machine this data model belongs to. + + A data model can only belong to a single state machine and a state machine + can only have one data model. This relation needs to be set up before the + state machine is started. Setting this property on a data model will + automatically set the corresponding \c dataModel property on the + \a stateMachine. +*/ + +/*! + * Creates a new data model, with the parent object \a parent. */ -QScxmlDataModel::QScxmlDataModel(QScxmlStateMachine *stateMachine) - : QObject(*(new QScxmlDataModelPrivate(stateMachine))) +QScxmlDataModel::QScxmlDataModel(QObject *parent) + : QObject(*(new QScxmlDataModelPrivate), parent) { - QScxmlStateMachinePrivate::get(stateMachine)->m_dataModel = this; } /*! * \internal */ -QScxmlDataModel::QScxmlDataModel(QScxmlDataModelPrivate &dd) : - QObject(dd) +QScxmlDataModel::QScxmlDataModel(QScxmlDataModelPrivate &dd, QObject *parent) : + QObject(dd, parent) { - QScxmlStateMachinePrivate::get(dd.m_stateMachine)->m_dataModel = this; +} + +/*! + * Sets the state machine this model belongs to to \a stateMachine. There is a + * 1:1 relation between state machines and models. After setting the state + * machine once you cannot change it anymore. Any further attempts to set the + * state machine using this method will be ignored. + */ +void QScxmlDataModel::setStateMachine(QScxmlStateMachine *stateMachine) +{ + Q_D(QScxmlDataModel); + + if (d->m_stateMachine == Q_NULLPTR && stateMachine != Q_NULLPTR) { + d->m_stateMachine = stateMachine; + if (stateMachine) + stateMachine->setDataModel(this); + emit stateMachineChanged(stateMachine); + } } /*! @@ -100,34 +128,25 @@ QScxmlTableData *QScxmlDataModel::tableData() const return stateMachine()->tableData(); } -QScxmlDataModel *QScxmlDataModelPrivate::instantiateDataModel( - DocumentModel::Scxml::DataModelType type, QScxmlStateMachine *stateMachine) +QScxmlDataModel *QScxmlDataModelPrivate::instantiateDataModel(DocumentModel::Scxml::DataModelType type) { - Q_ASSERT(stateMachine); - QScxmlDataModel *dataModel = Q_NULLPTR; switch (type) { case DocumentModel::Scxml::NullDataModel: - dataModel = new QScxmlNullDataModel(stateMachine); + dataModel = new QScxmlNullDataModel; break; case DocumentModel::Scxml::JSDataModel: - dataModel = new QScxmlEcmaScriptDataModel(stateMachine); + dataModel = new QScxmlEcmaScriptDataModel; break; case DocumentModel::Scxml::CppDataModel: break; default: Q_UNREACHABLE(); } - QScxmlStateMachinePrivate::get(stateMachine)->parserData()->m_ownedDataModel.reset(dataModel); return dataModel; } -void QScxmlDataModelPrivate::setStateMachine(QScxmlStateMachine *stateMachine) -{ - m_stateMachine = stateMachine; -} - /*! * \fn QScxmlDataModel::setup(const QVariantMap &initialDataValues) * diff --git a/src/scxml/qscxmldatamodel.h b/src/scxml/qscxmldatamodel.h index 79ae7c1..75c55e6 100644 --- a/src/scxml/qscxmldatamodel.h +++ b/src/scxml/qscxmldatamodel.h @@ -57,6 +57,7 @@ class Q_SCXML_EXPORT QScxmlDataModel : public QObject { Q_OBJECT Q_DECLARE_PRIVATE(QScxmlDataModel) + Q_PROPERTY(QScxmlStateMachine *stateMachine READ stateMachine WRITE setStateMachine NOTIFY stateMachineChanged) public: class ForeachLoopBody @@ -67,8 +68,9 @@ public: }; public: - QScxmlDataModel(QScxmlStateMachine *stateMachine); + QScxmlDataModel(QObject *parent = 0); + void setStateMachine(QScxmlStateMachine *stateMachine); QScxmlStateMachine *stateMachine() const; virtual bool setup(const QVariantMap &initialDataValues) = 0; @@ -89,8 +91,11 @@ public: virtual bool hasScxmlProperty(const QString &name) const = 0; virtual bool setScxmlProperty(const QString &name, const QVariant &value, const QString &context) = 0; +Q_SIGNALS: + void stateMachineChanged(QScxmlStateMachine *stateMachine); + protected: - QScxmlDataModel(QScxmlDataModelPrivate &dd); + QScxmlDataModel(QScxmlDataModelPrivate &dd, QObject *parent = 0); #ifndef Q_QDOC QScxmlTableData *tableData() const; #endif // Q_QDOC diff --git a/src/scxml/qscxmldatamodel_p.h b/src/scxml/qscxmldatamodel_p.h index ee9e405..1fdcfbb 100644 --- a/src/scxml/qscxmldatamodel_p.h +++ b/src/scxml/qscxmldatamodel_p.h @@ -60,16 +60,9 @@ QT_BEGIN_NAMESPACE class QScxmlDataModelPrivate : public QObjectPrivate { public: - QScxmlDataModelPrivate(QScxmlStateMachine *stateMachine) - : m_stateMachine(stateMachine) - { - Q_ASSERT(stateMachine != Q_NULLPTR); - } + QScxmlDataModelPrivate() : m_stateMachine(Q_NULLPTR) {} - static QScxmlDataModel *instantiateDataModel(DocumentModel::Scxml::DataModelType type, - QScxmlStateMachine *stateMachine); - - void setStateMachine(QScxmlStateMachine *stateMachine); + static QScxmlDataModel *instantiateDataModel(DocumentModel::Scxml::DataModelType type); public: QScxmlStateMachine *m_stateMachine; diff --git a/src/scxml/qscxmlecmascriptdatamodel.cpp b/src/scxml/qscxmlecmascriptdatamodel.cpp index 91de2aa..54c2dfb 100644 --- a/src/scxml/qscxmlecmascriptdatamodel.cpp +++ b/src/scxml/qscxmlecmascriptdatamodel.cpp @@ -65,9 +65,8 @@ class QScxmlEcmaScriptDataModelPrivate : public QScxmlDataModelPrivate { Q_DECLARE_PUBLIC(QScxmlEcmaScriptDataModel) public: - QScxmlEcmaScriptDataModelPrivate(QScxmlStateMachine *stateMachine) - : QScxmlDataModelPrivate(stateMachine) - , jsEngine(Q_NULLPTR) + QScxmlEcmaScriptDataModelPrivate() + : jsEngine(Q_NULLPTR) {} QString evalStr(const QString &expr, const QString &context, bool *ok) @@ -356,10 +355,10 @@ private: */ /*! - * Creates a new ECMAScript data model for the state machine \a stateMachine. + * Creates a new ECMAScript data model, with the parent object \a parent. */ -QScxmlEcmaScriptDataModel::QScxmlEcmaScriptDataModel(QScxmlStateMachine *stateMachine) - : QScxmlDataModel(*(new QScxmlEcmaScriptDataModelPrivate(stateMachine))) +QScxmlEcmaScriptDataModel::QScxmlEcmaScriptDataModel(QObject *parent) + : QScxmlDataModel(*(new QScxmlEcmaScriptDataModelPrivate), parent) {} /*! diff --git a/src/scxml/qscxmlecmascriptdatamodel.h b/src/scxml/qscxmlecmascriptdatamodel.h index 37d62c8..0b0708c 100644 --- a/src/scxml/qscxmlecmascriptdatamodel.h +++ b/src/scxml/qscxmlecmascriptdatamodel.h @@ -51,7 +51,7 @@ class Q_SCXML_EXPORT QScxmlEcmaScriptDataModel: public QScxmlDataModel Q_OBJECT Q_DECLARE_PRIVATE(QScxmlEcmaScriptDataModel) public: - QScxmlEcmaScriptDataModel(QScxmlStateMachine *stateMachine); + QScxmlEcmaScriptDataModel(QObject *parent = 0); bool setup(const QVariantMap &initialDataValues) Q_DECL_OVERRIDE; diff --git a/src/scxml/qscxmlnulldatamodel.cpp b/src/scxml/qscxmlnulldatamodel.cpp index 754bc1a..c24a729 100644 --- a/src/scxml/qscxmlnulldatamodel.cpp +++ b/src/scxml/qscxmlnulldatamodel.cpp @@ -59,10 +59,6 @@ class QScxmlNullDataModelPrivate : public QScxmlDataModelPrivate }; public: - QScxmlNullDataModelPrivate(QScxmlStateMachine *stateMachine) - : QScxmlDataModelPrivate(stateMachine) - {} - bool evalBool(QScxmlExecutableContent::EvaluatorId id, bool *ok) { Q_Q(QScxmlNullDataModel); @@ -132,10 +128,10 @@ private: */ /*! - * Creates a new Qt SCXML data model for the state machine \a stateMachine. + * Creates a new Qt SCXML data model, with the parent object \a parent. */ -QScxmlNullDataModel::QScxmlNullDataModel(QScxmlStateMachine *stateMachine) - : QScxmlDataModel(*(new QScxmlNullDataModelPrivate(stateMachine))) +QScxmlNullDataModel::QScxmlNullDataModel(QObject *parent) + : QScxmlDataModel(*(new QScxmlNullDataModelPrivate), parent) {} /*! diff --git a/src/scxml/qscxmlnulldatamodel.h b/src/scxml/qscxmlnulldatamodel.h index 9f75db7..5fb28d9 100644 --- a/src/scxml/qscxmlnulldatamodel.h +++ b/src/scxml/qscxmlnulldatamodel.h @@ -50,7 +50,7 @@ class Q_SCXML_EXPORT QScxmlNullDataModel: public QScxmlDataModel Q_OBJECT Q_DECLARE_PRIVATE(QScxmlNullDataModel) public: - QScxmlNullDataModel(QScxmlStateMachine *stateMachine); + QScxmlNullDataModel(QObject *parent = 0); bool setup(const QVariantMap &initialDataValues) Q_DECL_OVERRIDE; diff --git a/src/scxml/qscxmlparser.cpp b/src/scxml/qscxmlparser.cpp index 6a91142..162b6a2 100644 --- a/src/scxml/qscxmlparser.cpp +++ b/src/scxml/qscxmlparser.cpp @@ -1007,7 +1007,9 @@ inline QScxmlInvokableService *InvokeDynamicScxmlFactory::invoke(QScxmlStateMach { auto child = QStateMachineBuilder().build(m_content.data()); - QScxmlDataModelPrivate::instantiateDataModel(m_content->root->dataModel, child); + auto dm = QScxmlDataModelPrivate::instantiateDataModel(m_content->root->dataModel); + dm->setParent(child); + child->setDataModel(dm); return finishInvoke(child, parent); } @@ -1148,8 +1150,9 @@ void QScxmlParser::instantiateDataModel(QScxmlStateMachine *stateMachine) const if (root == Q_NULLPTR) { qWarning() << "SCXML document has no root element"; } else { - QScxmlDataModel *dm = QScxmlDataModelPrivate::instantiateDataModel(root->dataModel, - stateMachine); + QScxmlDataModel *dm = QScxmlDataModelPrivate::instantiateDataModel(root->dataModel); + QScxmlStateMachinePrivate::get(stateMachine)->parserData()->m_ownedDataModel.reset(dm); + stateMachine->setDataModel(dm); if (dm == Q_NULLPTR) qWarning() << "No data-model instantiated"; } diff --git a/src/scxml/qscxmlstatemachine.cpp b/src/scxml/qscxmlstatemachine.cpp index 1939fcc..eeca441 100644 --- a/src/scxml/qscxmlstatemachine.cpp +++ b/src/scxml/qscxmlstatemachine.cpp @@ -456,6 +456,22 @@ QScxmlStateMachine::QScxmlStateMachine(QScxmlStateMachinePrivate &dd, QObject *p */ /*! + \property QScxmlStateMachine::dataModel + + \brief The data model to be used for this state machine. + + SCXML data models are described in + \l {SCXML Specification - 5 Data Model and Data Manipulation}. For more + information about supported data models, see \l {SCXML Compliance}. + + Changing the data model while the state machine is \c running is not + specified in the SCXML standard and leads to undefined behavior. + + \sa QScxmlDataModel, QScxmlNullDataModel, QScxmlEcmaScriptDataModel, + QScxmlCppDataModel +*/ + +/*! \enum QScxmlStateMachine::BindingMethod This enum specifies the binding method. The binding method controls the point in time @@ -520,6 +536,24 @@ bool QScxmlStateMachine::isInvoked() const } /*! + * 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 + * cannot change it anymore. Any further attempts to set the model using this + * method will be ignored. + */ +void QScxmlStateMachine::setDataModel(QScxmlDataModel *model) +{ + Q_D(QScxmlStateMachine); + + if (d->m_dataModel == Q_NULLPTR && model != Q_NULLPTR) { + d->m_dataModel = model; + if (model) + model->setStateMachine(this); + emit dataModelChanged(model); + } +} + +/*! * Returns the data model used by the state machine. */ QScxmlDataModel *QScxmlStateMachine::dataModel() const diff --git a/src/scxml/qscxmlstatemachine.h b/src/scxml/qscxmlstatemachine.h index 0f7aeed..f1e7f82 100644 --- a/src/scxml/qscxmlstatemachine.h +++ b/src/scxml/qscxmlstatemachine.h @@ -75,6 +75,7 @@ class Q_SCXML_EXPORT QScxmlStateMachine: public QObject Q_OBJECT Q_ENUMS(BindingMethod) Q_PROPERTY(bool running READ isRunning WRITE setRunning NOTIFY runningChanged) + Q_PROPERTY(QScxmlDataModel *dataModel READ dataModel WRITE setDataModel NOTIFY dataModelChanged) protected: #ifndef Q_QDOC @@ -98,6 +99,7 @@ public: bool isInvoked() const; + void setDataModel(QScxmlDataModel *model); QScxmlDataModel *dataModel() const; BindingMethod dataBinding() const; @@ -132,6 +134,7 @@ Q_SIGNALS: void reachedStableState(); void finished(); void eventOccurred(const QScxmlEvent &event); + void dataModelChanged(QScxmlDataModel *model); public Q_SLOTS: void start(); |