summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2017-01-25 10:21:11 +0100
committerLiang Qi <liang.qi@qt.io>2017-01-25 10:21:11 +0100
commit5d851f27a3c72e46df0dfdd234fc3a300a2870fb (patch)
tree4fa416bfe19dd0de544a1babc649ecd66d814346
parent4b4e81398bdfcda23a9e3c86a297e12b2ff1e9d9 (diff)
parentc575eb524bc26fc4af3711d634110c226c9e11c0 (diff)
Merge remote-tracking branch 'origin/5.8' into devv5.9.0-alpha1
Conflicts: .qmake.conf Change-Id: I639eb3acef7004a20447bbb66fb44661bf8e952e
-rw-r--r--examples/scxml/trafficlight-common/TrafficLight.qml2
-rw-r--r--src/scxml/doc/external-resources.qdoc5
-rw-r--r--src/scxml/qscxmlcompiler.cpp22
-rw-r--r--src/scxml/qscxmlcompiler_p.h1
-rw-r--r--src/scxml/qscxmlcppdatamodel.cpp83
-rw-r--r--src/scxml/qscxmlcppdatamodel.h15
-rw-r--r--src/scxml/qscxmlcppdatamodel_p.h6
-rw-r--r--src/scxml/qscxmldatamodel.cpp85
-rw-r--r--src/scxml/qscxmldatamodel.h16
-rw-r--r--src/scxml/qscxmlecmascriptdatamodel.cpp101
-rw-r--r--src/scxml/qscxmlecmascriptdatamodel.h11
-rw-r--r--src/scxml/qscxmlecmascriptplatformproperties_p.h6
-rw-r--r--src/scxml/qscxmlevent.h6
-rw-r--r--src/scxml/qscxmlevent_p.h6
-rw-r--r--src/scxml/qscxmlexecutablecontent.cpp179
-rw-r--r--src/scxml/qscxmlexecutablecontent.h6
-rw-r--r--src/scxml/qscxmlexecutablecontent_p.h8
-rw-r--r--src/scxml/qscxmlglobals.h6
-rw-r--r--src/scxml/qscxmlglobals_p.h6
-rw-r--r--src/scxml/qscxmlinvokableservice.cpp302
-rw-r--r--src/scxml/qscxmlinvokableservice.h94
-rw-r--r--src/scxml/qscxmlinvokableservice_p.h41
-rw-r--r--src/scxml/qscxmlnulldatamodel.cpp61
-rw-r--r--src/scxml/qscxmlnulldatamodel.h10
-rw-r--r--src/scxml/qscxmlstatemachine.cpp117
-rw-r--r--src/scxml/qscxmlstatemachine.h17
-rw-r--r--src/scxml/qscxmlstatemachine_p.h6
-rw-r--r--src/scxml/qscxmltabledata.cpp79
-rw-r--r--src/scxml/qscxmltabledata_p.h2
-rw-r--r--sync.profile12
-rw-r--r--tests/auto/statemachine/tst_statemachine.cpp21
-rw-r--r--tools/qscxmlc/decl.t2
-rw-r--r--tools/qscxmlc/scxmlcppdumper.cpp20
-rw-r--r--tools/qscxmlc/scxmlcppdumper.h6
-rw-r--r--tools/tools.pro2
35 files changed, 968 insertions, 394 deletions
diff --git a/examples/scxml/trafficlight-common/TrafficLight.qml b/examples/scxml/trafficlight-common/TrafficLight.qml
index 1da3726..ec11ed5 100644
--- a/examples/scxml/trafficlight-common/TrafficLight.qml
+++ b/examples/scxml/trafficlight-common/TrafficLight.qml
@@ -60,6 +60,8 @@ Window {
visible: true
width: lights.width
height: lights.height
+ maximumWidth: lights.implicitWidth
+ maximumHeight: lights.implicitHeight
Lights {
id: lights
diff --git a/src/scxml/doc/external-resources.qdoc b/src/scxml/doc/external-resources.qdoc
index 3cbdc6f..39a1c3b 100644
--- a/src/scxml/doc/external-resources.qdoc
+++ b/src/scxml/doc/external-resources.qdoc
@@ -45,6 +45,11 @@
*/
/*!
+ \externalpage https://www.w3.org/TR/scxml/#invoke
+ \title SCXML Specification - 6.4 <invoke>
+*/
+
+/*!
\externalpage https://www.w3.org/TR/scxml/#minimal-profile
\title SCXML Specification - B.1 The Null Data Model
*/
diff --git a/src/scxml/qscxmlcompiler.cpp b/src/scxml/qscxmlcompiler.cpp
index 691f87a..b8434c6 100644
--- a/src/scxml/qscxmlcompiler.cpp
+++ b/src/scxml/qscxmlcompiler.cpp
@@ -473,13 +473,14 @@ private:
};
#ifndef BUILD_QSCXMLC
-class InvokeDynamicScxmlFactory: public QScxmlScxmlServiceFactory
+class InvokeDynamicScxmlFactory: public QScxmlInvokableServiceFactory
{
+ Q_OBJECT
public:
InvokeDynamicScxmlFactory(const QScxmlExecutableContent::InvokeInfo &invokeInfo,
const QVector<QScxmlExecutableContent::StringId> &namelist,
const QVector<QScxmlExecutableContent::ParameterInfo> &params)
- : QScxmlScxmlServiceFactory(invokeInfo, namelist, params)
+ : QScxmlInvokableServiceFactory(invokeInfo, namelist, params)
{}
void setContent(const QSharedPointer<DocumentModel::ScxmlDocument> &content)
@@ -647,12 +648,12 @@ inline QScxmlInvokableService *InvokeDynamicScxmlFactory::invoke(
QScxmlStateMachine *parentStateMachine)
{
bool ok = true;
- auto srcexpr = d->calculateSrcexpr(parentStateMachine, &ok);
+ auto srcexpr = calculateSrcexpr(parentStateMachine, invokeInfo().expr, &ok);
if (!ok)
return Q_NULLPTR;
if (!srcexpr.isEmpty())
- return invokeDynamic(parentStateMachine, srcexpr);
+ return invokeDynamicScxmlService(srcexpr, parentStateMachine, this);
auto childStateMachine = DynamicStateMachine::build(m_content.data());
@@ -660,15 +661,16 @@ inline QScxmlInvokableService *InvokeDynamicScxmlFactory::invoke(
dm->setParent(childStateMachine);
childStateMachine->setDataModel(dm);
- return invokeStatic(childStateMachine, parentStateMachine);
+ return invokeStaticScxmlService(childStateMachine, parentStateMachine, this);
}
#endif // BUILD_QSCXMLC
} // anonymous namespace
#ifndef BUILD_QSCXMLC
-QScxmlScxmlService *QScxmlScxmlServiceFactory::invokeDynamic(
- QScxmlStateMachine *parentStateMachine, const QString &sourceUrl)
+QScxmlScxmlService *invokeDynamicScxmlService(const QString &sourceUrl,
+ QScxmlStateMachine *parentStateMachine,
+ QScxmlInvokableServiceFactory *factory)
{
QScxmlCompiler::Loader *loader = parentStateMachine->loader();
@@ -708,7 +710,7 @@ QScxmlScxmlService *QScxmlScxmlServiceFactory::invokeDynamic(
dm->setParent(childStateMachine);
childStateMachine->setDataModel(dm);
- return invokeStatic(childStateMachine, parentStateMachine);
+ return invokeStaticScxmlService(childStateMachine, parentStateMachine, factory);
}
#endif // BUILD_QSCXMLC
@@ -2483,3 +2485,7 @@ QScxmlCompilerPrivate::ParserState::ParserState(QScxmlCompilerPrivate::ParserSta
{}
QT_END_NAMESPACE
+
+#ifndef BUILD_QSCXMLC
+#include "qscxmlcompiler.moc"
+#endif
diff --git a/src/scxml/qscxmlcompiler_p.h b/src/scxml/qscxmlcompiler_p.h
index 6909c2c..f74e282 100644
--- a/src/scxml/qscxmlcompiler_p.h
+++ b/src/scxml/qscxmlcompiler_p.h
@@ -387,6 +387,7 @@ struct Scxml: public StateContainer, public Node
: Node(xmlLocation)
, dataModel(NullDataModel)
, binding(EarlyBinding)
+ , initialTransition(nullptr)
{}
void add(StateOrTransition *s) Q_DECL_OVERRIDE
diff --git a/src/scxml/qscxmlcppdatamodel.cpp b/src/scxml/qscxmlcppdatamodel.cpp
index bc09d65..ba18cc7 100644
--- a/src/scxml/qscxmlcppdatamodel.cpp
+++ b/src/scxml/qscxmlcppdatamodel.cpp
@@ -52,7 +52,7 @@ using namespace QScxmlExecutableContent;
\sa QScxmlStateMachine QScxmlDataModel
- The C++ data model for SCXML that lets you write C++ code for \e expr attributes and \c <script>
+ The C++ data model for SCXML lets you write C++ code for \e expr attributes and \c <script>
elements. The \e {data part} of the data model is backed by a subclass of QScxmlCppDataModel, for
which the Qt SCXML compiler (\c qscxmlc) will generate the dispatch methods. It cannot be used
when loading an SCXML file at runtime.
@@ -69,6 +69,7 @@ using namespace QScxmlExecutableContent;
class TheDataModel: public QScxmlCppDataModel
{
+ Q_OBJECT
Q_SCXML_DATAMODEL
};
\endcode
@@ -77,8 +78,6 @@ class TheDataModel: public QScxmlCppDataModel
This macro expands to the declaration of some virtual
methods whose implementation is generated by the Qt SCXML compiler.
- \note You can of course inherit from both QScxmlCppDataModel and QObject.
-
The Qt SCXML compiler will generate the various \c evaluateTo methods, and convert expressions and
scripts into lambdas inside those methods. For example:
\code
@@ -134,11 +133,6 @@ QScxmlCppDataModel::QScxmlCppDataModel(QObject *parent)
: QScxmlDataModel(*(new QScxmlCppDataModelPrivate), parent)
{}
-/*! \internal */
-QScxmlCppDataModel::~QScxmlCppDataModel()
-{
-}
-
/*!
* Called during state machine initialization to set up a state machine using the initial values
* for data model variables specified by their keys, \a initialDataValues. These
@@ -153,33 +147,53 @@ bool QScxmlCppDataModel::setup(const QVariantMap &initialDataValues)
return true;
}
-void QScxmlCppDataModel::evaluateAssignment(EvaluatorId id, bool *ok)
+/*!
+ \reimp
+
+ This method does not perform any action, ignores \a id, and sets \a ok to
+ \c false. Override it in your specific data model in order to implement
+ \c <assign>.
+ */
+void QScxmlCppDataModel::evaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok)
{
Q_UNUSED(id);
- Q_UNUSED(ok);
- Q_UNREACHABLE();
+ *ok = false;
}
-void QScxmlCppDataModel::evaluateInitialization(EvaluatorId id, bool *ok)
+/*!
+ \reimp
+
+ This method does not perform any action, ignores \a id, and sets \a ok to
+ \c false. Override it in your specific data model in order to implement
+ \c <data>.
+ */
+void QScxmlCppDataModel::evaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok)
{
Q_UNUSED(id);
- Q_UNUSED(ok);
- Q_UNREACHABLE();
+ *ok = false;
}
-bool QScxmlCppDataModel::evaluateForeach(EvaluatorId id, bool *ok, ForeachLoopBody *body)
+/*!
+ \reimp
+
+ This method does not perform any action, ignores \a id and \a body, and sets
+ \a ok to \c false. Override it in your specific data model in order to
+ implement \c <foreach>.
+ */
+void QScxmlCppDataModel::evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok,
+ ForeachLoopBody *body)
{
Q_UNUSED(id);
- Q_UNUSED(ok);
Q_UNUSED(body);
- Q_UNREACHABLE();
- return false;
+ *ok = false;
}
/*!
- * Sets the \a event that will be processed next.
- *
- * \sa QScxmlCppDataModel::scxmlEvent
+ \reimp
+
+ Sets the \a event that will be processed next.
+
+ \sa QScxmlCppDataModel::scxmlEvent
*/
void QScxmlCppDataModel::setScxmlEvent(const QScxmlEvent &event)
{
@@ -206,7 +220,11 @@ const QScxmlEvent &QScxmlCppDataModel::scxmlEvent() const
}
/*!
- * \reimp
+ \reimp
+
+ This method always returns an empty QVariant and ignores \a name.
+ Override it to implement the lookup of data model properties via the
+ \c location attribute of various elements.
*/
QVariant QScxmlCppDataModel::scxmlProperty(const QString &name) const
{
@@ -215,7 +233,11 @@ QVariant QScxmlCppDataModel::scxmlProperty(const QString &name) const
}
/*!
- * \reimp
+ \reimp
+
+ This method always returns \c false and ignores \a name.
+ Override it to implement the lookup of data model properties via the
+ \c location attribute of various elements.
*/
bool QScxmlCppDataModel::hasScxmlProperty(const QString &name) const
{
@@ -224,20 +246,25 @@ bool QScxmlCppDataModel::hasScxmlProperty(const QString &name) const
}
/*!
- * \reimp
+ \reimp
+
+ This method always returns \c false and ignores \a name, \a value, and
+ \a context.
+ Override it to implement the lookup of data model properties via the
+ \c location attribute of various elements.
*/
-bool QScxmlCppDataModel::setScxmlProperty(const QString &name, const QVariant &value, const QString &context)
+bool QScxmlCppDataModel::setScxmlProperty(const QString &name, const QVariant &value,
+ const QString &context)
{
Q_UNUSED(name);
Q_UNUSED(value);
Q_UNUSED(context);
- Q_UNREACHABLE();
return false;
}
/*!
- * Returns \c true if the state machine is in the state specified by \a stateName, \c false
- * otherwise.
+ Returns \c true if the state machine is in the state specified by
+ \a stateName, \c false otherwise.
*/
bool QScxmlCppDataModel::inState(const QString &stateName) const
{
diff --git a/src/scxml/qscxmlcppdatamodel.h b/src/scxml/qscxmlcppdatamodel.h
index fb59336..244259f 100644
--- a/src/scxml/qscxmlcppdatamodel.h
+++ b/src/scxml/qscxmlcppdatamodel.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef CPPDATAMODEL_H
-#define CPPDATAMODEL_H
+#ifndef QSCXMLCPPDATAMODEL_H
+#define QSCXMLCPPDATAMODEL_H
#include <QtScxml/qscxmldatamodel.h>
@@ -59,15 +59,12 @@ class Q_SCXML_EXPORT QScxmlCppDataModel: public QScxmlDataModel
Q_DECLARE_PRIVATE(QScxmlCppDataModel)
public:
explicit QScxmlCppDataModel(QObject *parent = nullptr);
- ~QScxmlCppDataModel();
Q_INVOKABLE bool setup(const QVariantMap &initialDataValues) Q_DECL_OVERRIDE;
-#ifndef Q_QDOC
- void evaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
- void evaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
- bool evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) Q_DECL_OVERRIDE Q_DECL_FINAL;
-#endif // Q_QDOC
+ void evaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE;
+ void evaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE;
+ void evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) Q_DECL_OVERRIDE;
void setScxmlEvent(const QScxmlEvent &scxmlEvent) Q_DECL_OVERRIDE Q_DECL_FINAL;
const QScxmlEvent &scxmlEvent() const;
@@ -81,4 +78,4 @@ public:
QT_END_NAMESPACE
-#endif // CPPDATAMODEL_H
+#endif // QSCXMLCPPDATAMODEL_H
diff --git a/src/scxml/qscxmlcppdatamodel_p.h b/src/scxml/qscxmlcppdatamodel_p.h
index 1712a73..b342e39 100644
--- a/src/scxml/qscxmlcppdatamodel_p.h
+++ b/src/scxml/qscxmlcppdatamodel_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef CPPDATAMODEL_P_H
-#define CPPDATAMODEL_P_H
+#ifndef QSCXMLCPPDATAMODEL_P_H
+#define QSCXMLCPPDATAMODEL_P_H
//
// W A R N I N G
@@ -65,4 +65,4 @@ public:
QT_END_NAMESPACE
-#endif // CPPDATAMODEL_P_H
+#endif // QSCXMLCPPDATAMODEL_P_H
diff --git a/src/scxml/qscxmldatamodel.cpp b/src/scxml/qscxmldatamodel.cpp
index 9762e92..f7a7bb2 100644
--- a/src/scxml/qscxmldatamodel.cpp
+++ b/src/scxml/qscxmldatamodel.cpp
@@ -45,14 +45,27 @@
QT_BEGIN_NAMESPACE
/*!
- * \class QScxmlDataModel::ForeachLoopBody
- * \internal
+ \class QScxmlDataModel::ForeachLoopBody
+ \brief The ForeachLoopBody class represents a function to be executed on
+ each iteration of an SCXML foreach loop.
+ \since 5.8
+ \inmodule QtScxml
*/
+/*!
+ Destroys a foreach loop body.
+ */
QScxmlDataModel::ForeachLoopBody::~ForeachLoopBody()
{}
/*!
+ \fn QScxmlDataModel::ForeachLoopBody::run(bool *ok)
+
+ This function is executed on each iteration. If the execution fails, \a ok is
+ set to \c false, otherwise it is set to \c true.
+ */
+
+/*!
* \class QScxmlDataModel
* \brief The QScxmlDataModel class is the data model base class for a Qt SCXML
* state machine.
@@ -89,18 +102,14 @@ QScxmlDataModel::QScxmlDataModel(QObject *parent)
}
/*!
- * \internal
+ Creates a new data model from the private object \a dd, with the parent
+ object \a parent.
*/
QScxmlDataModel::QScxmlDataModel(QScxmlDataModelPrivate &dd, QObject *parent) :
QObject(dd, parent)
{
}
-/*! \internal */
-QScxmlDataModel::~QScxmlDataModel()
-{
-}
-
/*!
* 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
@@ -128,11 +137,6 @@ QScxmlStateMachine *QScxmlDataModel::stateMachine() const
return d->m_stateMachine;
}
-QScxmlTableData *QScxmlDataModel::tableData() const
-{
- return stateMachine()->tableData();
-}
-
QScxmlDataModel *QScxmlDataModelPrivate::instantiateDataModel(DocumentModel::Scxml::DataModelType type)
{
QScxmlDataModel *dataModel = Q_NULLPTR;
@@ -194,4 +198,59 @@ QScxmlDataModel *QScxmlDataModelPrivate::instantiateDataModel(DocumentModel::Scx
* Returns \c true if successful or \c false if an error occurred.
*/
+/*!
+ * \fn QScxmlDataModel::evaluateToString(
+ * QScxmlExecutableContent::EvaluatorId id, bool *ok)
+ * Evaluates the executable content pointed to by \a id and sets \a ok to
+ * \c false if there was an error or to \c true if there was not.
+ * Returns the result of the evaluation as a QString.
+ */
+
+/*!
+ * \fn QScxmlDataModel::evaluateToBool(QScxmlExecutableContent::EvaluatorId id,
+ * bool *ok)
+ * Evaluates the executable content pointed to by \a id and sets \a ok to
+ * \c false if there was an error or to \c true if there was not.
+ * Returns the result of the evaluation as a boolean value.
+ */
+
+/*!
+ * \fn QScxmlDataModel::evaluateToVariant(
+ * QScxmlExecutableContent::EvaluatorId id, bool *ok)
+ * Evaluates the executable content pointed to by \a id and sets \a ok to
+ * \c false if there was an error or to \c true if there was not.
+ * Returns the result of the evaluation as a QVariant.
+ */
+
+/*!
+ * \fn QScxmlDataModel::evaluateToVoid(QScxmlExecutableContent::EvaluatorId id,
+ * bool *ok)
+ * Evaluates the executable content pointed to by \a id and sets \a ok to
+ * \c false if there was an error or to \c true if there was not.
+ * The execution is expected to return no result.
+ */
+
+/*!
+ * \fn QScxmlDataModel::evaluateAssignment(
+ * QScxmlExecutableContent::EvaluatorId id, bool *ok)
+ * Evaluates the assignment pointed to by \a id and sets \a ok to
+ * \c false if there was an error or to \c true if there was not.
+ */
+
+/*!
+ * \fn QScxmlDataModel::evaluateInitialization(
+ * QScxmlExecutableContent::EvaluatorId id, bool *ok)
+ * Evaluates the initialization pointed to by \a id and sets \a ok to
+ * \c false if there was an error or to \c true if there was not.
+ */
+
+/*!
+ * \fn QScxmlDataModel::evaluateForeach(
+ * QScxmlExecutableContent::EvaluatorId id, bool *ok,
+ * ForeachLoopBody *body)
+ * Evaluates the foreach loop pointed to by \a id and sets \a ok to
+ * \c false if there was an error or to \c true if there was not. The
+ * \a body is executed on each iteration.
+ */
+
QT_END_NAMESPACE
diff --git a/src/scxml/qscxmldatamodel.h b/src/scxml/qscxmldatamodel.h
index 845d8bf..d34a84a 100644
--- a/src/scxml/qscxmldatamodel.h
+++ b/src/scxml/qscxmldatamodel.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef DATAMODEL_H
-#define DATAMODEL_H
+#ifndef QSCXMLDATAMODEL_H
+#define QSCXMLDATAMODEL_H
#include <QtScxml/qscxmlexecutablecontent.h>
@@ -64,27 +64,24 @@ public:
{
public:
virtual ~ForeachLoopBody();
- virtual bool run() = 0;
+ virtual void run(bool *ok) = 0;
};
public:
explicit QScxmlDataModel(QObject *parent = nullptr);
- ~QScxmlDataModel();
void setStateMachine(QScxmlStateMachine *stateMachine);
QScxmlStateMachine *stateMachine() const;
Q_INVOKABLE virtual bool setup(const QVariantMap &initialDataValues) = 0;
-#ifndef Q_QDOC
virtual QString evaluateToString(QScxmlExecutableContent::EvaluatorId id, bool *ok) = 0;
virtual bool evaluateToBool(QScxmlExecutableContent::EvaluatorId id, bool *ok) = 0;
virtual QVariant evaluateToVariant(QScxmlExecutableContent::EvaluatorId id, bool *ok) = 0;
virtual void evaluateToVoid(QScxmlExecutableContent::EvaluatorId id, bool *ok) = 0;
virtual void evaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok) = 0;
virtual void evaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok) = 0;
- virtual bool evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) = 0;
-#endif // Q_QDOC
+ virtual void evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) = 0;
virtual void setScxmlEvent(const QScxmlEvent &event) = 0;
@@ -97,11 +94,8 @@ Q_SIGNALS:
protected:
explicit QScxmlDataModel(QScxmlDataModelPrivate &dd, QObject *parent = nullptr);
-#ifndef Q_QDOC
- QScxmlTableData *tableData() const;
-#endif // Q_QDOC
};
QT_END_NAMESPACE
-#endif // DATAMODEL_H
+#endif // QSCXMLDATAMODEL_H
diff --git a/src/scxml/qscxmlecmascriptdatamodel.cpp b/src/scxml/qscxmlecmascriptdatamodel.cpp
index 32c49f0..e517989 100644
--- a/src/scxml/qscxmlecmascriptdatamodel.cpp
+++ b/src/scxml/qscxmlecmascriptdatamodel.cpp
@@ -121,25 +121,26 @@ public:
QJSEngine *engine = assertEngine();
dataModel = engine->globalObject();
- qCDebug(qscxmlLog) << stateMachine() << "initializing the datamodel";
+ qCDebug(qscxmlLog) << m_stateMachine << "initializing the datamodel";
setupSystemVariables();
}
void setupSystemVariables()
{
setReadonlyProperty(&dataModel, QStringLiteral("_sessionid"),
- stateMachine()->sessionId());
+ m_stateMachine->sessionId());
- setReadonlyProperty(&dataModel, QStringLiteral("_name"), stateMachine()->name());
+ setReadonlyProperty(&dataModel, QStringLiteral("_name"), m_stateMachine->name());
QJSEngine *engine = assertEngine();
auto scxml = engine->newObject();
- scxml.setProperty(QStringLiteral("location"), QStringLiteral("#_scxml_%1").arg(stateMachine()->sessionId()));
+ scxml.setProperty(QStringLiteral("location"), QStringLiteral("#_scxml_%1")
+ .arg(m_stateMachine->sessionId()));
auto ioProcs = engine->newObject();
setReadonlyProperty(&ioProcs, QStringLiteral("scxml"), scxml);
setReadonlyProperty(&dataModel, QStringLiteral("_ioprocessors"), ioProcs);
- auto platformVars = QScxmlPlatformProperties::create(engine, stateMachine());
+ auto platformVars = QScxmlPlatformProperties::create(engine, m_stateMachine);
dataModel.setProperty(QStringLiteral("_x"), platformVars->jsValue());
dataModel.setProperty(QStringLiteral("In"), engine->evaluate(
@@ -204,12 +205,6 @@ public:
return engine->toScriptValue(data);
}
- QScxmlStateMachine *stateMachine() const
- {
- Q_Q(const QScxmlEcmaScriptDataModel);
- return q->stateMachine();
- }
-
QJSEngine *assertEngine()
{
if (!jsEngine) {
@@ -230,8 +225,7 @@ public:
QString string(StringId id) const
{
- Q_Q(const QScxmlEcmaScriptDataModel);
- return q->tableData()->string(id);
+ return m_stateMachine->tableData()->string(id);
}
bool hasProperty(const QString &name) const
@@ -265,7 +259,7 @@ public:
void submitError(const QString &type, const QString &msg, const QString &sendid = QString())
{
- QScxmlStateMachinePrivate::get(stateMachine())->submitError(type, msg, sendid);
+ QScxmlStateMachinePrivate::get(m_stateMachine)->submitError(type, msg, sendid);
}
public:
@@ -370,11 +364,6 @@ QScxmlEcmaScriptDataModel::QScxmlEcmaScriptDataModel(QObject *parent)
: QScxmlDataModel(*(new QScxmlEcmaScriptDataModelPrivate), parent)
{}
-/*! \internal */
-QScxmlEcmaScriptDataModel::~QScxmlEcmaScriptDataModel()
-{
-}
-
/*!
\reimp
*/
@@ -386,7 +375,7 @@ bool QScxmlEcmaScriptDataModel::setup(const QVariantMap &initialDataValues)
bool ok = true;
QJSValue undefined(QJSValue::UndefinedValue); // See B.2.1, and test456.
int count;
- StringId *names = tableData()->dataNames(&count);
+ StringId *names = d->m_stateMachine->tableData()->dataNames(&count);
for (int i = 0; i < count; ++i) {
auto name = d->string(names[i]);
QJSValue v = undefined;
@@ -404,44 +393,64 @@ bool QScxmlEcmaScriptDataModel::setup(const QVariantMap &initialDataValues)
return ok;
}
-QString QScxmlEcmaScriptDataModel::evaluateToString(EvaluatorId id, bool *ok)
+/*!
+ \reimp
+ */
+QString QScxmlEcmaScriptDataModel::evaluateToString(QScxmlExecutableContent::EvaluatorId id,
+ bool *ok)
{
Q_D(QScxmlEcmaScriptDataModel);
- const EvaluatorInfo &info = tableData()->evaluatorInfo(id);
+ const EvaluatorInfo &info = d->m_stateMachine->tableData()->evaluatorInfo(id);
return d->evalStr(d->string(info.expr), d->string(info.context), ok);
}
-bool QScxmlEcmaScriptDataModel::evaluateToBool(EvaluatorId id, bool *ok)
+/*!
+ \reimp
+ */
+bool QScxmlEcmaScriptDataModel::evaluateToBool(QScxmlExecutableContent::EvaluatorId id,
+ bool *ok)
{
Q_D(QScxmlEcmaScriptDataModel);
- const EvaluatorInfo &info = tableData()->evaluatorInfo(id);
+ const EvaluatorInfo &info = d->m_stateMachine->tableData()->evaluatorInfo(id);
return d->evalBool(d->string(info.expr), d->string(info.context), ok);
}
-QVariant QScxmlEcmaScriptDataModel::evaluateToVariant(EvaluatorId id, bool *ok)
+/*!
+ \reimp
+ */
+QVariant QScxmlEcmaScriptDataModel::evaluateToVariant(QScxmlExecutableContent::EvaluatorId id,
+ bool *ok)
{
Q_D(QScxmlEcmaScriptDataModel);
- const EvaluatorInfo &info = tableData()->evaluatorInfo(id);
+ const EvaluatorInfo &info = d->m_stateMachine->tableData()->evaluatorInfo(id);
return d->evalJSValue(d->string(info.expr), d->string(info.context), ok).toVariant();
}
-void QScxmlEcmaScriptDataModel::evaluateToVoid(EvaluatorId id, bool *ok)
+/*!
+ \reimp
+ */
+void QScxmlEcmaScriptDataModel::evaluateToVoid(QScxmlExecutableContent::EvaluatorId id,
+ bool *ok)
{
Q_D(QScxmlEcmaScriptDataModel);
- const EvaluatorInfo &info = tableData()->evaluatorInfo(id);
+ const EvaluatorInfo &info = d->m_stateMachine->tableData()->evaluatorInfo(id);
d->eval(d->string(info.expr), d->string(info.context), ok);
}
-void QScxmlEcmaScriptDataModel::evaluateAssignment(EvaluatorId id, bool *ok)
+/*!
+ \reimp
+ */
+void QScxmlEcmaScriptDataModel::evaluateAssignment(QScxmlExecutableContent::EvaluatorId id,
+ bool *ok)
{
Q_D(QScxmlEcmaScriptDataModel);
Q_ASSERT(ok);
- const AssignmentInfo &info = tableData()->assignmentInfo(id);
+ const AssignmentInfo &info = d->m_stateMachine->tableData()->assignmentInfo(id);
QString dest = d->string(info.dest);
@@ -456,10 +465,14 @@ void QScxmlEcmaScriptDataModel::evaluateAssignment(EvaluatorId id, bool *ok)
}
}
-void QScxmlEcmaScriptDataModel::evaluateInitialization(EvaluatorId id, bool *ok)
+/*!
+ \reimp
+ */
+void QScxmlEcmaScriptDataModel::evaluateInitialization(QScxmlExecutableContent::EvaluatorId id,
+ bool *ok)
{
Q_D(QScxmlEcmaScriptDataModel);
- const AssignmentInfo &info = tableData()->assignmentInfo(id);
+ const AssignmentInfo &info = d->m_stateMachine->tableData()->assignmentInfo(id);
QString dest = d->string(info.dest);
if (d->initialDataNames.contains(dest)) {
*ok = true; // silently ignore the <data> tag
@@ -469,18 +482,22 @@ void QScxmlEcmaScriptDataModel::evaluateInitialization(EvaluatorId id, bool *ok)
evaluateAssignment(id, ok);
}
-bool QScxmlEcmaScriptDataModel::evaluateForeach(EvaluatorId id, bool *ok, ForeachLoopBody *body)
+/*!
+ \reimp
+ */
+void QScxmlEcmaScriptDataModel::evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok,
+ ForeachLoopBody *body)
{
Q_D(QScxmlEcmaScriptDataModel);
Q_ASSERT(ok);
Q_ASSERT(body);
- const ForeachInfo &info = tableData()->foreachInfo(id);
+ const ForeachInfo &info = d->m_stateMachine->tableData()->foreachInfo(id);
QJSValue jsArray = d->property(d->string(info.array));
if (!jsArray.isArray()) {
d->submitError(QStringLiteral("error.execution"), QStringLiteral("invalid array '%1' in %2").arg(d->string(info.array), d->string(info.context)));
*ok = false;
- return false;
+ return;
}
QString item = d->string(info.item);
@@ -490,7 +507,7 @@ bool QScxmlEcmaScriptDataModel::evaluateForeach(EvaluatorId id, bool *ok, Foreac
d->submitError(QStringLiteral("error.execution"), QStringLiteral("invalid item '%1' in %2")
.arg(d->string(info.item), d->string(info.context)));
*ok = false;
- return false;
+ return;
}
const int length = jsArray.property(QStringLiteral("length")).toInt();
@@ -502,17 +519,17 @@ bool QScxmlEcmaScriptDataModel::evaluateForeach(EvaluatorId id, bool *ok, Foreac
QJSValue currentItem = jsArray.property(static_cast<quint32>(currentIndex));
*ok = d->setProperty(item, currentItem, context);
if (!*ok)
- return false;
+ return;
if (hasIndex) {
*ok = d->setProperty(idx, currentIndex, context);
if (!*ok)
- return false;
+ return;
}
- if (!body->run())
- return false;
+ body->run(ok);
+ if (!*ok)
+ return;
}
-
- return true;
+ *ok = true;
}
/*!
diff --git a/src/scxml/qscxmlecmascriptdatamodel.h b/src/scxml/qscxmlecmascriptdatamodel.h
index b1d9f55..7c22044 100644
--- a/src/scxml/qscxmlecmascriptdatamodel.h
+++ b/src/scxml/qscxmlecmascriptdatamodel.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef ECMASCRIPTDATAMODEL_H
-#define ECMASCRIPTDATAMODEL_H
+#ifndef QSCXMLECMASCRIPTDATAMODEL_H
+#define QSCXMLECMASCRIPTDATAMODEL_H
#include <QtScxml/qscxmldatamodel.h>
@@ -52,19 +52,16 @@ class Q_SCXML_EXPORT QScxmlEcmaScriptDataModel: public QScxmlDataModel
Q_DECLARE_PRIVATE(QScxmlEcmaScriptDataModel)
public:
explicit QScxmlEcmaScriptDataModel(QObject *parent = nullptr);
- ~QScxmlEcmaScriptDataModel();
Q_INVOKABLE bool setup(const QVariantMap &initialDataValues) Q_DECL_OVERRIDE;
-#ifndef Q_QDOC
QString evaluateToString(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
bool evaluateToBool(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
QVariant evaluateToVariant(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
void evaluateToVoid(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
void evaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
void evaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
- bool evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) Q_DECL_OVERRIDE Q_DECL_FINAL;
-#endif // Q_QDOC
+ void evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) Q_DECL_OVERRIDE Q_DECL_FINAL;
void setScxmlEvent(const QScxmlEvent &event) Q_DECL_OVERRIDE;
@@ -75,4 +72,4 @@ public:
QT_END_NAMESPACE
-#endif // ECMASCRIPTDATAMODEL_H
+#endif // QSCXMLECMASCRIPTDATAMODEL_H
diff --git a/src/scxml/qscxmlecmascriptplatformproperties_p.h b/src/scxml/qscxmlecmascriptplatformproperties_p.h
index fef53ea..cf1c4a9 100644
--- a/src/scxml/qscxmlecmascriptplatformproperties_p.h
+++ b/src/scxml/qscxmlecmascriptplatformproperties_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef ECMASCRIPTPLATFORMPROPERTIES_P_H
-#define ECMASCRIPTPLATFORMPROPERTIES_P_H
+#ifndef QSCXMLECMASCRIPTPLATFORMPROPERTIES_P_H
+#define QSCXMLECMASCRIPTPLATFORMPROPERTIES_P_H
//
// W A R N I N G
@@ -86,4 +86,4 @@ private:
QT_END_NAMESPACE
-#endif // ECMASCRIPTPLATFORMPROPERTIES_P_H
+#endif // QSCXMLECMASCRIPTPLATFORMPROPERTIES_P_H
diff --git a/src/scxml/qscxmlevent.h b/src/scxml/qscxmlevent.h
index c4f517f..267f5ec 100644
--- a/src/scxml/qscxmlevent.h
+++ b/src/scxml/qscxmlevent.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef SCXMLEVENT_H
-#define SCXMLEVENT_H
+#ifndef QSCXMLEVENT_H
+#define QSCXMLEVENT_H
#include <QtScxml/qscxmlglobals.h>
@@ -119,4 +119,4 @@ QT_END_NAMESPACE
Q_DECLARE_METATYPE(QScxmlEvent)
-#endif // SCXMLEVENT_H
+#endif // QSCXMLEVENT_H
diff --git a/src/scxml/qscxmlevent_p.h b/src/scxml/qscxmlevent_p.h
index aef14d1..15bd6fa 100644
--- a/src/scxml/qscxmlevent_p.h
+++ b/src/scxml/qscxmlevent_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef SCXMLEVENT_P_H
-#define SCXMLEVENT_P_H
+#ifndef QSCXMLEVENT_P_H
+#define QSCXMLEVENT_P_H
//
// W A R N I N G
@@ -177,5 +177,5 @@ public:
QT_END_NAMESPACE
-#endif // SCXMLEVENT_P_H
+#endif // QSCXMLEVENT_P_H
diff --git a/src/scxml/qscxmlexecutablecontent.cpp b/src/scxml/qscxmlexecutablecontent.cpp
index 5df8b1f..682ea47 100644
--- a/src/scxml/qscxmlexecutablecontent.cpp
+++ b/src/scxml/qscxmlexecutablecontent.cpp
@@ -46,6 +46,177 @@ QT_BEGIN_NAMESPACE
using namespace QScxmlExecutableContent;
+/*!
+ \namespace QScxmlExecutableContent
+ \inmodule QtScxml
+ \since 5.8
+ \brief The QScxmlExecutableContent namespace contains various types used
+ to interpret executable content in state machines.
+ */
+
+/*!
+ \typedef QScxmlExecutableContent::ContainerId
+ \inmodule QtScxml
+ \since 5.8
+ \brief ID for a container holding executable content.
+ */
+
+/*!
+ \typedef QScxmlExecutableContent::EvaluatorId
+ \inmodule QtScxml
+ \since 5.8
+ \brief ID for a unit of executable content.
+ */
+
+/*!
+ \typedef QScxmlExecutableContent::InstructionId
+ \inmodule QtScxml
+ \since 5.8
+ \brief ID for an instruction of executable content.
+ */
+
+/*!
+ \typedef QScxmlExecutableContent::StringId
+ \inmodule QtScxml
+ \since 5.8
+ \brief ID for a string contained in executable content.
+ */
+
+/*!
+ \class QScxmlExecutableContent::EvaluatorInfo
+ \brief The EvaluatorInfo class represents a unit of executable content.
+ \since 5.8
+ \inmodule QtScxml
+ */
+
+/*!
+ \variable QScxmlExecutableContent::EvaluatorInfo::expr
+ \brief The expression to be evaluated
+ */
+
+/*!
+ \variable QScxmlExecutableContent::EvaluatorInfo::context
+ \brief The context for evaluating the expression
+ */
+
+/*!
+ \class QScxmlExecutableContent::AssignmentInfo
+ \brief The AssingmentInfo class represents a data assignment.
+ \since 5.8
+ \inmodule QtScxml
+ */
+
+/*!
+ \variable QScxmlExecutableContent::AssignmentInfo::expr
+ \brief The expression to be evaluated
+ */
+
+/*!
+ \variable QScxmlExecutableContent::AssignmentInfo::context
+ \brief The context for evaluating the expression
+ */
+
+/*!
+ \variable QScxmlExecutableContent::AssignmentInfo::dest
+ \brief The name of the data item to assign to
+ */
+
+/*!
+ \class QScxmlExecutableContent::ForeachInfo
+ \brief The ForeachInfo class represents a foreach construct.
+ \since 5.8
+ \inmodule QtScxml
+ */
+
+/*!
+ \variable QScxmlExecutableContent::ForeachInfo::array
+ \brief The name of the array that is iterated over
+ */
+
+/*!
+ \variable QScxmlExecutableContent::ForeachInfo::item
+ \brief The name of the iteration variable
+ */
+
+/*!
+ \variable QScxmlExecutableContent::ForeachInfo::index
+ \brief The name of the index variable
+ */
+
+/*!
+ \variable QScxmlExecutableContent::ForeachInfo::context
+ \brief The context for evaluating the expression
+ */
+
+/*!
+ \class QScxmlExecutableContent::ParameterInfo
+ \brief The ParameterInfo class represents a parameter to a service
+ invocation.
+ \since 5.8
+ \inmodule QtScxml
+ */
+
+/*!
+ \variable QScxmlExecutableContent::ParameterInfo::name
+ \brief The name of the parameter
+ */
+
+/*!
+ \variable QScxmlExecutableContent::ParameterInfo::expr
+ \brief The expression to be evaluated
+ */
+
+/*!
+ \variable QScxmlExecutableContent::ParameterInfo::location
+ \brief The data model name of the item to be passed as a parameter
+ */
+
+/*!
+ \class QScxmlExecutableContent::InvokeInfo
+ \brief The InvokeInfo class represents a service invocation.
+ \since 5.8
+ \inmodule QtScxml
+ */
+
+/*!
+ \variable QScxmlExecutableContent::InvokeInfo::id
+ \brief The ID specified by the \c id attribute in the \c <invoke> element.
+ */
+
+/*!
+ \variable QScxmlExecutableContent::InvokeInfo::prefix
+ \brief The unique prefix for this invocation in the context of the state
+ from which it is called
+ */
+
+/*!
+ \variable QScxmlExecutableContent::InvokeInfo::location
+ \brief The data model location to write the invocation ID to
+ */
+
+/*!
+ \variable QScxmlExecutableContent::InvokeInfo::context
+ \brief The context to interpret the location in
+ */
+
+/*!
+ \variable QScxmlExecutableContent::InvokeInfo::expr
+ \brief The expression representing the srcexpr of the invoke element
+ */
+
+/*!
+ \variable QScxmlExecutableContent::InvokeInfo::finalize
+ \brief The ID of the container of executable content to be run on finalizing
+ the invocation
+ */
+
+/*!
+ \variable QScxmlExecutableContent::InvokeInfo::autoforward
+ \brief Whether events should automatically be forwarded to the invoked
+ service
+ */
+
+
#ifndef BUILD_QSCXMLC
static int parseTime(const QString &t, bool *ok = 0)
{
@@ -216,11 +387,9 @@ const InstructionId *QScxmlExecutionEngine::step(const InstructionId *ip, bool *
, loopStart(loopStart)
{}
- bool run() Q_DECL_OVERRIDE
+ void run(bool *ok) Q_DECL_OVERRIDE
{
- bool ok = true;
- engine->step(loopStart, &ok);
- return ok;
+ engine->step(loopStart, ok);
}
};
@@ -229,7 +398,7 @@ const InstructionId *QScxmlExecutionEngine::step(const InstructionId *ip, bool *
const InstructionId *loopStart = _foreach->blockstart();
ip += _foreach->size();
LoopBody body(this, loopStart);
- *ok = dataModel->evaluateForeach(_foreach->doIt, ok, &body) && *ok;
+ dataModel->evaluateForeach(_foreach->doIt, ok, &body);
return ip;
}
diff --git a/src/scxml/qscxmlexecutablecontent.h b/src/scxml/qscxmlexecutablecontent.h
index cdf6b2b..8d2ef13 100644
--- a/src/scxml/qscxmlexecutablecontent.h
+++ b/src/scxml/qscxmlexecutablecontent.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef EXECUTABLECONTENT_H
-#define EXECUTABLECONTENT_H
+#ifndef QSCXMLEXECUTABLECONTENT_H
+#define QSCXMLEXECUTABLECONTENT_H
#include <QtScxml/qscxmlglobals.h>
@@ -99,4 +99,4 @@ struct InvokeInfo {
QT_END_NAMESPACE
-#endif // EXECUTABLECONTENT_H
+#endif // QSCXMLEXECUTABLECONTENT_H
diff --git a/src/scxml/qscxmlexecutablecontent_p.h b/src/scxml/qscxmlexecutablecontent_p.h
index 4429686..cfaec55 100644
--- a/src/scxml/qscxmlexecutablecontent_p.h
+++ b/src/scxml/qscxmlexecutablecontent_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef EXECUTABLECONTENT_P_H
-#define EXECUTABLECONTENT_P_H
+#ifndef QSCXMLEXECUTABLECONTENT_P_H
+#define QSCXMLEXECUTABLECONTENT_P_H
//
// W A R N I N G
@@ -61,6 +61,7 @@
#include <QtScxml/qscxmlstatemachine.h>
#endif // BUILD_QSCXMLC
+#ifndef Q_QDOC
QT_BEGIN_NAMESPACE
namespace QScxmlExecutableContent {
@@ -509,5 +510,6 @@ private:
};
QT_END_NAMESPACE
+#endif // Q_QDOC
-#endif // EXECUTABLECONTENT_P_H
+#endif // QSCXMLEXECUTABLECONTENT_P_H
diff --git a/src/scxml/qscxmlglobals.h b/src/scxml/qscxmlglobals.h
index d9bf7b5..8672aa1 100644
--- a/src/scxml/qscxmlglobals.h
+++ b/src/scxml/qscxmlglobals.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef SCXMLGLOBALS_H
-#define SCXMLGLOBALS_H
+#ifndef QSCXMLGLOBALS_H
+#define QSCXMLGLOBALS_H
#include <QtCore/qglobal.h>
QT_BEGIN_NAMESPACE
@@ -55,5 +55,5 @@ QT_BEGIN_NAMESPACE
QT_END_NAMESPACE
-#endif // SCXMLGLOBALS_H
+#endif // QSCXMLGLOBALS_H
diff --git a/src/scxml/qscxmlglobals_p.h b/src/scxml/qscxmlglobals_p.h
index 48b3d73..559636b 100644
--- a/src/scxml/qscxmlglobals_p.h
+++ b/src/scxml/qscxmlglobals_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef SCXMLGLOBALS_P_H
-#define SCXMLGLOBALS_P_H
+#ifndef QSCXMLGLOBALS_P_H
+#define QSCXMLGLOBALS_P_H
//
// W A R N I N G
@@ -62,4 +62,4 @@ Q_DECLARE_LOGGING_CATEGORY(scxmlLog)
QT_END_NAMESPACE
-#endif // SCXMLGLOBALS_P_H
+#endif // QSCXMLGLOBALS_P_H
diff --git a/src/scxml/qscxmlinvokableservice.cpp b/src/scxml/qscxmlinvokableservice.cpp
index 9af6be7..a897eaa 100644
--- a/src/scxml/qscxmlinvokableservice.cpp
+++ b/src/scxml/qscxmlinvokableservice.cpp
@@ -43,6 +43,112 @@
QT_BEGIN_NAMESPACE
+/*!
+ * \class QScxmlInvokableService
+ * \brief The QScxmlInvokableService class is the base class for services called
+ * from state machines.
+ * \since 5.8
+ * \inmodule QtScxml
+ *
+ * The services are called from state machines via the mechanism described in
+ * \l {SCXML Specification - 6.4 <invoke>}. This class represents an actual
+ * instance of an invoked service.
+ */
+
+/*!
+ * \class QScxmlInvokableServiceFactory
+ * \brief The QScxmlInvokableServiceFactory class creates invokable service
+ * instances.
+ * \since 5.8
+ * \inmodule QtScxml
+ *
+ * Each service instance represents
+ * an \c <invoke> element in the SCXML document. Each time the service is
+ * actually invoked, a new instance of QScxmlInvokableService is created.
+ */
+
+/*!
+ \property QScxmlInvokableServiceFactory::invokeInfo
+
+ \brief The QScxmlExecutableContent::InvokeInfo passed to the constructor.
+ */
+
+/*!
+ \property QScxmlInvokableServiceFactory::names
+
+ \brief The names passed to the constructor.
+ */
+
+/*!
+ \property QScxmlInvokableServiceFactory::parameters
+
+ \brief The parameters passed to the constructor.
+ */
+
+/*!
+ * \class QScxmlStaticScxmlServiceFactory
+ * \brief The QScxmlStaticScxmlServiceFactory class creates SCXML service
+ * instances from precompiled documents.
+ * \since 5.8
+ * \inmodule QtScxml
+ *
+ * A factory for instantiating SCXML state machines from files known at compile
+ * time, that is, files specified via the \c src attribute in \c <invoke>.
+ */
+
+/*!
+ * \class QScxmlDynamicScxmlServiceFactory
+ * \brief The QScxmlDynamicScxmlServiceFactory class creates SCXML service
+ * instances from documents loaded at runtime.
+ * \since 5.8
+ * \inmodule QtScxml
+ *
+ * Dynamically resolved services are used when loading \l{SCXML Specification}
+ * {SCXML} content from files that a
+ * parent state machine requests at runtime, via the \c srcexpr attribute in
+ * the \c <invoke> element.
+ */
+
+/*!
+ * \property QScxmlInvokableService::parentStateMachine
+ *
+ * \brief The SCXML state machine that invoked the service.
+ */
+
+/*!
+ * \property QScxmlInvokableService::id
+ *
+ * \brief The ID of the invokable service.
+ *
+ * The ID is specified by the \c id attribute of the \c <invoke> element.
+ */
+
+/*!
+ * \property QScxmlInvokableService::name
+ *
+ * \brief The name of the service being invoked.
+ */
+
+/*!
+ * \fn QScxmlInvokableService::postEvent(QScxmlEvent *event)
+ *
+ * Sends an \a event to the service.
+ */
+
+/*!
+ * \fn QScxmlInvokableService::start()
+ *
+ * Starts the invokable service. Returns \c true on success, or \c false if the
+ * invocation fails.
+ */
+
+/*!
+ * \fn QScxmlInvokableServiceFactory::invoke(QScxmlStateMachine *parentStateMachine)
+ *
+ * Invokes the service with the parameters given in the constructor, passing
+ * \a parentStateMachine as the parent. Returns the new invokable service.
+ */
+
QScxmlInvokableServicePrivate::QScxmlInvokableServicePrivate(QScxmlStateMachine *parentStateMachine)
: parentStateMachine(parentStateMachine)
{
@@ -59,9 +165,18 @@ QScxmlInvokableServiceFactoryPrivate::QScxmlInvokableServiceFactoryPrivate(
, parameters(parameters)
{}
+QScxmlStaticScxmlServiceFactoryPrivate::QScxmlStaticScxmlServiceFactoryPrivate(
+ const QMetaObject *metaObject,
+ const QScxmlExecutableContent::InvokeInfo &invokeInfo,
+ const QVector<QScxmlExecutableContent::StringId> &names,
+ const QVector<QScxmlExecutableContent::ParameterInfo> &parameters)
+ : QScxmlInvokableServiceFactoryPrivate(invokeInfo, names, parameters), metaObject(metaObject)
+{
+}
+
QScxmlInvokableService::QScxmlInvokableService(QScxmlStateMachine *parentStateMachine,
- QObject *parent) :
- QObject(*(new QScxmlInvokableServicePrivate(parentStateMachine)), parent)
+ QScxmlInvokableServiceFactory *factory) :
+ QObject(*(new QScxmlInvokableServicePrivate(parentStateMachine)), factory)
{
}
@@ -71,58 +186,43 @@ QScxmlStateMachine *QScxmlInvokableService::parentStateMachine() const
return d->parentStateMachine;
}
-void QScxmlInvokableService::finalize(QScxmlExecutableContent::ContainerId finalize)
-{
- if (finalize != QScxmlExecutableContent::NoInstruction) {
- auto psm = parentStateMachine();
- qCDebug(qscxmlLog) << psm << "running finalize on event";
- auto smp = QScxmlStateMachinePrivate::get(psm);
- smp->m_executionEngine->execute(finalize);
- }
-}
-
-QScxmlInvokableService::QScxmlInvokableService(QScxmlInvokableServicePrivate &dd, QObject *parent) :
- QObject(dd, parent)
-{
-}
-
QScxmlInvokableServiceFactory::QScxmlInvokableServiceFactory(
const QScxmlExecutableContent::InvokeInfo &invokeInfo,
const QVector<QScxmlExecutableContent::StringId> &names,
- const QVector<QScxmlExecutableContent::ParameterInfo> &parameters)
- : d(new QScxmlInvokableServiceFactoryPrivate(invokeInfo, names, parameters))
+ const QVector<QScxmlExecutableContent::ParameterInfo> &parameters,
+ QObject *parent)
+ : QObject(*(new QScxmlInvokableServiceFactoryPrivate(invokeInfo, names, parameters)), parent)
{}
-QScxmlInvokableServiceFactory::~QScxmlInvokableServiceFactory()
-{
- delete d;
-}
-
-QScxmlExecutableContent::InvokeInfo QScxmlInvokableServiceFactory::invokeInfo() const
+const QScxmlExecutableContent::InvokeInfo &QScxmlInvokableServiceFactory::invokeInfo() const
{
+ Q_D(const QScxmlInvokableServiceFactory);
return d->invokeInfo;
}
-QVector<QScxmlExecutableContent::ParameterInfo> QScxmlInvokableServiceFactory::parameters() const
+const QVector<QScxmlExecutableContent::ParameterInfo> &
+QScxmlInvokableServiceFactory::parameters() const
{
+ Q_D(const QScxmlInvokableServiceFactory);
return d->parameters;
}
-QVector<QScxmlExecutableContent::StringId> QScxmlInvokableServiceFactory::names() const
+const QVector<QScxmlExecutableContent::StringId> &QScxmlInvokableServiceFactory::names() const
{
+ Q_D(const QScxmlInvokableServiceFactory);
return d->names;
}
-QString QScxmlInvokableServiceFactoryPrivate::calculateSrcexpr(QScxmlStateMachine *parent,
- bool *ok) const
+QString calculateSrcexpr(QScxmlStateMachine *parent, QScxmlExecutableContent::EvaluatorId srcexpr,
+ bool *ok)
{
Q_ASSERT(ok);
*ok = true;
auto dataModel = parent->dataModel();
- if (invokeInfo.expr != QScxmlExecutableContent::NoEvaluator) {
+ if (srcexpr != QScxmlExecutableContent::NoEvaluator) {
*ok = false;
- auto v = dataModel->evaluateToString(invokeInfo.expr, ok);
+ auto v = dataModel->evaluateToString(srcexpr, ok);
if (!*ok)
return QString();
return v;
@@ -217,106 +317,142 @@ QVariantMap QScxmlInvokableServicePrivate::calculateData(
return result;
}
-QScxmlScxmlServicePrivate::QScxmlScxmlServicePrivate(QScxmlStateMachine *stateMachine,
- QScxmlStateMachine *parentStateMachine) :
- QScxmlInvokableServicePrivate(parentStateMachine), stateMachine(stateMachine)
-{}
-
-QScxmlScxmlServicePrivate::~QScxmlScxmlServicePrivate()
+QScxmlScxmlService::~QScxmlScxmlService()
{
delete stateMachine;
}
+/*!
+ Creates a SCXML service wrapping \a stateMachine, invoked from
+ \a parentStateMachine, as a child of \a factory.
+ */
QScxmlScxmlService::QScxmlScxmlService(QScxmlStateMachine *stateMachine,
QScxmlStateMachine *parentStateMachine,
- QObject *parent)
- : QScxmlInvokableService(*(new QScxmlScxmlServicePrivate(stateMachine, parentStateMachine)),
- parent)
+ QScxmlInvokableServiceFactory *factory)
+ : QScxmlInvokableService(parentStateMachine, factory), stateMachine(stateMachine)
{
QScxmlStateMachinePrivate::get(stateMachine)->m_parentStateMachine = parentStateMachine;
}
-bool QScxmlScxmlService::start(const QScxmlExecutableContent::InvokeInfo &invokeInfo,
- const QVector<QScxmlExecutableContent::ParameterInfo> &parameters,
- const QVector<QScxmlExecutableContent::StringId> &names)
+/*!
+ * \reimp
+ */
+bool QScxmlScxmlService::start()
{
- Q_D(QScxmlScxmlService);
- qCDebug(qscxmlLog) << parentStateMachine() << "preparing to start" << d->stateMachine;
+ Q_D(QScxmlInvokableService);
+ qCDebug(qscxmlLog) << parentStateMachine() << "preparing to start" << stateMachine;
+
+ const QScxmlInvokableServiceFactory *factory
+ = qobject_cast<QScxmlInvokableServiceFactory *>(parent());
+ Q_ASSERT(factory);
bool ok = false;
- auto id = d->calculateId(parentStateMachine(), invokeInfo, &ok);
+ auto id = d->calculateId(parentStateMachine(), factory->invokeInfo(), &ok);
if (!ok)
return false;
- auto data = d->calculateData(parentStateMachine(), parameters, names, &ok);
+ auto data = d->calculateData(parentStateMachine(), factory->parameters(), factory->names(),
+ &ok);
if (!ok)
return false;
- QScxmlStateMachinePrivate::get(d->stateMachine)->m_sessionId = id;
- d->stateMachine->setInitialValues(data);
- if (d->stateMachine->init()) {
- qCDebug(qscxmlLog) << parentStateMachine() << "starting" << d->stateMachine;
- d->stateMachine->start();
+ QScxmlStateMachinePrivate::get(stateMachine)->m_sessionId = id;
+ stateMachine->setInitialValues(data);
+ if (stateMachine->init()) {
+ qCDebug(qscxmlLog) << parentStateMachine() << "starting" << stateMachine;
+ stateMachine->start();
return true;
}
- qCDebug(qscxmlLog) << parentStateMachine() << "failed to start" << d->stateMachine;
+ qCDebug(qscxmlLog) << parentStateMachine() << "failed to start" << stateMachine;
return false;
}
+/*!
+ \reimp
+ */
QString QScxmlScxmlService::id() const
{
- Q_D(const QScxmlScxmlService);
- return d->stateMachine->sessionId();
+ return stateMachine->sessionId();
}
+/*!
+ \reimp
+ */
QString QScxmlScxmlService::name() const
{
- Q_D(const QScxmlScxmlService);
- return d->stateMachine->name();
+ return stateMachine->name();
}
+/*!
+ \reimp
+ */
void QScxmlScxmlService::postEvent(QScxmlEvent *event)
{
- Q_D(QScxmlScxmlService);
- QScxmlStateMachinePrivate::get(d->stateMachine)->postEvent(event);
-}
-
-QScxmlStateMachine *QScxmlScxmlService::stateMachine() const
-{
- Q_D(const QScxmlScxmlService);
- return d->stateMachine;
-}
-
-QScxmlScxmlServiceFactory::QScxmlScxmlServiceFactory(
- const QScxmlExecutableContent::InvokeInfo &invokeInfo,
- const QVector<QScxmlExecutableContent::StringId> &names,
- const QVector<QScxmlExecutableContent::ParameterInfo> &parameters)
- : QScxmlInvokableServiceFactory(invokeInfo, names, parameters)
-{}
-
-QScxmlScxmlService *QScxmlScxmlServiceFactory::invokeStatic(QScxmlStateMachine *childStateMachine,
- QScxmlStateMachine *parentStateMachine)
-{
- QScxmlStateMachinePrivate::get(childStateMachine)->setIsInvoked(true);
- return new QScxmlScxmlService(childStateMachine, parentStateMachine);
+ QScxmlStateMachinePrivate::get(stateMachine)->postEvent(event);
}
+/*!
+ Creates a factory for dynamically resolved services, passing the attributes of
+ the \c <invoke> element as \a invokeInfo, any \c <param> child elements as
+ \a parameters, the content of the \c names attribute as \a names, and the
+ QObject parent \a parent.
+ */
QScxmlDynamicScxmlServiceFactory::QScxmlDynamicScxmlServiceFactory(
const QScxmlExecutableContent::InvokeInfo &invokeInfo,
const QVector<QScxmlExecutableContent::StringId> &names,
- const QVector<QScxmlExecutableContent::ParameterInfo> &parameters)
- : QScxmlScxmlServiceFactory(invokeInfo, names, parameters)
+ const QVector<QScxmlExecutableContent::ParameterInfo> &parameters,
+ QObject *parent)
+ : QScxmlInvokableServiceFactory(invokeInfo, names, parameters, parent)
{}
+/*!
+ \reimp
+ */
QScxmlInvokableService *QScxmlDynamicScxmlServiceFactory::invoke(
QScxmlStateMachine *parentStateMachine)
{
bool ok = true;
- auto srcexpr = d->calculateSrcexpr(parentStateMachine, &ok);
+ auto srcexpr = calculateSrcexpr(parentStateMachine, invokeInfo().expr, &ok);
if (!ok)
return Q_NULLPTR;
- return invokeDynamic(parentStateMachine, srcexpr);
+ return invokeDynamicScxmlService(srcexpr, parentStateMachine, this);
+}
+
+QScxmlStaticScxmlServiceFactory::QScxmlStaticScxmlServiceFactory(
+ const QMetaObject *metaObject,
+ const QScxmlExecutableContent::InvokeInfo &invokeInfo,
+ const QVector<QScxmlExecutableContent::StringId> &nameList,
+ const QVector<QScxmlExecutableContent::ParameterInfo> &parameters,
+ QObject *parent)
+ : QScxmlInvokableServiceFactory(*(new QScxmlStaticScxmlServiceFactoryPrivate(
+ metaObject, invokeInfo, nameList, parameters)), parent)
+{
+}
+
+/*!
+ \reimp
+ */
+QScxmlInvokableService *QScxmlStaticScxmlServiceFactory::invoke(
+ QScxmlStateMachine *parentStateMachine)
+{
+ Q_D(const QScxmlStaticScxmlServiceFactory);
+ QScxmlStateMachine *instance = qobject_cast<QScxmlStateMachine *>(
+ d->metaObject->newInstance(Q_ARG(QObject *, this)));
+ return instance ? invokeStaticScxmlService(instance, parentStateMachine, this) : nullptr;
+}
+
+QScxmlInvokableServiceFactory::QScxmlInvokableServiceFactory(
+ QScxmlInvokableServiceFactoryPrivate &dd, QObject *parent)
+ : QObject(dd, parent)
+{}
+
+QScxmlScxmlService *invokeStaticScxmlService(QScxmlStateMachine *childStateMachine,
+ QScxmlStateMachine *parentStateMachine,
+ QScxmlInvokableServiceFactory *factory)
+{
+ QScxmlStateMachinePrivate::get(childStateMachine)->setIsInvoked(true);
+ return new QScxmlScxmlService(childStateMachine, parentStateMachine, factory);
}
QT_END_NAMESPACE
diff --git a/src/scxml/qscxmlinvokableservice.h b/src/scxml/qscxmlinvokableservice.h
index 36ebcd0..a3c09e8 100644
--- a/src/scxml/qscxmlinvokableservice.h
+++ b/src/scxml/qscxmlinvokableservice.h
@@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE
class QScxmlEvent;
class QScxmlStateMachine;
+class QScxmlInvokableServiceFactory;
class QScxmlInvokableServicePrivate;
class Q_SCXML_EXPORT QScxmlInvokableService : public QObject
{
@@ -59,101 +60,66 @@ class Q_SCXML_EXPORT QScxmlInvokableService : public QObject
public:
QScxmlInvokableService(QScxmlStateMachine *parentStateMachine,
- QObject *parent = nullptr);
+ QScxmlInvokableServiceFactory *parent);
QScxmlStateMachine *parentStateMachine() const;
- virtual bool start(const QScxmlExecutableContent::InvokeInfo &invokeInfo,
- const QVector<QScxmlExecutableContent::ParameterInfo> &parameters,
- const QVector<QScxmlExecutableContent::StringId> &names) = 0;
+ virtual bool start() = 0;
virtual QString id() const = 0;
virtual QString name() const = 0;
virtual void postEvent(QScxmlEvent *event) = 0;
-
- void finalize(QScxmlExecutableContent::ContainerId finalize);
-
-protected:
- QScxmlInvokableService(QScxmlInvokableServicePrivate &dd, QObject *parent = nullptr);
};
class QScxmlInvokableServiceFactoryPrivate;
-class Q_SCXML_EXPORT QScxmlInvokableServiceFactory
+class Q_SCXML_EXPORT QScxmlInvokableServiceFactory : public QObject
{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QScxmlInvokableServiceFactory)
+ Q_PROPERTY(QScxmlExecutableContent::InvokeInfo invokeInfo READ invokeInfo CONSTANT)
+ Q_PROPERTY(QVector<QScxmlExecutableContent::ParameterInfo> parameters READ parameters CONSTANT)
+ Q_PROPERTY(QVector<QScxmlExecutableContent::StringId> names READ names CONSTANT)
+
public:
QScxmlInvokableServiceFactory(
const QScxmlExecutableContent::InvokeInfo &invokeInfo,
const QVector<QScxmlExecutableContent::StringId> &names,
- const QVector<QScxmlExecutableContent::ParameterInfo> &parameters);
- virtual ~QScxmlInvokableServiceFactory();
+ const QVector<QScxmlExecutableContent::ParameterInfo> &parameters,
+ QObject *parent = nullptr);
virtual QScxmlInvokableService *invoke(QScxmlStateMachine *parentStateMachine) = 0;
- QScxmlExecutableContent::InvokeInfo invokeInfo() const;
- QVector<QScxmlExecutableContent::ParameterInfo> parameters() const;
- QVector<QScxmlExecutableContent::StringId> names() const;
+ const QScxmlExecutableContent::InvokeInfo &invokeInfo() const;
+ const QVector<QScxmlExecutableContent::ParameterInfo> &parameters() const;
+ const QVector<QScxmlExecutableContent::StringId> &names() const;
protected:
- QScxmlInvokableServiceFactoryPrivate *d;
+ QScxmlInvokableServiceFactory(QScxmlInvokableServiceFactoryPrivate &dd, QObject *parent);
};
-class QScxmlScxmlServicePrivate;
-class Q_SCXML_EXPORT QScxmlScxmlService: public QScxmlInvokableService
+class QScxmlStaticScxmlServiceFactoryPrivate;
+class Q_SCXML_EXPORT QScxmlStaticScxmlServiceFactory: public QScxmlInvokableServiceFactory
{
Q_OBJECT
- Q_DECLARE_PRIVATE(QScxmlScxmlService)
- Q_PROPERTY(QScxmlStateMachine *stateMachine READ stateMachine CONSTANT)
-public:
- QScxmlScxmlService(QScxmlStateMachine *stateMachine,
- QScxmlStateMachine *parentStateMachine,
- QObject *parent = nullptr);
-
- bool start(const QScxmlExecutableContent::InvokeInfo &invokeInfo,
- const QVector<QScxmlExecutableContent::ParameterInfo> &parameters,
- const QVector<QScxmlExecutableContent::StringId> &names) Q_DECL_OVERRIDE;
- QString id() const Q_DECL_OVERRIDE;
- QString name() const Q_DECL_OVERRIDE;
- void postEvent(QScxmlEvent *event) Q_DECL_OVERRIDE;
-
- QScxmlStateMachine *stateMachine() const;
-};
-
-class Q_SCXML_EXPORT QScxmlScxmlServiceFactory: public QScxmlInvokableServiceFactory
-{
-public:
- QScxmlScxmlServiceFactory(const QScxmlExecutableContent::InvokeInfo &invokeInfo,
- const QVector<QScxmlExecutableContent::StringId> &names,
- const QVector<QScxmlExecutableContent::ParameterInfo> &parameters);
-
-protected:
- QScxmlScxmlService *invokeDynamic(QScxmlStateMachine *parentStateMachine,
- const QString &sourceUrl);
- QScxmlScxmlService *invokeStatic(QScxmlStateMachine *childStateMachine,
- QScxmlStateMachine *parentStateMachine);
-};
-
-template<class T>
-class QScxmlStaticScxmlServiceFactory: public QScxmlScxmlServiceFactory
-{
+ Q_DECLARE_PRIVATE(QScxmlStaticScxmlServiceFactory)
public:
QScxmlStaticScxmlServiceFactory(
- const QScxmlExecutableContent::InvokeInfo &newInvokeInfo,
- const QVector<QScxmlExecutableContent::StringId> &newNameList,
- const QVector<QScxmlExecutableContent::ParameterInfo> &newParameters)
- : QScxmlScxmlServiceFactory(newInvokeInfo, newNameList, newParameters)
- {}
-
- QScxmlInvokableService *invoke(QScxmlStateMachine *parentStateMachine) Q_DECL_OVERRIDE
- {
- return invokeStatic(new T, parentStateMachine);
- }
+ const QMetaObject *metaObject,
+ const QScxmlExecutableContent::InvokeInfo &invokeInfo,
+ const QVector<QScxmlExecutableContent::StringId> &nameList,
+ const QVector<QScxmlExecutableContent::ParameterInfo> &parameters,
+ QObject *parent = nullptr);
+
+ QScxmlInvokableService *invoke(QScxmlStateMachine *parentStateMachine) Q_DECL_OVERRIDE;
};
-class Q_SCXML_EXPORT QScxmlDynamicScxmlServiceFactory: public QScxmlScxmlServiceFactory
+class Q_SCXML_EXPORT QScxmlDynamicScxmlServiceFactory: public QScxmlInvokableServiceFactory
{
+ Q_OBJECT
public:
QScxmlDynamicScxmlServiceFactory(
const QScxmlExecutableContent::InvokeInfo &invokeInfo,
const QVector<QScxmlExecutableContent::StringId> &names,
- const QVector<QScxmlExecutableContent::ParameterInfo> &parameters);
+ const QVector<QScxmlExecutableContent::ParameterInfo> &parameters,
+ QObject *parent = nullptr);
QScxmlInvokableService *invoke(QScxmlStateMachine *parentStateMachine) Q_DECL_OVERRIDE;
};
diff --git a/src/scxml/qscxmlinvokableservice_p.h b/src/scxml/qscxmlinvokableservice_p.h
index 52bd6d0..e2a9e7b 100644
--- a/src/scxml/qscxmlinvokableservice_p.h
+++ b/src/scxml/qscxmlinvokableservice_p.h
@@ -71,7 +71,7 @@ public:
QScxmlStateMachine *parentStateMachine;
};
-class QScxmlInvokableServiceFactoryPrivate
+class QScxmlInvokableServiceFactoryPrivate : public QObjectPrivate
{
public:
QScxmlInvokableServiceFactoryPrivate(
@@ -79,23 +79,50 @@ public:
const QVector<QScxmlExecutableContent::StringId> &names,
const QVector<QScxmlExecutableContent::ParameterInfo> &parameters);
- QString calculateSrcexpr(QScxmlStateMachine *parent, bool *ok) const;
-
QScxmlExecutableContent::InvokeInfo invokeInfo;
QVector<QScxmlExecutableContent::StringId> names;
QVector<QScxmlExecutableContent::ParameterInfo> parameters;
};
-class QScxmlScxmlServicePrivate : public QScxmlInvokableServicePrivate
+class Q_SCXML_EXPORT QScxmlScxmlService: public QScxmlInvokableService
{
+ Q_OBJECT
+ Q_DECLARE_PRIVATE(QScxmlInvokableService)
public:
- QScxmlScxmlServicePrivate(QScxmlStateMachine *stateMachine,
- QScxmlStateMachine *parentStateMachine);
- ~QScxmlScxmlServicePrivate();
+ QScxmlScxmlService(QScxmlStateMachine *stateMachine,
+ QScxmlStateMachine *parentStateMachine,
+ QScxmlInvokableServiceFactory *parent);
+ ~QScxmlScxmlService();
+
+ bool start() Q_DECL_OVERRIDE;
+ QString id() const Q_DECL_OVERRIDE;
+ QString name() const Q_DECL_OVERRIDE;
+ void postEvent(QScxmlEvent *event) Q_DECL_OVERRIDE;
QScxmlStateMachine *stateMachine;
};
+class QScxmlStaticScxmlServiceFactoryPrivate : public QScxmlInvokableServiceFactoryPrivate
+{
+public:
+ QScxmlStaticScxmlServiceFactoryPrivate(
+ const QMetaObject *metaObject,
+ const QScxmlExecutableContent::InvokeInfo &invokeInfo,
+ const QVector<QScxmlExecutableContent::StringId> &names,
+ const QVector<QScxmlExecutableContent::ParameterInfo> &parameters);
+
+ const QMetaObject *metaObject;
+};
+
+QScxmlScxmlService *invokeDynamicScxmlService(const QString &sourceUrl,
+ QScxmlStateMachine *parentStateMachine,
+ QScxmlInvokableServiceFactory *factory);
+QScxmlScxmlService *invokeStaticScxmlService(QScxmlStateMachine *childStateMachine,
+ QScxmlStateMachine *parentStateMachine,
+ QScxmlInvokableServiceFactory *factory);
+QString calculateSrcexpr(QScxmlStateMachine *parent, QScxmlExecutableContent::EvaluatorId srcexpr,
+ bool *ok);
+
QT_END_NAMESPACE
#endif // QSCXMLINVOKABLESERVICE_P_H
diff --git a/src/scxml/qscxmlnulldatamodel.cpp b/src/scxml/qscxmlnulldatamodel.cpp
index 08a9333..3054383 100644
--- a/src/scxml/qscxmlnulldatamodel.cpp
+++ b/src/scxml/qscxmlnulldatamodel.cpp
@@ -84,8 +84,7 @@ public:
ResolvedEvaluatorInfo prepare(QScxmlExecutableContent::EvaluatorId id)
{
- Q_Q(QScxmlNullDataModel);
- auto td = q->tableData();
+ auto td = m_stateMachine->tableData();
const QScxmlExecutableContent::EvaluatorInfo &info = td->evaluatorInfo(id);
QString expr = td->string(info.expr);
for (int i = 0; i < expr.size(); ) {
@@ -123,19 +122,22 @@ private:
* This class implements the null data model as described in the
* \l {SCXML Specification - B.1 The Null Data Model}. Using the value \c "null"
* for the \e datamodel attribute of the \c <scxml> element means that there is
- * no underlying data model.
+ * no underlying data model, but some executable content, like \c In(...) or
+ * \c <log> can still be used.
*
* \sa QScxmlStateMachine QScxmlDataModel
*/
/*!
- * Creates a new Qt SCXML data model, with the parent object \a parent.
+ * Creates a new Qt SCXML null data model, with the parent object \a parent.
*/
QScxmlNullDataModel::QScxmlNullDataModel(QObject *parent)
: QScxmlDataModel(*(new QScxmlNullDataModelPrivate), parent)
{}
-/*! \internal */
+/*!
+ Destroys the data model.
+ */
QScxmlNullDataModel::~QScxmlNullDataModel()
{
}
@@ -150,22 +152,43 @@ bool QScxmlNullDataModel::setup(const QVariantMap &initialDataValues)
return true;
}
+/*!
+ \reimp
+ Evaluates the executable content pointed to by \a id and records in \a ok
+ whether there was an error. Returns the result of the evaluation as a string.
+ The null data model can evaluate the \c <log> element, so this might result in
+ an actual value, rather than an error
+ */
QString QScxmlNullDataModel::evaluateToString(QScxmlExecutableContent::EvaluatorId id, bool *ok)
{
+ Q_D(QScxmlNullDataModel);
// We do implement this, because <log> is allowed in the Null data model,
// and <log> has an expr attribute that needs "evaluation" for it to generate the log message.
*ok = true;
- auto td = tableData();
+ auto td = d->m_stateMachine->tableData();
const QScxmlExecutableContent::EvaluatorInfo &info = td->evaluatorInfo(id);
return td->string(info.expr);
}
+/*!
+ \reimp
+ Evaluates the executable content pointed to by \a id and records in \a ok
+ whether there was an error. Returns the result of the evaluation as a boolean
+ value. The null data model can evaluate the instruction \c In(...), so this
+ might result in an actual value, rather than an error.
+ */
bool QScxmlNullDataModel::evaluateToBool(QScxmlExecutableContent::EvaluatorId id, bool *ok)
{
Q_D(QScxmlNullDataModel);
return d->evalBool(id, ok);
}
+/*!
+ \reimp
+ Evaluates the executable content pointed to by \a id and records in \a ok
+ whether there was an error. As this is the null data model, any evaluation will in
+ fact result in an error, with \a ok set to \c false. Returns an empty QVariant.
+ */
QVariant QScxmlNullDataModel::evaluateToVariant(QScxmlExecutableContent::EvaluatorId id, bool *ok)
{
Q_UNUSED(id);
@@ -176,6 +199,12 @@ QVariant QScxmlNullDataModel::evaluateToVariant(QScxmlExecutableContent::Evaluat
return QVariant();
}
+/*!
+ \reimp
+ Evaluates the executable content pointed to by \a id and records in \a ok
+ whether there was an error. As this is the null data model, any evaluation will in
+ fact result in an error, with \a ok set to \c false.
+ */
void QScxmlNullDataModel::evaluateToVoid(QScxmlExecutableContent::EvaluatorId id, bool *ok)
{
Q_UNUSED(id);
@@ -185,6 +214,11 @@ void QScxmlNullDataModel::evaluateToVoid(QScxmlExecutableContent::EvaluatorId id
QStringLiteral("Cannot evaluate expressions on a null data model"));
}
+/*!
+ \reimp
+ Throws an error and sets \a ok to \c false, because the null data model cannot evaluate
+ assignments.
+ */
void QScxmlNullDataModel::evaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok)
{
Q_UNUSED(id);
@@ -194,6 +228,11 @@ void QScxmlNullDataModel::evaluateAssignment(QScxmlExecutableContent::EvaluatorI
QStringLiteral("Cannot assign values on a null data model"));
}
+/*!
+ \reimp
+ Throws an error and sets \a ok to \c false, because the null data model cannot
+ initialize data.
+ */
void QScxmlNullDataModel::evaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok)
{
Q_UNUSED(id);
@@ -203,7 +242,13 @@ void QScxmlNullDataModel::evaluateInitialization(QScxmlExecutableContent::Evalua
QStringLiteral("Cannot initialize values on a null data model"));
}
-bool QScxmlNullDataModel::evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body)
+/*!
+ \reimp
+ Throws an error and sets \a ok to \c false, because the null data model cannot
+ evaluate \c <foreach> blocks.
+ */
+void QScxmlNullDataModel::evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok,
+ ForeachLoopBody *body)
{
Q_UNUSED(id);
Q_UNUSED(body);
@@ -211,11 +256,11 @@ bool QScxmlNullDataModel::evaluateForeach(QScxmlExecutableContent::EvaluatorId i
QScxmlStateMachinePrivate::get(stateMachine())->submitError(
QStringLiteral("error.execution"),
QStringLiteral("Cannot run foreach on a null data model"));
- return false;
}
/*!
* \reimp
+ * Does not actually set the \a event, because the null data model does not handle events.
*/
void QScxmlNullDataModel::setScxmlEvent(const QScxmlEvent &event)
{
diff --git a/src/scxml/qscxmlnulldatamodel.h b/src/scxml/qscxmlnulldatamodel.h
index e4f7942..830162f 100644
--- a/src/scxml/qscxmlnulldatamodel.h
+++ b/src/scxml/qscxmlnulldatamodel.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef NULLDATAMODEL_H
-#define NULLDATAMODEL_H
+#ifndef QSCXMLNULLDATAMODEL_H
+#define QSCXMLNULLDATAMODEL_H
#include <QtScxml/qscxmldatamodel.h>
@@ -55,15 +55,13 @@ public:
Q_INVOKABLE bool setup(const QVariantMap &initialDataValues) Q_DECL_OVERRIDE;
-#ifndef Q_QDOC
QString evaluateToString(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
bool evaluateToBool(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
QVariant evaluateToVariant(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
void evaluateToVoid(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
void evaluateAssignment(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
void evaluateInitialization(QScxmlExecutableContent::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE Q_DECL_FINAL;
- bool evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) Q_DECL_OVERRIDE Q_DECL_FINAL;
-#endif // Q_QDOC
+ void evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) Q_DECL_OVERRIDE Q_DECL_FINAL;
void setScxmlEvent(const QScxmlEvent &event) Q_DECL_OVERRIDE;
@@ -74,4 +72,4 @@ public:
QT_END_NAMESPACE
-#endif // NULLDATAMODEL_H
+#endif // QSCXMLNULLDATAMODEL_H
diff --git a/src/scxml/qscxmlstatemachine.cpp b/src/scxml/qscxmlstatemachine.cpp
index ef5a312..6bc7ab5 100644
--- a/src/scxml/qscxmlstatemachine.cpp
+++ b/src/scxml/qscxmlstatemachine.cpp
@@ -449,7 +449,7 @@ void QScxmlStateMachinePrivate::addService(int invokingState)
continue; // service failed to start
const QString serviceName = service->name();
m_invokedServices[size_t(id)] = { invokingState, service, serviceName };
- service->start(factory->invokeInfo(), factory->parameters(), factory->names());
+ service->start();
}
emitInvokedServicesChanged();
}
@@ -533,7 +533,16 @@ void QScxmlStateMachinePrivate::postEvent(QScxmlEvent *event)
auto factory = serviceFactory(id);
if (event->invokeId() == service->id()) {
setEvent(event);
- service->finalize(factory->invokeInfo().finalize);
+
+ const QScxmlExecutableContent::ContainerId finalize
+ = factory->invokeInfo().finalize;
+ if (finalize != QScxmlExecutableContent::NoContainer) {
+ auto psm = service->parentStateMachine();
+ qCDebug(qscxmlLog) << psm << "running finalize on event";
+ auto smp = QScxmlStateMachinePrivate::get(psm);
+ smp->m_executionEngine->execute(finalize);
+ }
+
resetEvent();
}
if (factory->invokeInfo().autoforward) {
@@ -580,36 +589,47 @@ void QScxmlStateMachinePrivate::submitDelayedEvent(QScxmlEvent *event)
}
/*!
- * \internal
- * \brief Submits an error event to the external event queue of this state machine.
+ * Submits an error event to the external event queue of this state machine.
*
- * \param type The error message type, e.g. "error.execution". The type has to start with "error.".
- * \param msg A string describing the nature of the error. This is passed to the event as the
- * errorMessage
- * \param sendid The sendid of the message causing the error, if it has one.
+ * The type of the error is specified by \a type. The value of type has to begin
+ * with the string \e error. For example \c {error.execution}. The message,
+ * \a message, decribes the error and is passed to the event as the
+ * \c errorMessage property. The \a sendId of the message causing the error is specified, if it has
+ * one.
*/
-void QScxmlStateMachinePrivate::submitError(const QString &type, const QString &msg, const QString &sendid)
+void QScxmlStateMachinePrivate::submitError(const QString &type, const QString &message,
+ const QString &sendId)
{
Q_Q(QScxmlStateMachine);
- qCDebug(qscxmlLog) << q << "had error" << type << ":" << msg;
+ qCDebug(qscxmlLog) << q << "had error" << type << ":" << message;
if (!type.startsWith(QStringLiteral("error.")))
qCWarning(qscxmlLog) << q << "Message type of error message does not start with 'error.'!";
- q->submitEvent(QScxmlEventBuilder::errorEvent(q, type, msg, sendid));
+ q->submitEvent(QScxmlEventBuilder::errorEvent(q, type, message, sendId));
}
void QScxmlStateMachinePrivate::start()
{
+ Q_Q(QScxmlStateMachine);
+
if (m_stateTable->binding == StateTable::LateBinding)
m_isFirstStateEntry.resize(m_stateTable->stateCount, true);
+ bool running = isRunnable() && !isPaused();
m_runningState = Starting;
Q_ASSERT(m_stateTable->initialTransition != StateTable::InvalidIndex);
+
+ if (!running)
+ emit q->runningChanged(true);
}
void QScxmlStateMachinePrivate::pause()
{
- if (isRunnable() && !isPaused())
+ Q_Q(QScxmlStateMachine);
+
+ if (isRunnable() && !isPaused()) {
m_runningState = Paused;
+ emit q->runningChanged(false);
+ }
}
void QScxmlStateMachinePrivate::processEvents()
@@ -1096,7 +1116,10 @@ void QScxmlStateMachinePrivate::enterStates(const OrderedSet &enabledTransitions
m_executionEngine->execute(dhc);
if (state.type == StateTable::State::Final) {
if (state.parentIsScxmlElement()) {
+ bool running = isRunnable() && !isPaused();
m_runningState = Finished;
+ if (running)
+ emit q->runningChanged(false);
} else {
const auto &parent = m_stateTable->state(state.parent);
m_executionEngine->execute(state.doneData, m_tableData->string(parent.name));
@@ -1532,6 +1555,16 @@ QScxmlStateMachine::QScxmlStateMachine(QScxmlStateMachinePrivate &dd, QObject *p
\brief The loader that is currently used to resolve and load URIs for the state machine.
*/
+/*!
+ \property QScxmlStateMachine::tableData
+
+ \brief The table data that is used when generating C++ from an SCXML file.
+
+ The class implementing
+ the state machine will use this property to assign the generated table
+ data. The state machine does not assume ownership of the table data.
+ */
+
QString QScxmlStateMachine::sessionId() const
{
Q_D(const QScxmlStateMachine);
@@ -1602,13 +1635,6 @@ QScxmlCompiler::Loader *QScxmlStateMachine::loader() const
return d->m_loader;
}
-/*!
- * \internal
- *
- * This is used internally in order to execute the executable content.
- *
- * \return the data tables used by the state machine.
- */
QScxmlTableData *QScxmlStateMachine::tableData() const
{
Q_D(const QScxmlStateMachine);
@@ -1616,36 +1642,36 @@ QScxmlTableData *QScxmlStateMachine::tableData() const
return d->m_tableData;
}
-/*!
- * \internal
- * This is used when generating C++ from an SCXML file. The class implementing the
- * state machine will use this method to pass in the table data (which is also generated).
- *
- * \return the data tables used by the state machine.
- */
void QScxmlStateMachine::setTableData(QScxmlTableData *tableData)
{
Q_D(QScxmlStateMachine);
- Q_ASSERT(tableData);
+
+ if (d->m_tableData == tableData)
+ return;
d->m_tableData = tableData;
- d->m_stateTable = reinterpret_cast<const QScxmlExecutableContent::StateTable *>(
- tableData->stateMachineTable());
- if (objectName().isEmpty()) {
- setObjectName(tableData->name());
- }
- if (d->m_stateTable->maxServiceId != QScxmlExecutableContent::StateTable::InvalidIndex) {
- const size_t serviceCount = size_t(d->m_stateTable->maxServiceId + 1);
- d->m_invokedServices.resize(serviceCount, { -1, nullptr, QString() });
- d->m_cachedFactories.resize(serviceCount, nullptr);
+ if (tableData) {
+ d->m_stateTable = reinterpret_cast<const QScxmlExecutableContent::StateTable *>(
+ tableData->stateMachineTable());
+ if (objectName().isEmpty()) {
+ setObjectName(tableData->name());
+ }
+ if (d->m_stateTable->maxServiceId != QScxmlExecutableContent::StateTable::InvalidIndex) {
+ const size_t serviceCount = size_t(d->m_stateTable->maxServiceId + 1);
+ d->m_invokedServices.resize(serviceCount, { -1, nullptr, QString() });
+ d->m_cachedFactories.resize(serviceCount, nullptr);
+ }
+
+ if (d->m_stateTable->version != Q_QSCXMLC_OUTPUT_REVISION) {
+ qFatal("Cannot mix incompatible state table (version 0x%x) with this library "
+ "(version 0x%x)", d->m_stateTable->version, Q_QSCXMLC_OUTPUT_REVISION);
+ }
+ Q_ASSERT(tableData->stateMachineTable()[d->m_stateTable->arrayOffset +
+ d->m_stateTable->arraySize]
+ == QScxmlExecutableContent::StateTable::terminator);
}
- if (d->m_stateTable->version != Q_QSCXMLC_OUTPUT_REVISION)
- qFatal("Cannot mix incompatible state table (version 0x%x) with this library (version 0x%x)",
- d->m_stateTable->version, Q_QSCXMLC_OUTPUT_REVISION);
- Q_ASSERT(tableData->stateMachineTable()[d->m_stateTable->arrayOffset +
- d->m_stateTable->arraySize]
- == QScxmlExecutableContent::StateTable::terminator);
+ emit tableDataChanged(tableData);
}
/*!
@@ -2057,6 +2083,13 @@ void QScxmlStateMachine::stop()
d->pause();
}
+/*!
+ Returns \c true if the state with the ID \a stateIndex is active.
+
+ This method is part of the interface to the compiled representation of SCXML
+ state machines. It should only be used internally and by state machines
+ compiled from SCXML documents.
+ */
bool QScxmlStateMachine::isActive(int stateIndex) const
{
Q_D(const QScxmlStateMachine);
diff --git a/src/scxml/qscxmlstatemachine.h b/src/scxml/qscxmlstatemachine.h
index 2dea079..d4435f7 100644
--- a/src/scxml/qscxmlstatemachine.h
+++ b/src/scxml/qscxmlstatemachine.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef SCXMLSTATEMACHINE_H
-#define SCXMLSTATEMACHINE_H
+#ifndef QSCXMLSTATEMACHINE_H
+#define QSCXMLSTATEMACHINE_H
#include <QtScxml/qscxmldatamodel.h>
#include <QtScxml/qscxmlexecutablecontent.h>
@@ -75,12 +75,11 @@ class Q_SCXML_EXPORT QScxmlStateMachine: public QObject
Q_PROPERTY(bool invoked READ isInvoked CONSTANT)
Q_PROPERTY(QVector<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)
protected:
-#ifndef Q_QDOC
explicit QScxmlStateMachine(const QMetaObject *metaObject, QObject *parent = nullptr);
QScxmlStateMachine(QScxmlStateMachinePrivate &dd, QObject *parent = nullptr);
-#endif // Q_QDOC
public:
static QScxmlStateMachine *fromFile(const QString &fileName);
@@ -314,6 +313,9 @@ public:
QVector<QScxmlInvokableService *> invokedServices() const;
+ QScxmlTableData *tableData() const;
+ void setTableData(QScxmlTableData *tableData);
+
Q_SIGNALS:
void runningChanged(bool running);
void invokedServicesChanged(const QVector<QScxmlInvokableService *> &invokedServices);
@@ -324,6 +326,7 @@ Q_SIGNALS:
void initialValuesChanged(const QVariantMap &initialValues);
void initializedChanged(bool initialized);
void loaderChanged(QScxmlCompiler::Loader *loader);
+ void tableDataChanged(QScxmlTableData *tableData);
public Q_SLOTS:
void start();
@@ -336,12 +339,8 @@ protected: // methods for friends:
friend class QScxmlInvokableServicePrivate;
friend class QScxmlExecutionEngine;
-#ifndef Q_QDOC
// The methods below are used by the compiled state machines.
bool isActive(int stateIndex) const;
- QScxmlTableData *tableData() const;
- void setTableData(QScxmlTableData *tableData);
-#endif // Q_QDOC
private:
QMetaObject::Connection connectToStateImpl(const QString &scxmlStateName,
@@ -356,4 +355,4 @@ private:
QT_END_NAMESPACE
-#endif // SCXMLSTATEMACHINE_H
+#endif // QSCXMLSTATEMACHINE_H
diff --git a/src/scxml/qscxmlstatemachine_p.h b/src/scxml/qscxmlstatemachine_p.h
index 69f3be4..bfa7bc1 100644
--- a/src/scxml/qscxmlstatemachine_p.h
+++ b/src/scxml/qscxmlstatemachine_p.h
@@ -37,8 +37,8 @@
**
****************************************************************************/
-#ifndef SCXMLSTATEMACHINE_P_H
-#define SCXMLSTATEMACHINE_P_H
+#ifndef QSCXMLSTATEMACHINE_P_H
+#define QSCXMLSTATEMACHINE_P_H
//
// W A R N I N G
@@ -383,5 +383,5 @@ private:
QT_END_NAMESPACE
-#endif // SCXMLSTATEMACHINE_P_H
+#endif // QSCXMLSTATEMACHINE_P_H
diff --git a/src/scxml/qscxmltabledata.cpp b/src/scxml/qscxmltabledata.cpp
index 2457840..f9665d3 100644
--- a/src/scxml/qscxmltabledata.cpp
+++ b/src/scxml/qscxmltabledata.cpp
@@ -43,6 +43,75 @@
QT_USE_NAMESPACE
+/*!
+ \class QScxmlTableData
+ \since 5.8
+ \inmodule QtScxml
+ \brief The QScxmlTableData class is used by compiled state machines.
+
+ QScxmlTableData is the interface to the compiled representation of SCXML
+ state machines. It should only be used internally and by state machines
+ compiled from SCXML documents.
+ */
+
+/*!
+ \fn QScxmlTableData::string(QScxmlExecutableContent::StringId id) const
+ Returns a QString for the given \a id.
+ */
+
+/*!
+ \fn QScxmlTableData::instructions() const
+ Returns a pointer to the instructions of executable content contained in
+ the state machine.
+ */
+
+/*!
+ \fn QScxmlTableData::evaluatorInfo(QScxmlExecutableContent::EvaluatorId evaluatorId) const
+ Returns the QScxmlExecutableContent::EvaluatorInfo object for the given \a evaluatorId.
+ */
+
+/*!
+ \fn QScxmlTableData::assignmentInfo(QScxmlExecutableContent::EvaluatorId assignmentId) const
+ Returns the QScxmlExecutableContent::AssignmentInfo object for the given \a assignmentId.
+ */
+
+/*!
+ \fn QScxmlTableData::foreachInfo(QScxmlExecutableContent::EvaluatorId foreachId) const
+ Returns the QScxmlExecutableContent::ForeachInfo object for the given \a foreachId.
+ */
+
+/*!
+ \fn QScxmlTableData::dataNames(int *count) const
+ Retrieves the string IDs for the names of data items in the data model. The
+ number of strings is saved into \a count and a pointer to an array of
+ string IDs is returned.
+
+ Returns a pointer to an array of string IDs.
+ */
+
+/*!
+ \fn QScxmlTableData::initialSetup() const
+ Initializes the table data. Returns the ID of the container with
+ instructions to be executed when initializing the state machine.
+ */
+
+/*!
+ \fn QScxmlTableData::name() const
+ Returns the name of the state machine.
+ */
+
+/*!
+ \fn QScxmlTableData::stateMachineTable() const
+ Returns a pointer to the complete state table, expressed as an opaque
+ sequence of integers.
+ */
+
+/*!
+ \fn QScxmlTableData::serviceFactory(int id) const
+ Returns the service factory that creates invokable services for the state
+ with the ID \a id.
+ */
+
using namespace QScxmlInternal;
namespace {
@@ -68,7 +137,7 @@ public:
{
m_activeSequences.reserve(4);
- tableData.theInitialSetup = QScxmlExecutableContent::NoInstruction;
+ tableData.theInitialSetup = QScxmlExecutableContent::NoContainer;
}
void buildTableData(DocumentModel::ScxmlDocument *doc)
@@ -264,7 +333,7 @@ protected: // visitor
params.append(p);
}
QScxmlExecutableContent::ContainerId finalize =
- QScxmlExecutableContent::NoInstruction;
+ QScxmlExecutableContent::NoContainer;
if (!invoke->finalize.isEmpty()) {
finalize = startNewSequence();
visit(&invoke->finalize);
@@ -528,7 +597,7 @@ protected:
ContainerId generate(const DocumentModel::InstructionSequences &inSequences)
{
if (inSequences.isEmpty())
- return NoInstruction;
+ return NoContainer;
auto id = m_instructions.newContainerId();
auto outSequences = m_instructions.add<InstructionSequences>();
@@ -898,6 +967,10 @@ private:
} // anonymous namespace
+/*!
+ \fn QScxmlTableData::~QScxmlTableData()
+ Destroys the SXCML table data.
+ */
QScxmlTableData::~QScxmlTableData()
{}
diff --git a/src/scxml/qscxmltabledata_p.h b/src/scxml/qscxmltabledata_p.h
index 2c825db..767b88a 100644
--- a/src/scxml/qscxmltabledata_p.h
+++ b/src/scxml/qscxmltabledata_p.h
@@ -117,7 +117,7 @@ public:
QVector<QScxmlExecutableContent::AssignmentInfo> theAssignments;
QVector<QScxmlExecutableContent::ForeachInfo> theForeaches;
QVector<QScxmlExecutableContent::StringId> theDataNameIds;
- QScxmlExecutableContent::EvaluatorId theInitialSetup;
+ QScxmlExecutableContent::ContainerId theInitialSetup;
int theName;
};
} // QScxmlInternal namespace
diff --git a/sync.profile b/sync.profile
index acbc753..1a8e936 100644
--- a/sync.profile
+++ b/sync.profile
@@ -7,15 +7,3 @@
);
%deprecatedheaders = (
);
-# Module dependencies.
-# Every module that is required to build this module should have one entry.
-# Each of the module version specifiers can take one of the following values:
-# - A specific Git revision.
-# - any git symbolic ref resolvable from the module's repository (e.g. "refs/heads/master" to track master branch)
-# - an empty string to use the same branch under test (dependencies will become "refs/heads/master" if we are in the master branch)
-#
-%dependencies = (
- "qtbase" => "",
- "qtdeclarative" => "",
- "qtxmlpatterns" => "",
-);
diff --git a/tests/auto/statemachine/tst_statemachine.cpp b/tests/auto/statemachine/tst_statemachine.cpp
index f09ad42..99d6661 100644
--- a/tests/auto/statemachine/tst_statemachine.cpp
+++ b/tests/auto/statemachine/tst_statemachine.cpp
@@ -51,6 +51,7 @@ private Q_SLOTS:
void eventOccurred();
void doneDotStateEvent();
+ void running();
};
void tst_StateMachine::stateNames_data()
@@ -365,6 +366,26 @@ void tst_StateMachine::doneDotStateEvent()
QVERIFY(stateMachine->activeStateNames(true).contains(QLatin1String("success")));
}
+void tst_StateMachine::running()
+{
+ QScopedPointer<QScxmlStateMachine> stateMachine(
+ QScxmlStateMachine::fromFile(QString(":/tst_statemachine/statenames.scxml")));
+ QVERIFY(!stateMachine.isNull());
+
+ QSignalSpy runningChangedSpy(stateMachine.data(), SIGNAL(runningChanged(bool)));
+
+ QCOMPARE(stateMachine->isRunning(), false);
+
+ stateMachine->start();
+
+ QCOMPARE(runningChangedSpy.count(), 1);
+ QCOMPARE(stateMachine->isRunning(), true);
+
+ stateMachine->stop();
+
+ QCOMPARE(runningChangedSpy.count(), 2);
+ QCOMPARE(stateMachine->isRunning(), false);
+}
QTEST_MAIN(tst_StateMachine)
diff --git a/tools/qscxmlc/decl.t b/tools/qscxmlc/decl.t
index 482c123..baf1600 100644
--- a/tools/qscxmlc/decl.t
+++ b/tools/qscxmlc/decl.t
@@ -5,7 +5,7 @@ class ${classname}: public QScxmlStateMachine
${properties}
public:
- ${classname}(QObject *parent = 0);
+ Q_INVOKABLE ${classname}(QObject *parent = 0);
~${classname}();
${accessors}
diff --git a/tools/qscxmlc/scxmlcppdumper.cpp b/tools/qscxmlc/scxmlcppdumper.cpp
index d99b3b0..40ae1dd 100644
--- a/tools/qscxmlc/scxmlcppdumper.cpp
+++ b/tools/qscxmlc/scxmlcppdumper.cpp
@@ -374,8 +374,8 @@ int createFactoryId(QStringList &factories, const QString &className,
const int idx = factories.size();
QString line = QStringLiteral("case %1: return new ").arg(QString::number(idx));
- if (invokeInfo.expr == QScxmlExecutableContent::NoInstruction) {
- line += QStringLiteral("QScxmlStaticScxmlServiceFactory< %1::%2 >(")
+ if (invokeInfo.expr == QScxmlExecutableContent::NoEvaluator) {
+ line += QStringLiteral("QScxmlStaticScxmlServiceFactory(&%1::%2::staticMetaObject,")
.arg(namespacePrefix, className);
} else {
line += QStringLiteral("QScxmlDynamicScxmlServiceFactory(");
@@ -445,7 +445,7 @@ void CppDumper::dump(TranslationUnit *unit)
const QVector<QScxmlExecutableContent::ParameterInfo> &parameters,
const QSharedPointer<DocumentModel::ScxmlDocument> &content) -> int {
QString className;
- if (invokeInfo.expr == QScxmlExecutableContent::NoInstruction) {
+ if (invokeInfo.expr == QScxmlExecutableContent::NoEvaluator) {
className = mangleIdentifier(classnameForDocument.value(content.data()));
}
return createFactoryId(factories[i], className, namespacePrefix,
@@ -755,6 +755,20 @@ QString CppDumper::generateMetaObject(const QString &className,
classDef.qualified = classDef.classname;
classDef.superclassList << qMakePair(QByteArray("QScxmlStateMachine"), FunctionDef::Public);
classDef.hasQObject = true;
+ FunctionDef constructor;
+ constructor.name = className.toUtf8();
+ constructor.access = FunctionDef::Public;
+ constructor.isInvokable = true;
+ constructor.isConstructor = true;
+
+ ArgumentDef arg;
+ arg.type.name = "QObject *";
+ arg.type.rawName = arg.type.name;
+ arg.normalizedType = arg.type.name;
+ arg.name = "parent";
+ arg.typeNameForCast = arg.type.name + "*";
+ constructor.arguments.append(arg);
+ classDef.constructorList.append(constructor);
// stateNames:
int stateIdx = 0;
diff --git a/tools/qscxmlc/scxmlcppdumper.h b/tools/qscxmlc/scxmlcppdumper.h
index 9c8cfe8..a987f80 100644
--- a/tools/qscxmlc/scxmlcppdumper.h
+++ b/tools/qscxmlc/scxmlcppdumper.h
@@ -26,8 +26,8 @@
**
****************************************************************************/
-#ifndef CPPDUMPER_H
-#define CPPDUMPER_H
+#ifndef SCXMLCPPDUMPER_H
+#define SCXMLCPPDUMPER_H
#include "qscxmlglobals.h"
@@ -99,4 +99,4 @@ private:
QT_END_NAMESPACE
-#endif // CPPDUMPER_H
+#endif // SCXMLCPPDUMPER_H
diff --git a/tools/tools.pro b/tools/tools.pro
index f96987d..1854cfc 100644
--- a/tools/tools.pro
+++ b/tools/tools.pro
@@ -1,4 +1,2 @@
TEMPLATE = subdirs
SUBDIRS = qscxmlc
-
-qscxmlc.CONFIG = host_build