summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorErik Verbruggen <erik.verbruggen@theqtcompany.com>2015-06-02 15:30:50 +0200
committerErik Verbruggen <erik.verbruggen@theqtcompany.com>2015-06-03 15:47:28 +0300
commit991ea63c6bae70404184b0fcb77aff87bebaa891 (patch)
treee8b9fa908ee10bc1f12e2c441d5c74a546b13e8e /src
parent944dad62a1f6125583d60b6406c26df7264d7004 (diff)
Added QML module and an example using it.
This supports loading a state machine from a .scxml file, as well as setting a state machine as a QObject on the QML context. Change-Id: Iab2f12cb58f13b43912e83a08e67476d4c9296b5 Reviewed-by: Erik Verbruggen <erik.verbruggen@theqtcompany.com>
Diffstat (limited to 'src')
-rw-r--r--src/qml-module/plugin.cpp50
-rw-r--r--src/qml-module/qml-module.pro17
-rw-r--r--src/qml-module/qmldir4
-rw-r--r--src/qml-module/state.cpp62
-rw-r--r--src/qml-module/state.h63
-rw-r--r--src/qml-module/statemachine.cpp150
-rw-r--r--src/qml-module/statemachine.h70
-rw-r--r--src/qscxmllib/datamodel.cpp10
-rw-r--r--src/qscxmllib/datamodel.h5
-rw-r--r--src/qscxmllib/ecmascriptdatamodel.cpp20
-rw-r--r--src/qscxmllib/ecmascriptdatamodel.h3
-rw-r--r--src/qscxmllib/nulldatamodel.cpp5
-rw-r--r--src/qscxmllib/nulldatamodel.h2
-rw-r--r--src/qscxmllib/scxmlstatetable.cpp16
-rw-r--r--src/qscxmllib/scxmlstatetable.h6
-rw-r--r--src/qscxmllib/scxmlstatetable_p.h1
-rw-r--r--src/src.pro4
17 files changed, 468 insertions, 20 deletions
diff --git a/src/qml-module/plugin.cpp b/src/qml-module/plugin.cpp
new file mode 100644
index 0000000..041572b
--- /dev/null
+++ b/src/qml-module/plugin.cpp
@@ -0,0 +1,50 @@
+/****************************************************************************
+ **
+ ** 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 "statemachine.h"
+#include "state.h"
+
+#include <QQmlExtensionPlugin>
+#include <qqml.h>
+
+QT_BEGIN_NAMESPACE
+
+class ScxmlStateMachinePlugin : public QQmlExtensionPlugin
+{
+ Q_OBJECT
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.Scxml/1.0")
+
+public:
+ void registerTypes(const char *uri)
+ {
+ qmlRegisterType<StateMachine>(uri, 1, 0, "StateMachine");
+ qmlRegisterType<State>(uri, 1, 0, "State");
+// qmlRegisterType<QHistoryState>(uri, 1, 0, "HistoryState");
+// qmlRegisterType<FinalState>(uri, 1, 0, "FinalState");
+// qmlRegisterUncreatableType<QState>(uri, 1, 0, "QState", "Don't use this, use State instead");
+// qmlRegisterUncreatableType<QAbstractState>(uri, 1, 0, "QAbstractState", "Don't use this, use State instead");
+// qmlRegisterUncreatableType<QSignalTransition>(uri, 1, 0, "QSignalTransition", "Don't use this, use SignalTransition instead");
+// qmlRegisterType<SignalTransition>(uri, 1, 0, "SignalTransition");
+// qmlRegisterType<TimeoutTransition>(uri, 1, 0, "TimeoutTransition");
+ qmlProtectModule(uri, 1);
+ }
+};
+
+QT_END_NAMESPACE
+
+#include "plugin.moc"
diff --git a/src/qml-module/qml-module.pro b/src/qml-module/qml-module.pro
new file mode 100644
index 0000000..11823f2
--- /dev/null
+++ b/src/qml-module/qml-module.pro
@@ -0,0 +1,17 @@
+CXX_MODULE = qml
+TARGET = scxmlstatemachine
+TARGETPATH = Scxml
+IMPORT_VERSION = 1.0
+
+QT = qscxmllib #qml-private
+
+SOURCES = \
+ $$PWD/plugin.cpp \
+ $$PWD/state.cpp \
+ $$PWD/statemachine.cpp
+
+HEADERS = \
+ $$PWD/state.h \
+ $$PWD/statemachine.h
+
+load(qml_plugin)
diff --git a/src/qml-module/qmldir b/src/qml-module/qmldir
new file mode 100644
index 0000000..a411f70
--- /dev/null
+++ b/src/qml-module/qmldir
@@ -0,0 +1,4 @@
+module Scxml
+plugin scxmlstatemachine
+classname ScxmlStateMachinePlugin
+
diff --git a/src/qml-module/state.cpp b/src/qml-module/state.cpp
new file mode 100644
index 0000000..b42a7e0
--- /dev/null
+++ b/src/qml-module/state.cpp
@@ -0,0 +1,62 @@
+/****************************************************************************
+ **
+ ** 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 "state.h"
+#include "statemachine.h"
+
+#include <QScxmlLib/scxmlstatetable.h>
+#include <QQmlInfo>
+
+State::State(StateMachine *parent)
+ : QObject(parent)
+{}
+
+void State::componentComplete()
+{
+ if (Scxml::StateTable *table = qobject_cast<StateMachine *>(parent())->stateMachine()) {
+ if (Scxml::ScxmlState *state = table->findState(m_scxmlName)) {
+ if (state != m_state) {
+ m_state = state;
+ connect(m_state, SIGNAL(activeChanged(bool)), this, SIGNAL(activeChanged(bool)));
+ connect(m_state, SIGNAL(didEnter()), this, SIGNAL(didEnter()));
+ connect(m_state, SIGNAL(willExit()), this, SIGNAL(willExit()));
+ }
+ }
+ }
+
+ if (m_state == nullptr)
+ qmlInfo(this) << QStringLiteral("No state '%1' found.").arg(m_scxmlName);
+}
+
+bool State::isActive() const
+{
+ return m_state && m_state->active();
+}
+
+QString State::scxmlName() const
+{
+ return m_scxmlName;
+}
+
+void State::setScxmlName(const QString &scxmlName)
+{
+ if (m_scxmlName != scxmlName) {
+ m_scxmlName = scxmlName;
+ emit scxmlNameChanged();
+ }
+}
diff --git a/src/qml-module/state.h b/src/qml-module/state.h
new file mode 100644
index 0000000..b0581c7
--- /dev/null
+++ b/src/qml-module/state.h
@@ -0,0 +1,63 @@
+/****************************************************************************
+ **
+ ** 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 STATE_H
+#define STATE_H
+
+#include <QtQml/QQmlParserStatus>
+#include <QtQml/QQmlListProperty>
+
+namespace Scxml {
+class ScxmlState;
+}
+
+QT_BEGIN_NAMESPACE
+
+class StateMachine;
+class State: public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+ Q_PROPERTY(bool active READ isActive NOTIFY activeChanged)
+ Q_PROPERTY(QString scxmlName READ scxmlName WRITE setScxmlName NOTIFY scxmlNameChanged)
+
+public:
+ explicit State(StateMachine *parent = 0);
+
+ void classBegin() {}
+ void componentComplete();
+
+ bool isActive() const;
+
+ QString scxmlName() const;
+ void setScxmlName(const QString &scxmlName);
+
+Q_SIGNALS:
+ void activeChanged(bool active);
+ void scxmlNameChanged();
+ void didEnter();
+ void willExit();
+
+private:
+ QString m_scxmlName;
+ Scxml::ScxmlState *m_state = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qml-module/statemachine.cpp b/src/qml-module/statemachine.cpp
new file mode 100644
index 0000000..80d06d1
--- /dev/null
+++ b/src/qml-module/statemachine.cpp
@@ -0,0 +1,150 @@
+/****************************************************************************
+ **
+ ** 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 "state.h"
+#include "statemachine.h"
+
+#include <QScxmlLib/ecmascriptdatamodel.h>
+#include <QScxmlLib/scxmlstatetable.h>
+#include <QScxmlLib/scxmlparser.h>
+#include <QQmlContext>
+#include <QQmlEngine>
+#include <QQmlInfo>
+#include <QFile>
+
+static void append(QQmlListProperty<QObject> *prop, QObject *o)
+{
+ if (!o)
+ return;
+
+ if (State *state = qobject_cast<State *>(o)) {
+ state->setParent(prop->object);
+ static_cast<StateMachine::States *>(prop->data)->append(state);
+ emit static_cast<StateMachine *>(prop->object)->statesChanged();
+ } else {
+ qmlInfo(prop->object) << "StateMachine can only contain State items";
+ }
+}
+
+static int count(QQmlListProperty<QObject> *prop)
+{
+ return static_cast<StateMachine::States *>(prop->data)->count();
+}
+
+static QObject *at(QQmlListProperty<QObject> *prop, int index)
+{
+ return static_cast<StateMachine::States *>(prop->data)->at(index);
+}
+
+static void clear(QQmlListProperty<QObject> *prop)
+{
+ static_cast<StateMachine::States *>(prop->data)->clear();
+ emit static_cast<StateMachine *>(prop->object)->statesChanged();
+}
+
+StateMachine::StateMachine(QObject *parent)
+ : QObject(parent)
+{
+}
+
+void StateMachine::componentComplete()
+{
+ if (m_table == nullptr) {
+ qmlInfo(this) << "No state machine loaded.";
+ return;
+ }
+
+ m_table->start();
+}
+
+QQmlListProperty<QObject> StateMachine::states()
+{
+ return QQmlListProperty<QObject>(this, &m_states, append, count, at, clear);
+}
+
+Scxml::StateTable *StateMachine::stateMachine() const
+{
+ return m_table;
+}
+
+void StateMachine::setStateMachine(Scxml::StateTable *table)
+{
+ qDebug()<<"setting state machine to"<<table;
+ if (m_table == nullptr && table != nullptr) {
+ m_table = table;
+ m_table->init();
+ QQmlContext *context = QQmlEngine::contextForObject(parent());
+ if (Scxml::EcmaScriptDataModel *dataModel = m_table->dataModel()->asEcmaScriptDataModel())
+ dataModel->setEngine(context->engine());
+ } else if (m_table) {
+ qmlInfo(this) << "Can set the table only once";
+ }
+}
+
+QString StateMachine::filename()
+{
+ return m_filename;
+}
+
+void StateMachine::setFilename(const QString filename)
+{
+ QString oldFilename = m_filename;
+ if (m_table) {
+ delete m_table;
+ m_table = nullptr;
+ }
+
+ if (parse(filename)) {
+ m_filename = filename;
+ emit filenameChanged();
+ } else {
+ m_filename.clear();
+ if (!oldFilename.isEmpty()) {
+ emit filenameChanged();
+ }
+ }
+}
+
+bool StateMachine::parse(const QString &filename)
+{
+ QFile scxmlFile(filename);
+ if (!scxmlFile.open(QIODevice::ReadOnly)) {
+ qmlInfo(this) << QStringLiteral("ERROR: cannot open '%1' for reading!").arg(filename);
+ return false;
+ }
+
+ QXmlStreamReader xmlReader(&scxmlFile);
+ Scxml::ScxmlParser parser(&xmlReader);
+ parser.parse();
+ scxmlFile.close();
+ setStateMachine(parser.table());
+
+ if (parser.state() != Scxml::ScxmlParser::FinishedParsing || m_table == nullptr) {
+ qmlInfo(this) << QStringLiteral("Something went wrong while parsing '%1':").arg(filename) << endl;
+ foreach (const Scxml::ErrorMessage &msg, parser.errors()) {
+ qmlInfo(this) << msg.fileName << QStringLiteral(":") << msg.line
+ << QStringLiteral(":") << msg.column
+ << QStringLiteral(": ") << msg.severityString()
+ << QStringLiteral(": ") << msg.msg;
+ }
+
+ return false;
+ }
+
+ return true;
+}
diff --git a/src/qml-module/statemachine.h b/src/qml-module/statemachine.h
new file mode 100644
index 0000000..c35fd35
--- /dev/null
+++ b/src/qml-module/statemachine.h
@@ -0,0 +1,70 @@
+/****************************************************************************
+ **
+ ** 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 STATEMACHINE_H
+#define STATEMACHINE_H
+
+#include <QVector>
+#include <QQmlParserStatus>
+#include <QQmlListProperty>
+#include <QScxmlLib/scxmlstatetable.h>
+
+QT_BEGIN_NAMESPACE
+
+class State;
+class QQmlOpenMetaObject;
+class StateMachine: public QObject, public QQmlParserStatus
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlParserStatus)
+ Q_PROPERTY(QQmlListProperty<QObject> states READ states NOTIFY statesChanged DESIGNABLE false)
+ Q_PROPERTY(QString filename READ filename WRITE setFilename NOTIFY filenameChanged)
+ Q_PROPERTY(Scxml::StateTable* stateMachine READ stateMachine WRITE setStateMachine)
+
+ Q_CLASSINFO("DefaultProperty", "states")
+
+public:
+ typedef QVector<State *> States;
+ explicit StateMachine(QObject *parent = 0);
+
+ void classBegin() {}
+ void componentComplete();
+ QQmlListProperty<QObject> states();
+
+ Scxml::StateTable *stateMachine() const;
+ void setStateMachine(Scxml::StateTable *stateMachine);
+
+ QString filename();
+ void setFilename(const QString filename);
+
+Q_SIGNALS:
+ void statesChanged();
+ void filenameChanged();
+
+private:
+ bool parse(const QString &filename);
+
+private:
+ QString m_filename;
+ States m_states;
+ Scxml::StateTable *m_table = nullptr;
+};
+
+QT_END_NAMESPACE
+
+#endif
diff --git a/src/qscxmllib/datamodel.cpp b/src/qscxmllib/datamodel.cpp
index 329f097..7cba99c 100644
--- a/src/qscxmllib/datamodel.cpp
+++ b/src/qscxmllib/datamodel.cpp
@@ -34,3 +34,13 @@ StateTable *DataModel::table() const
{
return m_table;
}
+
+NullDataModel *DataModel::asNullDataModel()
+{
+ return nullptr;
+}
+
+EcmaScriptDataModel *DataModel::asEcmaScriptDataModel()
+{
+ return nullptr;
+}
diff --git a/src/qscxmllib/datamodel.h b/src/qscxmllib/datamodel.h
index 89e1138..05a9743 100644
--- a/src/qscxmllib/datamodel.h
+++ b/src/qscxmllib/datamodel.h
@@ -56,6 +56,8 @@ struct ForeachInfo {
typedef qint32 EvaluatorId;
enum { NoEvaluator = -1 };
+class NullDataModel;
+class EcmaScriptDataModel;
class SCXML_EXPORT DataModel
{
Q_DISABLE_COPY(DataModel)
@@ -82,6 +84,9 @@ public:
virtual void setStringProperty(const QString &name, const QString &value, const QString &context,
bool *ok) = 0;
+ virtual NullDataModel *asNullDataModel();
+ virtual EcmaScriptDataModel *asEcmaScriptDataModel();
+
private:
StateTable *m_table;
};
diff --git a/src/qscxmllib/ecmascriptdatamodel.cpp b/src/qscxmllib/ecmascriptdatamodel.cpp
index 452b551..0f0942f 100644
--- a/src/qscxmllib/ecmascriptdatamodel.cpp
+++ b/src/qscxmllib/ecmascriptdatamodel.cpp
@@ -176,7 +176,10 @@ public:
{ return q->table(); }
QJSEngine *engine() const
- { return q->engine(); }
+ { return jsEngine; }
+
+ void setEngine(QJSEngine *engine)
+ { jsEngine = engine; }
QString string(ExecutableContent::StringId id) const
{ return table()->tableData()->string(id); }
@@ -292,6 +295,7 @@ private: // Uses private API
private:
EcmaScriptDataModel *q;
+ QJSEngine *jsEngine;
QJSValue dataModel;
};
@@ -381,7 +385,7 @@ bool EcmaScriptDataModel::evaluateForeach(EvaluatorId id, bool *ok, std::functio
}
QString item = d->string(info.item);
- if (table()->engine()->evaluate(QStringLiteral("(function(){var %1 = 0})()").arg(item)).isError()) {
+ if (engine()->evaluate(QStringLiteral("(function(){var %1 = 0})()").arg(item)).isError()) {
table()->submitError("error.execution", QStringLiteral("invalid item '%1' in %2")
.arg(d->string(info.item), d->string(info.context)), sendid);
*ok = false;
@@ -431,7 +435,17 @@ void EcmaScriptDataModel::setStringProperty(const QString &name, const QString &
d->setProperty(name, QJSValue(value), context, ok);
}
+EcmaScriptDataModel *EcmaScriptDataModel::asEcmaScriptDataModel()
+{
+ return this;
+}
+
QJSEngine *EcmaScriptDataModel::engine() const
{
- return table()->engine();
+ return d->engine();
+}
+
+void EcmaScriptDataModel::setEngine(QJSEngine *engine)
+{
+ d->setEngine(engine);
}
diff --git a/src/qscxmllib/ecmascriptdatamodel.h b/src/qscxmllib/ecmascriptdatamodel.h
index 132ec89..2dd3412 100644
--- a/src/qscxmllib/ecmascriptdatamodel.h
+++ b/src/qscxmllib/ecmascriptdatamodel.h
@@ -49,7 +49,10 @@ public:
bool hasProperty(const QString &name) const Q_DECL_OVERRIDE;
void setStringProperty(const QString &name, const QString &value, const QString &context, bool *ok) Q_DECL_OVERRIDE;
+ virtual EcmaScriptDataModel *asEcmaScriptDataModel() Q_DECL_OVERRIDE;
+
QJSEngine *engine() const;
+ void setEngine(QJSEngine *engine);
private:
EcmaScriptDataModelPrivate *d;
diff --git a/src/qscxmllib/nulldatamodel.cpp b/src/qscxmllib/nulldatamodel.cpp
index 7ffd4c0..0eb0039 100644
--- a/src/qscxmllib/nulldatamodel.cpp
+++ b/src/qscxmllib/nulldatamodel.cpp
@@ -100,3 +100,8 @@ void NullDataModel::setStringProperty(const QString &name, const QString &value,
Q_UNUSED(ok);
Q_UNREACHABLE();
}
+
+NullDataModel *NullDataModel::asNullDataModel()
+{
+ return this;
+}
diff --git a/src/qscxmllib/nulldatamodel.h b/src/qscxmllib/nulldatamodel.h
index 16909e0..ef40d77 100644
--- a/src/qscxmllib/nulldatamodel.h
+++ b/src/qscxmllib/nulldatamodel.h
@@ -42,6 +42,8 @@ public:
QVariant property(const QString &name) const Q_DECL_OVERRIDE;
bool hasProperty(const QString &name) const Q_DECL_OVERRIDE;
void setStringProperty(const QString &name, const QString &value, const QString &context, bool *ok) Q_DECL_OVERRIDE;
+
+ virtual NullDataModel *asNullDataModel() Q_DECL_OVERRIDE;
};
} // Scxml namespace
diff --git a/src/qscxmllib/scxmlstatetable.cpp b/src/qscxmllib/scxmlstatetable.cpp
index 69ecde2..e1f8e1b 100644
--- a/src/qscxmllib/scxmlstatetable.cpp
+++ b/src/qscxmllib/scxmlstatetable.cpp
@@ -438,20 +438,6 @@ bool StateTable::init()
return res;
}
-QJSEngine *StateTable::engine() const
-{
- Q_D(const StateTable);
-
- return d->m_engine;
-}
-
-void StateTable::setEngine(QJSEngine *engine)
-{
- Q_D(StateTable);
-
- d->m_engine = engine;
-}
-
QString StateTable::name() const
{
Q_D(const StateTable);
@@ -938,10 +924,12 @@ void ScxmlState::onEntry(QEvent *event)
}
QState::onEntry(event);
table()->executionEngine()->execute(d->onEntryInstructions);
+ emit didEnter();
}
void ScxmlState::onExit(QEvent *event)
{
+ emit willExit();
QState::onExit(event);
table()->executionEngine()->execute(d->onExitInstructions);
}
diff --git a/src/qscxmllib/scxmlstatetable.h b/src/qscxmllib/scxmlstatetable.h
index 72be037..59824e1 100644
--- a/src/qscxmllib/scxmlstatetable.h
+++ b/src/qscxmllib/scxmlstatetable.h
@@ -106,8 +106,6 @@ public:
void doLog(const QString &label, const QString &msg);
virtual bool init();
- QJSEngine *engine() const;
- void setEngine(QJSEngine *engine);
QString name() const;
QStringList currentStates(bool compress = true);
@@ -237,6 +235,10 @@ public:
void setOnEntryInstructions(ExecutableContent::ContainerId instructions);
void setOnExitInstructions(ExecutableContent::ContainerId instructions);
+Q_SIGNALS:
+ void didEnter();
+ void willExit();
+
protected:
ScxmlState(QStatePrivate &dd, QState *parent = 0);
diff --git a/src/qscxmllib/scxmlstatetable_p.h b/src/qscxmllib/scxmlstatetable_p.h
index e702d0e..b4b6eb1 100644
--- a/src/qscxmllib/scxmlstatetable_p.h
+++ b/src/qscxmllib/scxmlstatetable_p.h
@@ -53,7 +53,6 @@ public: // StateTable data fields:
DataModel *m_dataModel = nullptr;
const int m_sessionId;
ExecutableContent::ContainerId m_initialSetup = ExecutableContent::NoInstruction;
- QJSEngine *m_engine = nullptr;
StateTable::BindingMethod m_dataBinding = StateTable::EarlyBinding;
ExecutableContent::ExecutionEngine *m_executionEngine = nullptr;
TableData *tableData = nullptr;
diff --git a/src/src.pro b/src/src.pro
index 66c8640..5a23ed5 100644
--- a/src/src.pro
+++ b/src/src.pro
@@ -7,3 +7,7 @@ SUBDIRS += \
qscxmlparse.depends = qscxmllib
qscxmlcpp.depends = qscxmllib
imports.depends = qscxmllib
+
+qtHaveModule(qml) {
+ SUBDIRS += qml-module
+}