summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorUlf Hermann <ulf.hermann@theqtcompany.com>2016-03-10 11:16:52 +0100
committerUlf Hermann <ulf.hermann@theqtcompany.com>2016-03-30 11:56:34 +0000
commit2f2e803aa720e8a60b18eab7e4c41e67cd449457 (patch)
tree6807c3d6a8140e04e70d805f2e046eacda4c846f /src
parent40914b6c47945dbce11f4993cd0dcf4f640161b3 (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.cpp6
-rw-r--r--src/scxml/qscxmlcppdatamodel.h2
-rw-r--r--src/scxml/qscxmlcppdatamodel_p.h2
-rw-r--r--src/scxml/qscxmldatamodel.cpp57
-rw-r--r--src/scxml/qscxmldatamodel.h9
-rw-r--r--src/scxml/qscxmldatamodel_p.h11
-rw-r--r--src/scxml/qscxmlecmascriptdatamodel.cpp11
-rw-r--r--src/scxml/qscxmlecmascriptdatamodel.h2
-rw-r--r--src/scxml/qscxmlnulldatamodel.cpp10
-rw-r--r--src/scxml/qscxmlnulldatamodel.h2
-rw-r--r--src/scxml/qscxmlparser.cpp9
-rw-r--r--src/scxml/qscxmlstatemachine.cpp34
-rw-r--r--src/scxml/qscxmlstatemachine.h3
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();