summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/scxml/qscxmlcompiler.cpp22
-rw-r--r--src/scxml/qscxmlcppdatamodel.cpp14
-rw-r--r--src/scxml/qscxmlcppdatamodel.h3
-rw-r--r--src/scxml/qscxmldatamodel.cpp5
-rw-r--r--src/scxml/qscxmldatamodel.h5
-rw-r--r--src/scxml/qscxmlecmascriptdatamodel.cpp18
-rw-r--r--src/scxml/qscxmlecmascriptdatamodel.h2
-rw-r--r--src/scxml/qscxmlexecutablecontent.cpp8
-rw-r--r--src/scxml/qscxmlinvokableservice.cpp168
-rw-r--r--src/scxml/qscxmlinvokableservice.h94
-rw-r--r--src/scxml/qscxmlinvokableservice_p.h41
-rw-r--r--src/scxml/qscxmlnulldatamodel.cpp3
-rw-r--r--src/scxml/qscxmlnulldatamodel.h2
-rw-r--r--src/scxml/qscxmlstatemachine.cpp13
-rw-r--r--tools/qscxmlc/decl.t2
-rw-r--r--tools/qscxmlc/scxmlcppdumper.cpp16
16 files changed, 212 insertions, 204 deletions
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/qscxmlcppdatamodel.cpp b/src/scxml/qscxmlcppdatamodel.cpp
index bc09d65..69f0fbd 100644
--- a/src/scxml/qscxmlcppdatamodel.cpp
+++ b/src/scxml/qscxmlcppdatamodel.cpp
@@ -134,11 +134,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
@@ -156,24 +151,23 @@ bool QScxmlCppDataModel::setup(const QVariantMap &initialDataValues)
void QScxmlCppDataModel::evaluateAssignment(EvaluatorId id, bool *ok)
{
Q_UNUSED(id);
- Q_UNUSED(ok);
+ *ok = false;
Q_UNREACHABLE();
}
void QScxmlCppDataModel::evaluateInitialization(EvaluatorId id, bool *ok)
{
Q_UNUSED(id);
- Q_UNUSED(ok);
+ *ok = false;
Q_UNREACHABLE();
}
-bool QScxmlCppDataModel::evaluateForeach(EvaluatorId id, bool *ok, ForeachLoopBody *body)
+void QScxmlCppDataModel::evaluateForeach(EvaluatorId id, bool *ok, ForeachLoopBody *body)
{
Q_UNUSED(id);
- Q_UNUSED(ok);
Q_UNUSED(body);
+ *ok = false;
Q_UNREACHABLE();
- return false;
}
/*!
diff --git a/src/scxml/qscxmlcppdatamodel.h b/src/scxml/qscxmlcppdatamodel.h
index fb59336..04607f2 100644
--- a/src/scxml/qscxmlcppdatamodel.h
+++ b/src/scxml/qscxmlcppdatamodel.h
@@ -59,14 +59,13 @@ 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;
+ void evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) Q_DECL_OVERRIDE Q_DECL_FINAL;
#endif // Q_QDOC
void setScxmlEvent(const QScxmlEvent &scxmlEvent) Q_DECL_OVERRIDE Q_DECL_FINAL;
diff --git a/src/scxml/qscxmldatamodel.cpp b/src/scxml/qscxmldatamodel.cpp
index 9762e92..6e6d62b 100644
--- a/src/scxml/qscxmldatamodel.cpp
+++ b/src/scxml/qscxmldatamodel.cpp
@@ -96,11 +96,6 @@ QScxmlDataModel::QScxmlDataModel(QScxmlDataModelPrivate &dd, QObject *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
diff --git a/src/scxml/qscxmldatamodel.h b/src/scxml/qscxmldatamodel.h
index 845d8bf..e1a575a 100644
--- a/src/scxml/qscxmldatamodel.h
+++ b/src/scxml/qscxmldatamodel.h
@@ -64,12 +64,11 @@ 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;
@@ -83,7 +82,7 @@ public:
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;
+ virtual void evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) = 0;
#endif // Q_QDOC
virtual void setScxmlEvent(const QScxmlEvent &event) = 0;
diff --git a/src/scxml/qscxmlecmascriptdatamodel.cpp b/src/scxml/qscxmlecmascriptdatamodel.cpp
index 32c49f0..4b0329e 100644
--- a/src/scxml/qscxmlecmascriptdatamodel.cpp
+++ b/src/scxml/qscxmlecmascriptdatamodel.cpp
@@ -469,7 +469,7 @@ void QScxmlEcmaScriptDataModel::evaluateInitialization(EvaluatorId id, bool *ok)
evaluateAssignment(id, ok);
}
-bool QScxmlEcmaScriptDataModel::evaluateForeach(EvaluatorId id, bool *ok, ForeachLoopBody *body)
+void QScxmlEcmaScriptDataModel::evaluateForeach(EvaluatorId id, bool *ok, ForeachLoopBody *body)
{
Q_D(QScxmlEcmaScriptDataModel);
Q_ASSERT(ok);
@@ -480,7 +480,7 @@ bool QScxmlEcmaScriptDataModel::evaluateForeach(EvaluatorId id, bool *ok, Foreac
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 +490,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 +502,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..808830a 100644
--- a/src/scxml/qscxmlecmascriptdatamodel.h
+++ b/src/scxml/qscxmlecmascriptdatamodel.h
@@ -63,7 +63,7 @@ public:
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;
+ void evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) Q_DECL_OVERRIDE Q_DECL_FINAL;
#endif // Q_QDOC
void setScxmlEvent(const QScxmlEvent &event) Q_DECL_OVERRIDE;
diff --git a/src/scxml/qscxmlexecutablecontent.cpp b/src/scxml/qscxmlexecutablecontent.cpp
index 5df8b1f..9fbcd15 100644
--- a/src/scxml/qscxmlexecutablecontent.cpp
+++ b/src/scxml/qscxmlexecutablecontent.cpp
@@ -216,11 +216,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 +227,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/qscxmlinvokableservice.cpp b/src/scxml/qscxmlinvokableservice.cpp
index 9af6be7..9dfda21 100644
--- a/src/scxml/qscxmlinvokableservice.cpp
+++ b/src/scxml/qscxmlinvokableservice.cpp
@@ -59,9 +59,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 +80,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 +211,114 @@ QVariantMap QScxmlInvokableServicePrivate::calculateData(
return result;
}
-QScxmlScxmlServicePrivate::QScxmlScxmlServicePrivate(QScxmlStateMachine *stateMachine,
- QScxmlStateMachine *parentStateMachine) :
- QScxmlInvokableServicePrivate(parentStateMachine), stateMachine(stateMachine)
-{}
-
-QScxmlScxmlServicePrivate::~QScxmlScxmlServicePrivate()
+QScxmlScxmlService::~QScxmlScxmlService()
{
delete stateMachine;
}
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)
+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;
}
QString QScxmlScxmlService::id() const
{
- Q_D(const QScxmlScxmlService);
- return d->stateMachine->sessionId();
+ return stateMachine->sessionId();
}
QString QScxmlScxmlService::name() const
{
- Q_D(const QScxmlScxmlService);
- return d->stateMachine->name();
+ return stateMachine->name();
}
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);
}
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)
{}
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)
+{
+}
+
+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 6efc07d..63b9ec3 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..35f1b91 100644
--- a/src/scxml/qscxmlnulldatamodel.cpp
+++ b/src/scxml/qscxmlnulldatamodel.cpp
@@ -203,7 +203,7 @@ void QScxmlNullDataModel::evaluateInitialization(QScxmlExecutableContent::Evalua
QStringLiteral("Cannot initialize values on a null data model"));
}
-bool QScxmlNullDataModel::evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body)
+void QScxmlNullDataModel::evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body)
{
Q_UNUSED(id);
Q_UNUSED(body);
@@ -211,7 +211,6 @@ bool QScxmlNullDataModel::evaluateForeach(QScxmlExecutableContent::EvaluatorId i
QScxmlStateMachinePrivate::get(stateMachine())->submitError(
QStringLiteral("error.execution"),
QStringLiteral("Cannot run foreach on a null data model"));
- return false;
}
/*!
diff --git a/src/scxml/qscxmlnulldatamodel.h b/src/scxml/qscxmlnulldatamodel.h
index e4f7942..f5aeb26 100644
--- a/src/scxml/qscxmlnulldatamodel.h
+++ b/src/scxml/qscxmlnulldatamodel.h
@@ -62,7 +62,7 @@ public:
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;
+ void evaluateForeach(QScxmlExecutableContent::EvaluatorId id, bool *ok, ForeachLoopBody *body) Q_DECL_OVERRIDE Q_DECL_FINAL;
#endif // Q_QDOC
void setScxmlEvent(const QScxmlEvent &event) Q_DECL_OVERRIDE;
diff --git a/src/scxml/qscxmlstatemachine.cpp b/src/scxml/qscxmlstatemachine.cpp
index ef5a312..1397b71 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) {
diff --git a/tools/qscxmlc/decl.t b/tools/qscxmlc/decl.t
index 9482885..648476d 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}();
private:
diff --git a/tools/qscxmlc/scxmlcppdumper.cpp b/tools/qscxmlc/scxmlcppdumper.cpp
index b539e0d..f5e9b2e 100644
--- a/tools/qscxmlc/scxmlcppdumper.cpp
+++ b/tools/qscxmlc/scxmlcppdumper.cpp
@@ -375,7 +375,7 @@ int createFactoryId(QStringList &factories, const QString &className,
QString line = QStringLiteral("case %1: return new ").arg(QString::number(idx));
if (invokeInfo.expr == QScxmlExecutableContent::NoInstruction) {
- line += QStringLiteral("QScxmlStaticScxmlServiceFactory< %1::%2 >(")
+ line += QStringLiteral("QScxmlStaticScxmlServiceFactory(&%1::%2::staticMetaObject,")
.arg(namespacePrefix, className);
} else {
line += QStringLiteral("QScxmlDynamicScxmlServiceFactory(");
@@ -714,6 +714,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;