From 7cb37856848f4ead8030d3aa660c1c244ccecdaa Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 29 Nov 2016 10:16:58 +0100 Subject: Drop indirect access to tableData from various data models As we need to access it from everywhere, we can as well make it a public property of the state machine. This saves us the tableData() method on QScxmlDataModel and some back and forth between d and q pointers. We can also drop the indirection for accessing the state machine in most cases, as that is just a public member of QScxmlDataModelPrivate. Change-Id: I4aa0cec7d4664aec7b1581de531cdb1554ca5342 Reviewed-by: Erik Verbruggen --- src/scxml/qscxmldatamodel.cpp | 5 --- src/scxml/qscxmldatamodel.h | 3 -- src/scxml/qscxmlecmascriptdatamodel.cpp | 38 +++++++++----------- src/scxml/qscxmlnulldatamodel.cpp | 6 ++-- src/scxml/qscxmlstatemachine.cpp | 61 +++++++++++++++++---------------- src/scxml/qscxmlstatemachine.h | 7 ++-- 6 files changed, 55 insertions(+), 65 deletions(-) diff --git a/src/scxml/qscxmldatamodel.cpp b/src/scxml/qscxmldatamodel.cpp index 6e6d62b..570289d 100644 --- a/src/scxml/qscxmldatamodel.cpp +++ b/src/scxml/qscxmldatamodel.cpp @@ -123,11 +123,6 @@ QScxmlStateMachine *QScxmlDataModel::stateMachine() const return d->m_stateMachine; } -QScxmlTableData *QScxmlDataModel::tableData() const -{ - return stateMachine()->tableData(); -} - QScxmlDataModel *QScxmlDataModelPrivate::instantiateDataModel(DocumentModel::Scxml::DataModelType type) { QScxmlDataModel *dataModel = Q_NULLPTR; diff --git a/src/scxml/qscxmldatamodel.h b/src/scxml/qscxmldatamodel.h index 3d19685..e16f2f7 100644 --- a/src/scxml/qscxmldatamodel.h +++ b/src/scxml/qscxmldatamodel.h @@ -96,9 +96,6 @@ Q_SIGNALS: protected: explicit QScxmlDataModel(QScxmlDataModelPrivate &dd, QObject *parent = nullptr); -#ifndef Q_QDOC - QScxmlTableData *tableData() const; -#endif // Q_QDOC }; QT_END_NAMESPACE diff --git a/src/scxml/qscxmlecmascriptdatamodel.cpp b/src/scxml/qscxmlecmascriptdatamodel.cpp index 5532a9b..869afec 100644 --- a/src/scxml/qscxmlecmascriptdatamodel.cpp +++ b/src/scxml/qscxmlecmascriptdatamodel.cpp @@ -121,25 +121,26 @@ public: QJSEngine *engine = assertEngine(); dataModel = engine->globalObject(); - qCDebug(qscxmlLog) << stateMachine() << "initializing the datamodel"; + qCDebug(qscxmlLog) << m_stateMachine << "initializing the datamodel"; setupSystemVariables(); } void setupSystemVariables() { setReadonlyProperty(&dataModel, QStringLiteral("_sessionid"), - stateMachine()->sessionId()); + m_stateMachine->sessionId()); - setReadonlyProperty(&dataModel, QStringLiteral("_name"), stateMachine()->name()); + setReadonlyProperty(&dataModel, QStringLiteral("_name"), m_stateMachine->name()); QJSEngine *engine = assertEngine(); auto scxml = engine->newObject(); - scxml.setProperty(QStringLiteral("location"), QStringLiteral("#_scxml_%1").arg(stateMachine()->sessionId())); + scxml.setProperty(QStringLiteral("location"), QStringLiteral("#_scxml_%1") + .arg(m_stateMachine->sessionId())); auto ioProcs = engine->newObject(); setReadonlyProperty(&ioProcs, QStringLiteral("scxml"), scxml); setReadonlyProperty(&dataModel, QStringLiteral("_ioprocessors"), ioProcs); - auto platformVars = QScxmlPlatformProperties::create(engine, stateMachine()); + auto platformVars = QScxmlPlatformProperties::create(engine, m_stateMachine); dataModel.setProperty(QStringLiteral("_x"), platformVars->jsValue()); dataModel.setProperty(QStringLiteral("In"), engine->evaluate( @@ -204,12 +205,6 @@ public: return engine->toScriptValue(data); } - QScxmlStateMachine *stateMachine() const - { - Q_Q(const QScxmlEcmaScriptDataModel); - return q->stateMachine(); - } - QJSEngine *assertEngine() { if (!jsEngine) { @@ -230,8 +225,7 @@ public: QString string(StringId id) const { - Q_Q(const QScxmlEcmaScriptDataModel); - return q->tableData()->string(id); + return m_stateMachine->tableData()->string(id); } bool hasProperty(const QString &name) const @@ -265,7 +259,7 @@ public: void submitError(const QString &type, const QString &msg, const QString &sendid = QString()) { - QScxmlStateMachinePrivate::get(stateMachine())->submitError(type, msg, sendid); + QScxmlStateMachinePrivate::get(m_stateMachine)->submitError(type, msg, sendid); } public: @@ -381,7 +375,7 @@ bool QScxmlEcmaScriptDataModel::setup(const QVariantMap &initialDataValues) bool ok = true; QJSValue undefined(QJSValue::UndefinedValue); // See B.2.1, and test456. int count; - StringId *names = tableData()->dataNames(&count); + StringId *names = d->m_stateMachine->tableData()->dataNames(&count); for (int i = 0; i < count; ++i) { auto name = d->string(names[i]); QJSValue v = undefined; @@ -402,7 +396,7 @@ bool QScxmlEcmaScriptDataModel::setup(const QVariantMap &initialDataValues) QString QScxmlEcmaScriptDataModel::evaluateToString(EvaluatorId id, bool *ok) { Q_D(QScxmlEcmaScriptDataModel); - const EvaluatorInfo &info = tableData()->evaluatorInfo(id); + const EvaluatorInfo &info = d->m_stateMachine->tableData()->evaluatorInfo(id); return d->evalStr(d->string(info.expr), d->string(info.context), ok); } @@ -410,7 +404,7 @@ QString QScxmlEcmaScriptDataModel::evaluateToString(EvaluatorId id, bool *ok) bool QScxmlEcmaScriptDataModel::evaluateToBool(EvaluatorId id, bool *ok) { Q_D(QScxmlEcmaScriptDataModel); - const EvaluatorInfo &info = tableData()->evaluatorInfo(id); + const EvaluatorInfo &info = d->m_stateMachine->tableData()->evaluatorInfo(id); return d->evalBool(d->string(info.expr), d->string(info.context), ok); } @@ -418,7 +412,7 @@ bool QScxmlEcmaScriptDataModel::evaluateToBool(EvaluatorId id, bool *ok) QVariant QScxmlEcmaScriptDataModel::evaluateToVariant(EvaluatorId id, bool *ok) { Q_D(QScxmlEcmaScriptDataModel); - const EvaluatorInfo &info = tableData()->evaluatorInfo(id); + const EvaluatorInfo &info = d->m_stateMachine->tableData()->evaluatorInfo(id); return d->evalJSValue(d->string(info.expr), d->string(info.context), ok).toVariant(); } @@ -426,7 +420,7 @@ QVariant QScxmlEcmaScriptDataModel::evaluateToVariant(EvaluatorId id, bool *ok) void QScxmlEcmaScriptDataModel::evaluateToVoid(EvaluatorId id, bool *ok) { Q_D(QScxmlEcmaScriptDataModel); - const EvaluatorInfo &info = tableData()->evaluatorInfo(id); + const EvaluatorInfo &info = d->m_stateMachine->tableData()->evaluatorInfo(id); d->eval(d->string(info.expr), d->string(info.context), ok); } @@ -436,7 +430,7 @@ void QScxmlEcmaScriptDataModel::evaluateAssignment(EvaluatorId id, bool *ok) Q_D(QScxmlEcmaScriptDataModel); Q_ASSERT(ok); - const AssignmentInfo &info = tableData()->assignmentInfo(id); + const AssignmentInfo &info = d->m_stateMachine->tableData()->assignmentInfo(id); QString dest = d->string(info.dest); @@ -454,7 +448,7 @@ void QScxmlEcmaScriptDataModel::evaluateAssignment(EvaluatorId id, bool *ok) void QScxmlEcmaScriptDataModel::evaluateInitialization(EvaluatorId id, bool *ok) { Q_D(QScxmlEcmaScriptDataModel); - const AssignmentInfo &info = tableData()->assignmentInfo(id); + const AssignmentInfo &info = d->m_stateMachine->tableData()->assignmentInfo(id); QString dest = d->string(info.dest); if (d->initialDataNames.contains(dest)) { *ok = true; // silently ignore the tag @@ -469,7 +463,7 @@ void QScxmlEcmaScriptDataModel::evaluateForeach(EvaluatorId id, bool *ok, Foreac Q_D(QScxmlEcmaScriptDataModel); Q_ASSERT(ok); Q_ASSERT(body); - const ForeachInfo &info = tableData()->foreachInfo(id); + const ForeachInfo &info = d->m_stateMachine->tableData()->foreachInfo(id); QJSValue jsArray = d->property(d->string(info.array)); if (!jsArray.isArray()) { diff --git a/src/scxml/qscxmlnulldatamodel.cpp b/src/scxml/qscxmlnulldatamodel.cpp index 35f1b91..d7b64d0 100644 --- a/src/scxml/qscxmlnulldatamodel.cpp +++ b/src/scxml/qscxmlnulldatamodel.cpp @@ -84,8 +84,7 @@ public: ResolvedEvaluatorInfo prepare(QScxmlExecutableContent::EvaluatorId id) { - Q_Q(QScxmlNullDataModel); - auto td = q->tableData(); + auto td = m_stateMachine->tableData(); const QScxmlExecutableContent::EvaluatorInfo &info = td->evaluatorInfo(id); QString expr = td->string(info.expr); for (int i = 0; i < expr.size(); ) { @@ -152,10 +151,11 @@ bool QScxmlNullDataModel::setup(const QVariantMap &initialDataValues) QString QScxmlNullDataModel::evaluateToString(QScxmlExecutableContent::EvaluatorId id, bool *ok) { + Q_D(QScxmlNullDataModel); // We do implement this, because is allowed in the Null data model, // and has an expr attribute that needs "evaluation" for it to generate the log message. *ok = true; - auto td = tableData(); + auto td = d->m_stateMachine->tableData(); const QScxmlExecutableContent::EvaluatorInfo &info = td->evaluatorInfo(id); return td->string(info.expr); } diff --git a/src/scxml/qscxmlstatemachine.cpp b/src/scxml/qscxmlstatemachine.cpp index 1397b71..d71755b 100644 --- a/src/scxml/qscxmlstatemachine.cpp +++ b/src/scxml/qscxmlstatemachine.cpp @@ -1541,6 +1541,14 @@ QScxmlStateMachine::QScxmlStateMachine(QScxmlStateMachinePrivate &dd, QObject *p \brief The loader that is currently used to resolve and load URIs for the state machine. */ +/*! + \property QScxmlStateMachine::tableData + + This is used when generating C++ from an SCXML file. The class implementing + the state machine will use this property to assign the generated table + data. The state machine does not assume ownership of the table data. + */ + QString QScxmlStateMachine::sessionId() const { Q_D(const QScxmlStateMachine); @@ -1611,13 +1619,6 @@ QScxmlCompiler::Loader *QScxmlStateMachine::loader() const return d->m_loader; } -/*! - * \internal - * - * This is used internally in order to execute the executable content. - * - * \return the data tables used by the state machine. - */ QScxmlTableData *QScxmlStateMachine::tableData() const { Q_D(const QScxmlStateMachine); @@ -1625,36 +1626,36 @@ QScxmlTableData *QScxmlStateMachine::tableData() const return d->m_tableData; } -/*! - * \internal - * This is used when generating C++ from an SCXML file. The class implementing the - * state machine will use this method to pass in the table data (which is also generated). - * - * \return the data tables used by the state machine. - */ void QScxmlStateMachine::setTableData(QScxmlTableData *tableData) { Q_D(QScxmlStateMachine); - Q_ASSERT(tableData); + + if (d->m_tableData == tableData) + return; d->m_tableData = tableData; - d->m_stateTable = reinterpret_cast( - tableData->stateMachineTable()); - if (objectName().isEmpty()) { - setObjectName(tableData->name()); - } - if (d->m_stateTable->maxServiceId != QScxmlExecutableContent::StateTable::InvalidIndex) { - const size_t serviceCount = size_t(d->m_stateTable->maxServiceId + 1); - d->m_invokedServices.resize(serviceCount, { -1, nullptr, QString() }); - d->m_cachedFactories.resize(serviceCount, nullptr); + if (tableData) { + d->m_stateTable = reinterpret_cast( + tableData->stateMachineTable()); + if (objectName().isEmpty()) { + setObjectName(tableData->name()); + } + if (d->m_stateTable->maxServiceId != QScxmlExecutableContent::StateTable::InvalidIndex) { + const size_t serviceCount = size_t(d->m_stateTable->maxServiceId + 1); + d->m_invokedServices.resize(serviceCount, { -1, nullptr, QString() }); + d->m_cachedFactories.resize(serviceCount, nullptr); + } + + if (d->m_stateTable->version != Q_QSCXMLC_OUTPUT_REVISION) { + qFatal("Cannot mix incompatible state table (version 0x%x) with this library " + "(version 0x%x)", d->m_stateTable->version, Q_QSCXMLC_OUTPUT_REVISION); + } + Q_ASSERT(tableData->stateMachineTable()[d->m_stateTable->arrayOffset + + d->m_stateTable->arraySize] + == QScxmlExecutableContent::StateTable::terminator); } - if (d->m_stateTable->version != Q_QSCXMLC_OUTPUT_REVISION) - qFatal("Cannot mix incompatible state table (version 0x%x) with this library (version 0x%x)", - d->m_stateTable->version, Q_QSCXMLC_OUTPUT_REVISION); - Q_ASSERT(tableData->stateMachineTable()[d->m_stateTable->arrayOffset + - d->m_stateTable->arraySize] - == QScxmlExecutableContent::StateTable::terminator); + emit tableDataChanged(tableData); } /*! diff --git a/src/scxml/qscxmlstatemachine.h b/src/scxml/qscxmlstatemachine.h index b5837db..da8de50 100644 --- a/src/scxml/qscxmlstatemachine.h +++ b/src/scxml/qscxmlstatemachine.h @@ -75,6 +75,7 @@ class Q_SCXML_EXPORT QScxmlStateMachine: public QObject Q_PROPERTY(bool invoked READ isInvoked CONSTANT) Q_PROPERTY(QVector parseErrors READ parseErrors CONSTANT) Q_PROPERTY(QScxmlCompiler::Loader *loader READ loader WRITE setLoader NOTIFY loaderChanged) + Q_PROPERTY(QScxmlTableData *tableData READ tableData WRITE setTableData NOTIFY tableDataChanged) protected: #ifndef Q_QDOC @@ -314,6 +315,9 @@ public: QVector invokedServices() const; + QScxmlTableData *tableData() const; + void setTableData(QScxmlTableData *tableData); + Q_SIGNALS: void runningChanged(bool running); void invokedServicesChanged(const QVector &invokedServices); @@ -324,6 +328,7 @@ Q_SIGNALS: void initialValuesChanged(const QVariantMap &initialValues); void initializedChanged(bool initialized); void loaderChanged(QScxmlCompiler::Loader *loader); + void tableDataChanged(QScxmlTableData *tableData); public Q_SLOTS: void start(); @@ -339,8 +344,6 @@ protected: // methods for friends: #ifndef Q_QDOC // The methods below are used by the compiled state machines. bool isActive(int stateIndex) const; - QScxmlTableData *tableData() const; - void setTableData(QScxmlTableData *tableData); #endif // Q_QDOC private: -- cgit v1.2.3