summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/examples.pro2
-rw-r--r--examples/mediaplayer-qml-cppdatamodel/mediaplayer-cppdatamodel.scxml73
-rw-r--r--examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.cpp63
-rw-r--r--examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.pro18
-rw-r--r--examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.qml43
-rw-r--r--examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.qrc6
-rw-r--r--examples/mediaplayer-qml-cppdatamodel/thedatamodel.cpp57
-rw-r--r--examples/mediaplayer-qml-cppdatamodel/thedatamodel.h60
-rw-r--r--src/scxml/cppdatamodel.cpp96
-rw-r--r--src/scxml/cppdatamodel.h66
-rw-r--r--src/scxml/cppdatamodel_p.h39
-rw-r--r--src/scxml/executablecontent.cpp56
-rw-r--r--src/scxml/executablecontent_p.h30
-rw-r--r--src/scxml/scxml.pro7
-rw-r--r--src/scxml/scxmlparser.cpp17
-rw-r--r--src/scxml/scxmlparser_p.h5
-rw-r--r--tools/qscxmlc/scxmlcppdumper.cpp283
17 files changed, 818 insertions, 103 deletions
diff --git a/examples/examples.pro b/examples/examples.pro
index 7c27353..99ac34d 100644
--- a/examples/examples.pro
+++ b/examples/examples.pro
@@ -12,4 +12,6 @@ qtHaveModule(qml) {
SUBDIRS += trafficlight-qml-dynamic
SUBDIRS += mediaplayer-qml-static
SUBDIRS += mediaplayer-qml-dynamic
+
+ SUBDIRS += mediaplayer-qml-cppdatamodel
}
diff --git a/examples/mediaplayer-qml-cppdatamodel/mediaplayer-cppdatamodel.scxml b/examples/mediaplayer-qml-cppdatamodel/mediaplayer-cppdatamodel.scxml
new file mode 100644
index 0000000..789f739
--- /dev/null
+++ b/examples/mediaplayer-qml-cppdatamodel/mediaplayer-cppdatamodel.scxml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+-->
+<scxml
+ xmlns="http://www.w3.org/2005/07/scxml"
+ version="1.0"
+ name="MediaPlayerStateMachine"
+ initial="stopped"
+ datamodel="cplusplus:TheDataModel:thedatamodel.h"
+>
+ <state id="stopped">
+ <transition event="tap" cond="isValidMedia()" target="playing"/>
+ </state>
+
+ <state id="playing">
+ <onentry>
+ <script>
+ media = eventData().value(QStringLiteral(&quot;media&quot;)).toString();
+ </script>
+ <send type="qt:signal" event="playbackStarted">
+ <param name="media" expr="media"/>
+ </send>
+ </onentry>
+
+ <onexit>
+ <send type="qt:signal" event="playbackStopped">
+ <param name="media" expr="media"/>
+ </send>
+ </onexit>
+
+ <transition event="tap" cond="!isValidMedia() || media == eventData().value(QStringLiteral(&quot;media&quot;))" target="stopped"/>
+ <transition event="tap" cond="isValidMedia() &amp;&amp; media != eventData().value(QStringLiteral(&quot;media&quot;))" target="playing"/>
+ </state>
+</scxml>
diff --git a/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.cpp b/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.cpp
new file mode 100644
index 0000000..5c950f9
--- /dev/null
+++ b/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.cpp
@@ -0,0 +1,63 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QQmlContext>
+
+#include "mediaplayer-cppdatamodel.h"
+#include "thedatamodel.h"
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ MediaPlayerStateMachine stateMachine;
+ TheDataModel dataModel;
+ stateMachine.setDataModel(&dataModel);
+ stateMachine.init();
+ stateMachine.start();
+
+ QQmlApplicationEngine engine;
+ engine.rootContext()->setContextProperty(QStringLiteral("mediaPlayerStateMachine"), &stateMachine);
+ engine.load(QUrl(QStringLiteral("qrc:///mediaplayer-qml-cppdatamodel.qml")));
+
+ return app.exec();
+}
diff --git a/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.pro b/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.pro
new file mode 100644
index 0000000..efbbea8
--- /dev/null
+++ b/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.pro
@@ -0,0 +1,18 @@
+TEMPLATE = app
+
+QT += qml scxml
+
+SOURCES += mediaplayer-qml-cppdatamodel.cpp \
+ thedatamodel.cpp
+
+HEADERS += thedatamodel.h
+
+RESOURCES += mediaplayer-qml-cppdatamodel.qrc
+
+STATECHARTS = mediaplayer-cppdatamodel.scxml
+
+load(qscxmlc)
+
+target.path = $$[QT_INSTALL_EXAMPLES]/scxml/mediaplayer-qml-cppdatamodel
+INSTALLS += target
+
diff --git a/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.qml b/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.qml
new file mode 100644
index 0000000..3db05f7
--- /dev/null
+++ b/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.qml
@@ -0,0 +1,43 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+Mediaplayer {
+ stateMachine: mediaPlayerStateMachine
+}
diff --git a/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.qrc b/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.qrc
new file mode 100644
index 0000000..0de7eb7
--- /dev/null
+++ b/examples/mediaplayer-qml-cppdatamodel/mediaplayer-qml-cppdatamodel.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file alias="Mediaplayer.qml">../mediaplayer-common/Mediaplayer.qml</file>
+ <file>mediaplayer-qml-cppdatamodel.qml</file>
+ </qresource>
+</RCC>
diff --git a/examples/mediaplayer-qml-cppdatamodel/thedatamodel.cpp b/examples/mediaplayer-qml-cppdatamodel/thedatamodel.cpp
new file mode 100644
index 0000000..a018f68
--- /dev/null
+++ b/examples/mediaplayer-qml-cppdatamodel/thedatamodel.cpp
@@ -0,0 +1,57 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "thedatamodel.h"
+
+#include <QScxmlEvent>
+
+TheDataModel::~TheDataModel()
+{}
+
+bool TheDataModel::isValidMedia() const
+{
+ QString eventMedia = eventData().value(QStringLiteral("media")).toString();
+ return eventMedia.size() > 0;
+}
+
+QVariantMap TheDataModel::eventData() const
+{
+ return event().data().value<QVariantMap>();
+}
diff --git a/examples/mediaplayer-qml-cppdatamodel/thedatamodel.h b/examples/mediaplayer-qml-cppdatamodel/thedatamodel.h
new file mode 100644
index 0000000..e67cde6
--- /dev/null
+++ b/examples/mediaplayer-qml-cppdatamodel/thedatamodel.h
@@ -0,0 +1,60 @@
+/****************************************************************************
+**
+** Copyright (C) 2015 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+** * Redistributions of source code must retain the above copyright
+** notice, this list of conditions and the following disclaimer.
+** * Redistributions in binary form must reproduce the above copyright
+** notice, this list of conditions and the following disclaimer in
+** the documentation and/or other materials provided with the
+** distribution.
+** * Neither the name of The Qt Company Ltd nor the names of its
+** contributors may be used to endorse or promote products derived
+** from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef THEDATAMODEL_H
+#define THEDATAMODEL_H
+
+#include "cppdatamodel.h"
+
+class TheDataModel: public Scxml::QScxmlCppDataModel
+{
+ Q_SCXML_DATAMODEL
+
+public:
+ ~TheDataModel();
+
+private:
+ bool isValidMedia() const;
+ QVariantMap eventData() const;
+
+ QString media;
+};
+
+#endif // THEDATAMODEL_H
diff --git a/src/scxml/cppdatamodel.cpp b/src/scxml/cppdatamodel.cpp
new file mode 100644
index 0000000..06e8b40
--- /dev/null
+++ b/src/scxml/cppdatamodel.cpp
@@ -0,0 +1,96 @@
+/****************************************************************************
+ **
+ ** Copyright (c) 2015 Digia Plc
+ ** For any questions to Digia, please use contact form at http://qt.digia.com/
+ **
+ ** All Rights Reserved.
+ **
+ ** NOTICE: All information contained herein is, and remains
+ ** the property of Digia Plc and its suppliers,
+ ** if any. The intellectual and technical concepts contained
+ ** herein are proprietary to Digia Plc
+ ** and its suppliers and may be covered by Finnish and Foreign Patents,
+ ** patents in process, and are protected by trade secret or copyright law.
+ ** Dissemination of this information or reproduction of this material
+ ** is strictly forbidden unless prior written permission is obtained
+ ** from Digia Plc.
+ ****************************************************************************/
+
+#include "cppdatamodel_p.h"
+#include "scxmlstatemachine.h"
+
+QT_USE_NAMESPACE
+using namespace Scxml;
+
+QScxmlCppDataModel::QScxmlCppDataModel()
+ : data(new QScxmlCppDataModelPrivate)
+{}
+
+QScxmlCppDataModel::~QScxmlCppDataModel()
+{
+ delete data;
+}
+
+void QScxmlCppDataModel::setup(const QVariantMap &initialDataValues)
+{
+ Q_UNUSED(initialDataValues);
+}
+
+void QScxmlCppDataModel::evaluateAssignment(EvaluatorId id, bool *ok)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(ok);
+ Q_UNREACHABLE();
+}
+
+void QScxmlCppDataModel::evaluateInitialization(EvaluatorId id, bool *ok)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(ok);
+ Q_UNREACHABLE();
+}
+
+bool QScxmlCppDataModel::evaluateForeach(EvaluatorId id, bool *ok, ForeachLoopBody *body)
+{
+ Q_UNUSED(id);
+ Q_UNUSED(ok);
+ Q_UNUSED(body);
+ Q_UNREACHABLE();
+ return false;
+}
+
+void QScxmlCppDataModel::setEvent(const QScxmlEvent &event)
+{
+ data->event = event;
+}
+
+const QScxmlEvent &QScxmlCppDataModel::event() const
+{
+ return data->event;
+}
+
+QVariant QScxmlCppDataModel::property(const QString &name) const
+{
+ Q_UNUSED(name);
+ return QVariant();
+}
+
+bool QScxmlCppDataModel::hasProperty(const QString &name) const
+{
+ Q_UNUSED(name);
+ return false;
+}
+
+void QScxmlCppDataModel::setProperty(const QString &name, const QVariant &value, const QString &context, bool *ok)
+{
+ Q_UNUSED(name);
+ Q_UNUSED(value);
+ Q_UNUSED(context);
+ Q_UNUSED(ok);
+ Q_UNREACHABLE();
+}
+
+bool QScxmlCppDataModel::In(const QString &stateName) const
+{
+ return stateMachine()->isActive(stateName);
+}
diff --git a/src/scxml/cppdatamodel.h b/src/scxml/cppdatamodel.h
new file mode 100644
index 0000000..a1f0c99
--- /dev/null
+++ b/src/scxml/cppdatamodel.h
@@ -0,0 +1,66 @@
+/****************************************************************************
+ **
+ ** Copyright (c) 2015 Digia Plc
+ ** For any questions to Digia, please use contact form at http://qt.digia.com/
+ **
+ ** All Rights Reserved.
+ **
+ ** NOTICE: All information contained herein is, and remains
+ ** the property of Digia Plc and its suppliers,
+ ** if any. The intellectual and technical concepts contained
+ ** herein are proprietary to Digia Plc
+ ** and its suppliers and may be covered by Finnish and Foreign Patents,
+ ** patents in process, and are protected by trade secret or copyright law.
+ ** Dissemination of this information or reproduction of this material
+ ** is strictly forbidden unless prior written permission is obtained
+ ** from Digia Plc.
+ ****************************************************************************/
+
+#ifndef CPPDATAMODEL_H
+#define CPPDATAMODEL_H
+
+#include "datamodel.h"
+
+#define Q_SCXML_DATAMODEL \
+ public: \
+ QString evaluateToString(Scxml::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE; \
+ bool evaluateToBool(Scxml::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE; \
+ QVariant evaluateToVariant(Scxml::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE; \
+ void evaluateToVoid(Scxml::EvaluatorId id, bool *ok) Q_DECL_OVERRIDE;
+
+QT_BEGIN_NAMESPACE
+
+namespace Scxml {
+
+class QScxmlCppDataModelPrivate;
+class Q_SCXML_EXPORT QScxmlCppDataModel: public QScxmlDataModel
+{
+public:
+ QScxmlCppDataModel();
+ ~QScxmlCppDataModel();
+
+ void setup(const QVariantMap &initialDataValues) Q_DECL_OVERRIDE;
+
+ void evaluateAssignment(EvaluatorId id, bool *ok) Q_DECL_OVERRIDE;
+ void evaluateInitialization(EvaluatorId id, bool *ok) Q_DECL_OVERRIDE;
+ bool evaluateForeach(EvaluatorId id, bool *ok, ForeachLoopBody *body) Q_DECL_OVERRIDE;
+
+ void setEvent(const QScxmlEvent &event) Q_DECL_OVERRIDE;
+ const QScxmlEvent &event() const;
+
+ QVariant property(const QString &name) const Q_DECL_OVERRIDE;
+ bool hasProperty(const QString &name) const Q_DECL_OVERRIDE;
+ void setProperty(const QString &name, const QVariant &value, const QString &context,
+ bool *ok) Q_DECL_OVERRIDE;
+
+ bool In(const QString &stateName) const;
+
+private:
+ QScxmlCppDataModelPrivate *data;
+};
+
+} // Scxml namespace
+
+QT_END_NAMESPACE
+
+#endif // CPPDATAMODEL_H
diff --git a/src/scxml/cppdatamodel_p.h b/src/scxml/cppdatamodel_p.h
new file mode 100644
index 0000000..8e40d68
--- /dev/null
+++ b/src/scxml/cppdatamodel_p.h
@@ -0,0 +1,39 @@
+/****************************************************************************
+ **
+ ** Copyright (c) 2015 Digia Plc
+ ** For any questions to Digia, please use contact form at http://qt.digia.com/
+ **
+ ** All Rights Reserved.
+ **
+ ** NOTICE: All information contained herein is, and remains
+ ** the property of Digia Plc and its suppliers,
+ ** if any. The intellectual and technical concepts contained
+ ** herein are proprietary to Digia Plc
+ ** and its suppliers and may be covered by Finnish and Foreign Patents,
+ ** patents in process, and are protected by trade secret or copyright law.
+ ** Dissemination of this information or reproduction of this material
+ ** is strictly forbidden unless prior written permission is obtained
+ ** from Digia Plc.
+ ****************************************************************************/
+
+#ifndef CPPDATAMODEL_P_H
+#define CPPDATAMODEL_P_H
+
+#include "cppdatamodel.h"
+#include "QScxmlEvent"
+
+QT_BEGIN_NAMESPACE
+
+namespace Scxml {
+
+class Q_SCXML_EXPORT QScxmlCppDataModelPrivate
+{
+public:
+ QScxmlEvent event;
+};
+
+} // Scxml namespace
+
+QT_END_NAMESPACE
+
+#endif // CPPDATAMODEL_P_H
diff --git a/src/scxml/executablecontent.cpp b/src/scxml/executablecontent.cpp
index 9749e8e..d741f14 100644
--- a/src/scxml/executablecontent.cpp
+++ b/src/scxml/executablecontent.cpp
@@ -133,7 +133,7 @@ public:
}
case Instruction::JavaScript: {
- qDebug() << "Executing javascript step";
+ qDebug() << "Executing script step";
JavaScript *javascript = reinterpret_cast<JavaScript *>(instr);
ip += javascript->size();
bool ok = true;
@@ -295,6 +295,7 @@ bool ExecutionEngine::execute(ContainerId id, const QVariant &extraData)
Builder::Builder()
: m_initialSetup(ExecutableContent::NoInstruction)
+ , m_isCppDataModel(false)
{
m_activeSequences.reserve(4);
}
@@ -335,8 +336,7 @@ void Builder::visit(DocumentModel::Log *node)
void Builder::visit(DocumentModel::Script *node)
{
auto instr = m_instructions.add<JavaScript>();
- auto ctxt = createContext(QStringLiteral("script"), QStringLiteral("source"), node->content);
- instr->go = addEvaluator(node->content, ctxt);
+ instr->go = createEvaluatorVoid(QStringLiteral("script"), QStringLiteral("source"), node->content);
}
void Builder::visit(DocumentModel::Assign *node)
@@ -504,8 +504,14 @@ InstructionSequence *Builder::endSequence()
EvaluatorId Builder::createEvaluatorString(const QString &instrName, const QString &attrName, const QString &expr)
{
if (!expr.isEmpty()) {
- QString loc = createContext(instrName, attrName, expr);
- return addEvaluator(expr, loc);
+ if (isCppDataModel()) {
+ auto id = m_evaluators.add(QScxmlEvaluatorInfo(), false);
+ m_stringEvaluators.insert(id, expr);
+ return id;
+ } else {
+ QString loc = createContext(instrName, attrName, expr);
+ return addEvaluator(expr, loc);
+ }
}
return NoEvaluator;
@@ -514,18 +520,46 @@ EvaluatorId Builder::createEvaluatorString(const QString &instrName, const QStri
EvaluatorId Builder::createEvaluatorBool(const QString &instrName, const QString &attrName, const QString &cond)
{
if (!cond.isEmpty()) {
- QString loc = createContext(instrName, attrName, cond);
- return addEvaluator(cond, loc);
+ if (isCppDataModel()) {
+ auto id = m_evaluators.add(QScxmlEvaluatorInfo(), false);
+ m_boolEvaluators.insert(id, cond);
+ return id;
+ } else {
+ QString loc = createContext(instrName, attrName, cond);
+ return addEvaluator(cond, loc);
+ }
}
return NoEvaluator;
}
-EvaluatorId Builder::createEvaluatorVariant(const QString &instrName, const QString &attrName, const QString &cond)
+EvaluatorId Builder::createEvaluatorVariant(const QString &instrName, const QString &attrName, const QString &expr)
{
- if (!cond.isEmpty()) {
- QString loc = createContext(instrName, attrName, cond);
- return addEvaluator(cond, loc);
+ if (!expr.isEmpty()) {
+ if (isCppDataModel()) {
+ auto id = m_evaluators.add(QScxmlEvaluatorInfo(), false);
+ m_variantEvaluators.insert(id, expr);
+ return id;
+ } else {
+ QString loc = createContext(instrName, attrName, expr);
+ return addEvaluator(expr, loc);
+ }
+ }
+
+ return NoEvaluator;
+}
+
+EvaluatorId Builder::createEvaluatorVoid(const QString &instrName, const QString &attrName, const QString &stuff)
+{
+ if (!stuff.isEmpty()) {
+ if (isCppDataModel()) {
+ auto id = m_evaluators.add(QScxmlEvaluatorInfo(), false);
+ m_voidEvaluators.insert(id, stuff);
+ return id;
+ } else {
+ QString loc = createContext(instrName, attrName, stuff);
+ return addEvaluator(stuff, loc);
+ }
}
return NoEvaluator;
diff --git a/src/scxml/executablecontent_p.h b/src/scxml/executablecontent_p.h
index 3f06a7c..b3237b7 100644
--- a/src/scxml/executablecontent_p.h
+++ b/src/scxml/executablecontent_p.h
@@ -322,7 +322,8 @@ protected:
InstructionSequence *endSequence();
EvaluatorId createEvaluatorString(const QString &instrName, const QString &attrName, const QString &expr);
EvaluatorId createEvaluatorBool(const QString &instrName, const QString &attrName, const QString &cond);
- EvaluatorId createEvaluatorVariant(const QString &instrName, const QString &attrName, const QString &cond);
+ EvaluatorId createEvaluatorVariant(const QString &instrName, const QString &attrName, const QString &expr);
+ EvaluatorId createEvaluatorVoid(const QString &instrName, const QString &attrName, const QString &stuff);
virtual QString createContextString(const QString &instrName) const = 0;
virtual QString createContext(const QString &instrName, const QString &attrName, const QString &attrValue) const = 0;
@@ -341,6 +342,24 @@ protected:
void setName(const QString &name)
{ m_name = name; }
+ bool isCppDataModel() const
+ { return m_isCppDataModel; }
+
+ void setIsCppDataModel(bool onoff)
+ { m_isCppDataModel = onoff; }
+
+ QMap<EvaluatorId, QString> boolEvaluators() const
+ { return m_boolEvaluators; }
+
+ QMap<EvaluatorId, QString> stringEvaluators() const
+ { return m_stringEvaluators; }
+
+ QMap<EvaluatorId, QString> variantEvaluators() const
+ { return m_variantEvaluators; }
+
+ QMap<EvaluatorId, QString> voidEvaluators() const
+ { return m_voidEvaluators; }
+
private:
template <typename T, typename U>
class Table {
@@ -348,8 +367,8 @@ private:
QMap<T, int> indexForElement;
public:
- U add(const T &s) {
- int pos = indexForElement.value(s, -1);
+ U add(const T &s, bool uniqueOnly = true) {
+ int pos = uniqueOnly ? indexForElement.value(s, -1) : -1;
if (pos == -1) {
pos = elements.size();
elements.append(s);
@@ -464,9 +483,14 @@ private:
Table<QScxmlEvaluatorInfo, EvaluatorId> m_evaluators;
Table<QScxmlAssignmentInfo, EvaluatorId> m_assignments;
Table<QScxmlForeachInfo, EvaluatorId> m_foreaches;
+ QMap<EvaluatorId, QString> m_boolEvaluators;
+ QMap<EvaluatorId, QString> m_stringEvaluators;
+ QMap<EvaluatorId, QString> m_variantEvaluators;
+ QMap<EvaluatorId, QString> m_voidEvaluators;
ExecutableContent::StringIds m_dataIds;
ContainerId m_initialSetup;
QString m_name;
+ bool m_isCppDataModel;
};
} // ExecutableContent namespace
diff --git a/src/scxml/scxml.pro b/src/scxml/scxml.pro
index 149c5e2..ebdd0d8 100644
--- a/src/scxml/scxml.pro
+++ b/src/scxml/scxml.pro
@@ -22,7 +22,9 @@ HEADERS += \
scxmlevent_p.h \
datamodel.h \
scxmlqstates.h \
- scxmlqstates_p.h
+ scxmlqstates_p.h \
+ cppdatamodel_p.h \
+ cppdatamodel.h
SOURCES += \
scxmlparser.cpp \
@@ -33,4 +35,5 @@ SOURCES += \
executablecontent.cpp \
scxmlevent.cpp \
datamodel.cpp \
- scxmlqstates.cpp
+ scxmlqstates.cpp \
+ cppdatamodel.cpp
diff --git a/src/scxml/scxmlparser.cpp b/src/scxml/scxmlparser.cpp
index 0f28d88..4b1a6af 100644
--- a/src/scxml/scxmlparser.cpp
+++ b/src/scxml/scxmlparser.cpp
@@ -867,6 +867,8 @@ inline ScxmlInvokableService *InvokeDynamicScxmlFactory::invoke(StateMachine *pa
case DocumentModel::Scxml::JSDataModel:
dataModel = new QScxmlEcmaScriptDataModel;
break;
+ case DocumentModel::Scxml::CppDataModel:
+ break;
default:
Q_UNREACHABLE();
}
@@ -1387,6 +1389,21 @@ void ScxmlParserPrivate::parse()
scxml->dataModel = DocumentModel::Scxml::NullDataModel;
} else if (datamodel == QLatin1String("ecmascript")) {
scxml->dataModel = DocumentModel::Scxml::JSDataModel;
+ } else if (datamodel.startsWith(QLatin1String("cplusplus"))) {
+ scxml->dataModel = DocumentModel::Scxml::CppDataModel;
+ int firstColon = datamodel.indexOf(QLatin1Char(':'));
+ if (firstColon == -1) {
+ scxml->cppDataModelClassName = attributes.value(QStringLiteral("name")) + QStringLiteral("DataModel");
+ scxml->cppDataModelHeaderName = scxml->cppDataModelClassName + QStringLiteral(".h");
+ } else {
+ int lastColon = datamodel.lastIndexOf(QLatin1Char(':'));
+ if (lastColon == -1) {
+ lastColon = datamodel.length();
+ } else {
+ scxml->cppDataModelHeaderName = datamodel.mid(lastColon + 1).toString();
+ }
+ scxml->cppDataModelClassName = datamodel.mid(firstColon + 1, lastColon - firstColon - 1).toString();
+ }
} else {
addError(QStringLiteral("Unsupported data model '%1' in scxml")
.arg(datamodel.toString()));
diff --git a/src/scxml/scxmlparser_p.h b/src/scxml/scxmlparser_p.h
index d8834d5..f0bac94 100644
--- a/src/scxml/scxmlparser_p.h
+++ b/src/scxml/scxmlparser_p.h
@@ -338,7 +338,8 @@ struct Scxml: public StateContainer, public Node
{
enum DataModelType {
NullDataModel,
- JSDataModel
+ JSDataModel,
+ CppDataModel
};
enum BindingMethod {
EarlyBinding,
@@ -349,6 +350,8 @@ struct Scxml: public StateContainer, public Node
QString name;
QString qtClassname;
DataModelType dataModel;
+ QString cppDataModelClassName;
+ QString cppDataModelHeaderName;
BindingMethod binding;
QVector<StateOrTransition *> children;
QVector<DataElement *> dataElements;
diff --git a/tools/qscxmlc/scxmlcppdumper.cpp b/tools/qscxmlc/scxmlcppdumper.cpp
index f8ebe4e..bc88146 100644
--- a/tools/qscxmlc/scxmlcppdumper.cpp
+++ b/tools/qscxmlc/scxmlcppdumper.cpp
@@ -74,6 +74,7 @@ struct StringListDumper {
struct Method {
StringListDumper initializer;
Method(const QString &decl = QString()): decl(decl) {}
+ Method(const StringListDumper &impl): impl(impl) {}
QString decl; // void f(int i = 0);
StringListDumper impl; // void f(int i) { m_i = ++i; }
};
@@ -81,6 +82,7 @@ struct Method {
struct ClassDump {
StringListDumper implIncludes;
QString className;
+ QString dataModelClassName;
StringListDumper classFields;
StringListDumper tables;
Method init;
@@ -93,6 +95,8 @@ struct ClassDump {
QList<Method> publicMethods;
StringListDumper publicSlotDeclarations;
StringListDumper publicSlotDefinitions;
+
+ QList<Method> dataModelMethods;
};
namespace {
@@ -210,7 +214,12 @@ protected:
<< QStringLiteral("{ return QString(); }")
<< QString();
}
- clazz.init.impl << QStringLiteral("stateMachine.setDataModel(&dataModel);");
+ if (node->dataModel == Scxml::CppDataModel) {
+ setIsCppDataModel(true);
+ clazz.dataModelClassName = node->cppDataModelClassName;
+ } else {
+ clazz.init.impl << QStringLiteral("stateMachine.setDataModel(&dataModel);");
+ }
QString binding;
switch (node->binding) {
@@ -258,20 +267,21 @@ protected:
m_parents.removeLast();
{ // the data model:
- QString dmName;
switch (node->dataModel) {
case Scxml::NullDataModel:
- dmName = QStringLiteral("Null");
+ clazz.classFields << QStringLiteral("Scxml::QScxmlNullDataModel dataModel;");
clazz.implIncludes << QStringLiteral("QtScxml/nulldatamodel.h");
break;
case Scxml::JSDataModel:
- dmName = QStringLiteral("EcmaScript");
+ clazz.classFields << QStringLiteral("Scxml::QScxmlEcmaScriptDataModel dataModel;");
clazz.implIncludes << QStringLiteral("QtScxml/ecmascriptdatamodel.h");
break;
+ case Scxml::CppDataModel:
+ clazz.implIncludes << node->cppDataModelHeaderName;
+ break;
default:
Q_UNREACHABLE();
}
- clazz.classFields << QStringLiteral("Scxml::QScxml") + dmName + QStringLiteral("DataModel dataModel;");
}
return false;
}
@@ -730,6 +740,171 @@ private:
<< QString();
}
+ { // dataIds
+ int count;
+ auto dataIds = td->dataNames(&count);
+ clazz.classFields << QStringLiteral("static Scxml::ExecutableContent::StringId dataIds[];");
+ t << QStringLiteral("Scxml::ExecutableContent::StringId %1::Data::dataIds[] = {").arg(clazz.className);
+ if (isCppDataModel()) {
+ t << QStringLiteral("-1");
+ } else {
+ generateList(t, [&dataIds, count](int idx) -> QString {
+ if (count == 0 && idx == 0) // prevent generation of empty array
+ return QStringLiteral("-1");
+ if (idx < count)
+ return QString::number(dataIds[idx]);
+ else
+ return QString();
+ });
+ }
+ t << QStringLiteral("};") << QStringLiteral("");
+ clazz.dataMethods << QStringLiteral("Scxml::ExecutableContent::StringId *dataNames(int *count) const Q_DECL_OVERRIDE");
+ clazz.dataMethods << QStringLiteral("{ *count = %1; return dataIds; }").arg(count);
+ clazz.dataMethods << QString();
+ }
+
+ { // evaluators
+ auto evaluators = td->evaluators();
+ clazz.classFields << QStringLiteral("static Scxml::QScxmlEvaluatorInfo evaluators[];");
+ t << QStringLiteral("Scxml::QScxmlEvaluatorInfo %1::Data::evaluators[] = {").arg(clazz.className);
+ if (isCppDataModel()) {
+ t << QStringLiteral("{ -1, -1 }");
+ } else {
+ generateList(t, [&evaluators](int idx) -> QString {
+ if (evaluators.isEmpty() && idx == 0) // prevent generation of empty array
+ return QStringLiteral("{ -1, -1 }");
+ if (idx >= evaluators.size())
+ return QString();
+
+ auto eval = evaluators.at(idx);
+ return QStringLiteral("{ %1, %2 }").arg(eval.expr).arg(eval.context);
+ });
+ }
+ t << QStringLiteral("};") << QStringLiteral("");
+ clazz.dataMethods << QStringLiteral("Scxml::QScxmlEvaluatorInfo evaluatorInfo(Scxml::EvaluatorId evaluatorId) const Q_DECL_OVERRIDE");
+ clazz.dataMethods << QStringLiteral("{ Q_ASSERT(evaluatorId >= 0); Q_ASSERT(evaluatorId < %1); return evaluators[evaluatorId]; }").arg(evaluators.size());
+ clazz.dataMethods << QString();
+
+ if (isCppDataModel()) {
+ {
+ StringListDumper stringEvals;
+ stringEvals << QStringLiteral("QString %1::evaluateToString(Scxml::EvaluatorId id, bool *ok) {").arg(clazz.dataModelClassName)
+ << QStringLiteral(" *ok = true;")
+ << QStringLiteral(" switch (id) {");
+ auto evals = stringEvaluators();
+ for (auto it = evals.constBegin(), eit = evals.constEnd(); it != eit; ++it) {
+ stringEvals << QStringLiteral(" case %1:").arg(it.key())
+ << QStringLiteral(" return [this](){ return %1; }();").arg(it.value());
+ }
+ stringEvals << QStringLiteral(" default:")
+ << QStringLiteral(" Q_UNREACHABLE();")
+ << QStringLiteral(" *ok = false;")
+ << QStringLiteral(" return QString();")
+ << QStringLiteral(" }");
+ stringEvals << QStringLiteral("}");
+ clazz.dataModelMethods.append(Method(stringEvals));
+ }
+
+ {
+ StringListDumper boolEvals;
+ boolEvals << QStringLiteral("bool %1::evaluateToBool(Scxml::EvaluatorId id, bool *ok) {").arg(clazz.dataModelClassName)
+ << QStringLiteral(" *ok = true;")
+ << QStringLiteral(" switch (id) {");
+ auto evals = boolEvaluators();
+ for (auto it = evals.constBegin(), eit = evals.constEnd(); it != eit; ++it) {
+ boolEvals << QStringLiteral(" case %1:").arg(it.key())
+ << QStringLiteral(" return [this](){ return %1; }();").arg(it.value());
+ }
+ boolEvals << QStringLiteral(" default:")
+ << QStringLiteral(" Q_UNREACHABLE();")
+ << QStringLiteral(" *ok = false;")
+ << QStringLiteral(" return false;")
+ << QStringLiteral(" }");
+ boolEvals << QStringLiteral("}");
+ clazz.dataModelMethods.append(Method(boolEvals));
+ }
+
+ {
+ StringListDumper variantEvals;
+ variantEvals << QStringLiteral("QVariant %1::evaluateToVariant(Scxml::EvaluatorId id, bool *ok) {").arg(clazz.dataModelClassName)
+ << QStringLiteral(" *ok = true;")
+ << QStringLiteral(" switch (id) {");
+ auto evals = variantEvaluators();
+ for (auto it = evals.constBegin(), eit = evals.constEnd(); it != eit; ++it) {
+ variantEvals << QStringLiteral(" case %1:").arg(it.key())
+ << QStringLiteral(" return [this](){ return %1; }();").arg(it.value());
+ }
+ variantEvals << QStringLiteral(" default:")
+ << QStringLiteral(" Q_UNREACHABLE();")
+ << QStringLiteral(" *ok = false;")
+ << QStringLiteral(" return QVariant();")
+ << QStringLiteral(" }");
+ variantEvals << QStringLiteral("}");
+ clazz.dataModelMethods.append(Method(variantEvals));
+ }
+
+ {
+ StringListDumper voidEvals;
+ voidEvals << QStringLiteral("void %1::evaluateToVoid(Scxml::EvaluatorId id, bool *ok) {").arg(clazz.dataModelClassName)
+ << QStringLiteral(" *ok = true;")
+ << QStringLiteral(" switch (id) {");
+ auto evals = voidEvaluators();
+ for (auto it = evals.constBegin(), eit = evals.constEnd(); it != eit; ++it) {
+ voidEvals << QStringLiteral(" case %1:").arg(it.key())
+ << QStringLiteral(" [this](){ %1 }();").arg(it.value())
+ << QStringLiteral(" break;");
+ }
+ voidEvals << QStringLiteral(" default:")
+ << QStringLiteral(" Q_UNREACHABLE();")
+ << QStringLiteral(" *ok = false;")
+ << QStringLiteral(" }");
+ voidEvals << QStringLiteral("}");
+ clazz.dataModelMethods.append(Method(voidEvals));
+ }
+ }
+ }
+
+ { // assignments
+ auto assignments = td->assignments();
+ clazz.classFields << QStringLiteral("static Scxml::QScxmlAssignmentInfo assignments[];");
+ t << QStringLiteral("Scxml::QScxmlAssignmentInfo %1::Data::assignments[] = {").arg(clazz.className);
+ if (isCppDataModel()) {
+ t << QStringLiteral("{ -1, -1, -1 }");
+ } else {
+ generateList(t, [&assignments](int idx) -> QString {
+ if (assignments.isEmpty() && idx == 0) // prevent generation of empty array
+ return QStringLiteral("{ -1, -1, -1 }");
+ if (idx >= assignments.size())
+ return QString();
+
+ auto ass = assignments.at(idx);
+ return QStringLiteral("{ %1, %2, %3 }").arg(ass.dest).arg(ass.expr).arg(ass.context);
+ });
+ }
+ t << QStringLiteral("};") << QStringLiteral("");
+ clazz.dataMethods << QStringLiteral("Scxml::QScxmlAssignmentInfo assignmentInfo(Scxml::EvaluatorId assignmentId) const Q_DECL_OVERRIDE");
+ clazz.dataMethods << QStringLiteral("{ Q_ASSERT(assignmentId >= 0); Q_ASSERT(assignmentId < %1); return assignments[assignmentId]; }").arg(assignments.size());
+ clazz.dataMethods << QString();
+ }
+
+ { // foreaches
+ auto foreaches = td->foreaches();
+ clazz.classFields << QStringLiteral("static Scxml::QScxmlForeachInfo foreaches[];");
+ t << QStringLiteral("Scxml::QScxmlForeachInfo %1::Data::foreaches[] = {").arg(clazz.className);
+ generateList(t, [&foreaches](int idx) -> QString {
+ if (foreaches.isEmpty() && idx == 0) // prevent generation of empty array
+ return QStringLiteral("{ -1, -1, -1, -1 }");
+ if (idx >= foreaches.size())
+ return QString();
+
+ auto foreach = foreaches.at(idx);
+ return QStringLiteral("{ %1, %2, %3, %4 }").arg(foreach.array).arg(foreach.item).arg(foreach.index).arg(foreach.context);
+ });
+ t << QStringLiteral("};") << QStringLiteral("");
+ clazz.dataMethods << QStringLiteral("Scxml::QScxmlForeachInfo foreachInfo(Scxml::EvaluatorId foreachId) const Q_DECL_OVERRIDE");
+ clazz.dataMethods << QStringLiteral("{ Q_ASSERT(foreachId >= 0); Q_ASSERT(foreachId < %1); return foreaches[foreachId]; }").arg(foreaches.size());
+ }
+
{ // strings
t << QStringLiteral("#define STR_LIT(idx, ofs, len) \\")
<< QStringLiteral(" Q_STATIC_STRING_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \\")
@@ -745,19 +920,21 @@ private:
if (idx >= strings.size())
return QString();
- auto s = strings.at(idx);
+ int length = strings.at(idx).size();
QString str = QStringLiteral("STR_LIT(%1, %2, %3)").arg(QString::number(idx),
QString::number(ucharCount),
- QString::number(s.size()));
- ucharCount += s.size() + 1;
+ QString::number(length));
+ ucharCount += length + 1;
return str;
});
t << QStringLiteral("},");
if (strings.isEmpty()) {
t << QStringLiteral("QT_UNICODE_LITERAL_II(\"\")");
} else {
- foreach (const QString &s, strings) {
- t << QStringLiteral("QT_UNICODE_LITERAL_II(\"%1\") // %2").arg(toHex(s) + QStringLiteral("\\x00"), cEscape(s));
+ for (int i = 0, ei = strings.size(); i < ei; ++i) {
+ QString s = strings.at(i);
+ QString comment = cEscape(s);
+ t << QStringLiteral("QT_UNICODE_LITERAL_II(\"%1\") // %2").arg(toHex(s) + QStringLiteral("\\x00"), comment);
}
}
t << QStringLiteral("};") << QStringLiteral("");
@@ -836,81 +1013,6 @@ private:
clazz.dataMethods << QStringLiteral("}");
clazz.dataMethods << QString();
}
-
- { // dataIds
- int count;
- auto dataIds = td->dataNames(&count);
- clazz.classFields << QStringLiteral("static Scxml::ExecutableContent::StringId dataIds[];");
- t << QStringLiteral("Scxml::ExecutableContent::StringId %1::Data::dataIds[] = {").arg(clazz.className);
- generateList(t, [&dataIds, count](int idx) -> QString {
- if (count == 0 && idx == 0) // prevent generation of empty array
- return QStringLiteral("-1");
- if (idx < count)
- return QString::number(dataIds[idx]);
- else
- return QString();
- });
- t << QStringLiteral("};") << QStringLiteral("");
- clazz.dataMethods << QStringLiteral("Scxml::ExecutableContent::StringId *dataNames(int *count) const Q_DECL_OVERRIDE");
- clazz.dataMethods << QStringLiteral("{ *count = %1; return dataIds; }").arg(count);
- clazz.dataMethods << QString();
- }
-
- { // evaluators
- auto evaluators = td->evaluators();
- clazz.classFields << QStringLiteral("static Scxml::QScxmlEvaluatorInfo evaluators[];");
- t << QStringLiteral("Scxml::QScxmlEvaluatorInfo %1::Data::evaluators[] = {").arg(clazz.className);
- generateList(t, [&evaluators](int idx) -> QString {
- if (evaluators.isEmpty() && idx == 0) // prevent generation of empty array
- return QStringLiteral("{ -1, -1 }");
- if (idx >= evaluators.size())
- return QString();
-
- auto eval = evaluators.at(idx);
- return QStringLiteral("{ %1, %2 }").arg(eval.expr).arg(eval.context);
- });
- t << QStringLiteral("};") << QStringLiteral("");
- clazz.dataMethods << QStringLiteral("Scxml::QScxmlEvaluatorInfo evaluatorInfo(Scxml::EvaluatorId evaluatorId) const Q_DECL_OVERRIDE");
- clazz.dataMethods << QStringLiteral("{ Q_ASSERT(evaluatorId >= 0); Q_ASSERT(evaluatorId < %1); return evaluators[evaluatorId]; }").arg(evaluators.size());
- clazz.dataMethods << QString();
- }
-
- { // assignments
- auto assignments = td->assignments();
- clazz.classFields << QStringLiteral("static Scxml::QScxmlAssignmentInfo assignments[];");
- t << QStringLiteral("Scxml::QScxmlAssignmentInfo %1::Data::assignments[] = {").arg(clazz.className);
- generateList(t, [&assignments](int idx) -> QString {
- if (assignments.isEmpty() && idx == 0) // prevent generation of empty array
- return QStringLiteral("{ -1, -1, -1 }");
- if (idx >= assignments.size())
- return QString();
-
- auto ass = assignments.at(idx);
- return QStringLiteral("{ %1, %2, %3 }").arg(ass.dest).arg(ass.expr).arg(ass.context);
- });
- t << QStringLiteral("};") << QStringLiteral("");
- clazz.dataMethods << QStringLiteral("Scxml::QScxmlAssignmentInfo assignmentInfo(Scxml::EvaluatorId assignmentId) const Q_DECL_OVERRIDE");
- clazz.dataMethods << QStringLiteral("{ Q_ASSERT(assignmentId >= 0); Q_ASSERT(assignmentId < %1); return assignments[assignmentId]; }").arg(assignments.size());
- clazz.dataMethods << QString();
- }
-
- { // foreaches
- auto foreaches = td->foreaches();
- clazz.classFields << QStringLiteral("static Scxml::QScxmlForeachInfo foreaches[];");
- t << QStringLiteral("Scxml::QScxmlForeachInfo %1::Data::foreaches[] = {").arg(clazz.className);
- generateList(t, [&foreaches](int idx) -> QString {
- if (foreaches.isEmpty() && idx == 0) // prevent generation of empty array
- return QStringLiteral("{ -1, -1, -1, -1 }");
- if (idx >= foreaches.size())
- return QString();
-
- auto foreach = foreaches.at(idx);
- return QStringLiteral("{ %1, %2, %3, %4 }").arg(foreach.array).arg(foreach.item).arg(foreach.index).arg(foreach.context);
- });
- t << QStringLiteral("};") << QStringLiteral("");
- clazz.dataMethods << QStringLiteral("Scxml::QScxmlForeachInfo foreachInfo(Scxml::EvaluatorId foreachId) const Q_DECL_OVERRIDE");
- clazz.dataMethods << QStringLiteral("{ Q_ASSERT(foreachId >= 0); Q_ASSERT(foreachId < %1); return foreaches[foreachId]; }").arg(foreaches.size());
- }
}
QString qba(const QString &bytes)
@@ -960,7 +1062,9 @@ void CppDumper::dump(TranslationUnit *unit)
}
auto headerName = QFileInfo(unit->outHFileName).fileName();
- const QString headerGuard = headerName.toUpper().replace(QLatin1Char('.'), QLatin1Char('_'));
+ const QString headerGuard = headerName.toUpper()
+ .replace(QLatin1Char('.'), QLatin1Char('_'))
+ .replace(QLatin1Char('-'), QLatin1Char('_'));
writeHeaderStart(headerGuard);
writeImplStart(clazzes);
@@ -1099,6 +1203,13 @@ void CppDumper::writeImplBody(const ClassDump &clazz)
cpp << endl;
clazz.tables.write(cpp, QStringLiteral(""), QStringLiteral("\n"));
+
+ if (!clazz.dataModelMethods.isEmpty()) {
+ foreach (const Method &m, clazz.dataModelMethods) {
+ m.impl.write(cpp, QStringLiteral(""), QStringLiteral("\n"));
+ cpp << endl;
+ }
+ }
}
void CppDumper::writeImplEnd()