From 1db438735f7a3033b8a3ce6ef2b36aee1d725197 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 30 Aug 2016 14:39:51 +0200 Subject: Replace runningSubStateMachines() with invokableServices() SCXML allows for different kinds of services, not only other state machines. We might add support for them in the future. From invoked state machines you can always get the actual state machine via the respective property. To make this easily accessible, we make the invoked services QObjects. Change-Id: Idd07783730bc98bded404dc2c2c3bd241180c1f4 Reviewed-by: Erik Verbruggen --- src/imports/scxmlstatemachine/invokedservices.cpp | 100 +++++++++++++++++++++ src/imports/scxmlstatemachine/invokedservices.h | 81 +++++++++++++++++ src/imports/scxmlstatemachine/plugin.cpp | 4 +- .../scxmlstatemachine/scxmlstatemachine.pro | 4 +- src/imports/scxmlstatemachine/substatemachines.cpp | 99 -------------------- src/imports/scxmlstatemachine/substatemachines.h | 81 ----------------- src/scxml/qscxmlinvokableservice.h | 10 ++- src/scxml/qscxmlstatemachine.cpp | 31 +++---- src/scxml/qscxmlstatemachine.h | 7 +- src/scxml/qscxmlstatemachine_p.h | 2 +- 10 files changed, 208 insertions(+), 211 deletions(-) create mode 100644 src/imports/scxmlstatemachine/invokedservices.cpp create mode 100644 src/imports/scxmlstatemachine/invokedservices.h delete mode 100644 src/imports/scxmlstatemachine/substatemachines.cpp delete mode 100644 src/imports/scxmlstatemachine/substatemachines.h (limited to 'src') diff --git a/src/imports/scxmlstatemachine/invokedservices.cpp b/src/imports/scxmlstatemachine/invokedservices.cpp new file mode 100644 index 0000000..8b4fd44 --- /dev/null +++ b/src/imports/scxmlstatemachine/invokedservices.cpp @@ -0,0 +1,100 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtScxml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "invokedservices.h" +#include + +QT_BEGIN_NAMESPACE + +QScxmlInvokedServices::QScxmlInvokedServices(QObject *parent) : QObject(parent) +{ +} + +QVariantMap QScxmlInvokedServices::children() +{ + QVariantMap ret; + if (m_stateMachine) { + const QVector children = m_stateMachine->invokedServices(); + for (QScxmlInvokableService *service : children) + ret.insertMulti(service->name(), QVariant::fromValue(service)); + } + return ret; +} + +void QScxmlInvokedServices::classBegin() +{ +} + +QScxmlStateMachine *QScxmlInvokedServices::stateMachine() const +{ + return m_stateMachine; +} + +void QScxmlInvokedServices::setStateMachine(QScxmlStateMachine *stateMachine) +{ + if (stateMachine != m_stateMachine) { + if (m_stateMachine) { + disconnect(m_stateMachine, &QScxmlStateMachine::invokedServicesChanged, + this, &QScxmlInvokedServices::childrenChanged); + } + m_stateMachine = stateMachine; + connect(m_stateMachine, &QScxmlStateMachine::invokedServicesChanged, + this, &QScxmlInvokedServices::childrenChanged); + emit stateMachineChanged(); + emit childrenChanged(); + } +} + +QQmlListProperty QScxmlInvokedServices::qmlChildren() +{ + return QQmlListProperty(this, m_qmlChildren); +} + + +void QScxmlInvokedServices::componentComplete() +{ + if (!m_stateMachine) { + if ((m_stateMachine = qobject_cast(parent()))) { + connect(m_stateMachine, &QScxmlStateMachine::invokedServicesChanged, + this, &QScxmlInvokedServices::childrenChanged); + } + } +} + +QT_END_NAMESPACE diff --git a/src/imports/scxmlstatemachine/invokedservices.h b/src/imports/scxmlstatemachine/invokedservices.h new file mode 100644 index 0000000..58d93ad --- /dev/null +++ b/src/imports/scxmlstatemachine/invokedservices.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtScxml module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef INVOKEDSERVICES_H +#define INVOKEDSERVICES_H + +#include +#include +#include + +QT_BEGIN_NAMESPACE + +class QScxmlInvokedServices : public QObject, public QQmlParserStatus +{ + Q_OBJECT + Q_PROPERTY(QScxmlStateMachine *stateMachine READ stateMachine WRITE setStateMachine + NOTIFY stateMachineChanged) + Q_PROPERTY(QVariantMap children READ children NOTIFY childrenChanged) + Q_PROPERTY(QQmlListProperty qmlChildren READ qmlChildren) + Q_INTERFACES(QQmlParserStatus) + Q_CLASSINFO("DefaultProperty", "qmlChildren") +public: + QScxmlInvokedServices(QObject *parent = 0); + QVariantMap children(); + + QScxmlStateMachine *stateMachine() const; + void setStateMachine(QScxmlStateMachine *stateMachine); + + QQmlListProperty qmlChildren(); + +Q_SIGNALS: + void childrenChanged(); + void stateMachineChanged(); + +private: + void classBegin() override; + void componentComplete() override; + + QScxmlStateMachine *m_stateMachine = 0; + QList m_qmlChildren; +}; + +QT_END_NAMESPACE + +#endif // INVOKEDSERVICES_H diff --git a/src/imports/scxmlstatemachine/plugin.cpp b/src/imports/scxmlstatemachine/plugin.cpp index 9357764..cd13f33 100644 --- a/src/imports/scxmlstatemachine/plugin.cpp +++ b/src/imports/scxmlstatemachine/plugin.cpp @@ -41,7 +41,7 @@ #include "eventconnection.h" #include "qscxmlevent.h" #include "statemachineextended.h" -#include "substatemachines.h" +#include "invokedservices.h" #include #include @@ -70,7 +70,7 @@ public: Q_UNUSED(qScxmlEventMetaTypeId) qmlRegisterType(uri, major, minor, "StateMachineLoader"); qmlRegisterType(uri, major, minor, "EventConnection"); - qmlRegisterType(uri, major, minor, "SubStateMachines"); + qmlRegisterType(uri, major, minor, "InvokedServices"); qmlRegisterExtendedUncreatableType( uri, major, minor, "QScxmlStateMachine", "Only created through derived types"); qmlProtectModule(uri, 1); diff --git a/src/imports/scxmlstatemachine/scxmlstatemachine.pro b/src/imports/scxmlstatemachine/scxmlstatemachine.pro index 7c94091..da8dc18 100644 --- a/src/imports/scxmlstatemachine/scxmlstatemachine.pro +++ b/src/imports/scxmlstatemachine/scxmlstatemachine.pro @@ -8,13 +8,13 @@ SOURCES = \ $$PWD/statemachineloader.cpp \ $$PWD/eventconnection.cpp \ $$PWD/statemachineextended.cpp \ - $$PWD/substatemachines.cpp + $$PWD/invokedservices.cpp HEADERS = \ $$PWD/statemachineloader.h \ $$PWD/eventconnection.h \ $$PWD/statemachineextended.h \ - $$PWD/substatemachines.h + $$PWD/invokedservices.h load(qml_plugin) diff --git a/src/imports/scxmlstatemachine/substatemachines.cpp b/src/imports/scxmlstatemachine/substatemachines.cpp deleted file mode 100644 index 7feac92..0000000 --- a/src/imports/scxmlstatemachine/substatemachines.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtScxml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "substatemachines.h" - -QT_BEGIN_NAMESPACE - -QScxmlSubStateMachines::QScxmlSubStateMachines(QObject *parent) : QObject(parent) -{ -} - -QVariantMap QScxmlSubStateMachines::children() -{ - QVariantMap ret; - if (m_stateMachine) { - const QVector children = m_stateMachine->runningSubStateMachines(); - for (QScxmlStateMachine *stateMachine : children) - ret.insertMulti(stateMachine->name(), QVariant::fromValue(stateMachine)); - } - return ret; -} - -void QScxmlSubStateMachines::classBegin() -{ -} - -QScxmlStateMachine *QScxmlSubStateMachines::stateMachine() const -{ - return m_stateMachine; -} - -void QScxmlSubStateMachines::setStateMachine(QScxmlStateMachine *stateMachine) -{ - if (stateMachine != m_stateMachine) { - if (m_stateMachine) { - disconnect(m_stateMachine, &QScxmlStateMachine::runningSubStateMachinesChanged, - this, &QScxmlSubStateMachines::childrenChanged); - } - m_stateMachine = stateMachine; - connect(m_stateMachine, &QScxmlStateMachine::runningSubStateMachinesChanged, - this, &QScxmlSubStateMachines::childrenChanged); - emit stateMachineChanged(); - emit childrenChanged(); - } -} - -QQmlListProperty QScxmlSubStateMachines::qmlChildren() -{ - return QQmlListProperty(this, m_qmlChildren); -} - - -void QScxmlSubStateMachines::componentComplete() -{ - if (!m_stateMachine) { - if ((m_stateMachine = qobject_cast(parent()))) { - connect(m_stateMachine, &QScxmlStateMachine::runningSubStateMachinesChanged, - this, &QScxmlSubStateMachines::childrenChanged); - } - } -} - -QT_END_NAMESPACE diff --git a/src/imports/scxmlstatemachine/substatemachines.h b/src/imports/scxmlstatemachine/substatemachines.h deleted file mode 100644 index 064f37a..0000000 --- a/src/imports/scxmlstatemachine/substatemachines.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtScxml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef SUBSTATEMACHINES_H -#define SUBSTATEMACHINES_H - -#include -#include -#include - -QT_BEGIN_NAMESPACE - -class QScxmlSubStateMachines : public QObject, public QQmlParserStatus -{ - Q_OBJECT - Q_PROPERTY(QScxmlStateMachine *stateMachine READ stateMachine WRITE setStateMachine - NOTIFY stateMachineChanged) - Q_PROPERTY(QVariantMap children READ children NOTIFY childrenChanged) - Q_PROPERTY(QQmlListProperty qmlChildren READ qmlChildren) - Q_INTERFACES(QQmlParserStatus) - Q_CLASSINFO("DefaultProperty", "qmlChildren") -public: - QScxmlSubStateMachines(QObject *parent = 0); - QVariantMap children(); - - QScxmlStateMachine *stateMachine() const; - void setStateMachine(QScxmlStateMachine *stateMachine); - - QQmlListProperty qmlChildren(); - -Q_SIGNALS: - void childrenChanged(); - void stateMachineChanged(); - -private: - void classBegin() override; - void componentComplete() override; - - QScxmlStateMachine *m_stateMachine = 0; - QList m_qmlChildren; -}; - -QT_END_NAMESPACE - -#endif // SUBSTATEMACHINES_H diff --git a/src/scxml/qscxmlinvokableservice.h b/src/scxml/qscxmlinvokableservice.h index 8323fe2..a17fdde 100644 --- a/src/scxml/qscxmlinvokableservice.h +++ b/src/scxml/qscxmlinvokableservice.h @@ -51,8 +51,14 @@ class QScxmlEvent; class QScxmlStateMachine; class QScxmlInvokableServiceFactory; -class Q_SCXML_EXPORT QScxmlInvokableService +class Q_SCXML_EXPORT QScxmlInvokableService : public QObject { + Q_OBJECT + Q_PROPERTY(QScxmlStateMachine *parentStateMachine READ parentStateMachine CONSTANT) + Q_PROPERTY(bool autoforward READ autoforward CONSTANT) + Q_PROPERTY(QString id READ id CONSTANT) + Q_PROPERTY(QString name READ name CONSTANT) + public: QScxmlInvokableService(QScxmlInvokableServiceFactory *service, QScxmlStateMachine *parentStateMachine); virtual ~QScxmlInvokableService(); @@ -105,6 +111,8 @@ private: class Q_SCXML_EXPORT QScxmlInvokableScxml: public QScxmlInvokableService { + Q_OBJECT + Q_PROPERTY(QScxmlStateMachine *stateMachine READ stateMachine CONSTANT) public: QScxmlInvokableScxml(QScxmlInvokableServiceFactory *service, QScxmlStateMachine *stateMachine, diff --git a/src/scxml/qscxmlstatemachine.cpp b/src/scxml/qscxmlstatemachine.cpp index 7dae1e3..ab03ad4 100644 --- a/src/scxml/qscxmlstatemachine.cpp +++ b/src/scxml/qscxmlstatemachine.cpp @@ -332,7 +332,7 @@ void QScxmlStateMachinePrivate::addService(int invokingState) m_invokedServices[size_t(id)] = { invokingState, service, serviceName }; service->start(); } - emitRunningSubStateMachinesChanged(); + emitInvokedServicesChanged(); } void QScxmlStateMachinePrivate::removeService(int invokingState) @@ -349,7 +349,7 @@ void QScxmlStateMachinePrivate::removeService(int invokingState) delete service; } } - emitRunningSubStateMachinesChanged(); + emitInvokedServicesChanged(); } QScxmlInvokableServiceFactory *QScxmlStateMachinePrivate::serviceFactory(int id) @@ -576,10 +576,10 @@ void QScxmlStateMachinePrivate::emitStateActive(int stateIndex, bool active) QMetaObject::activate(q, m_metaObject, stateIndex, args); } -void QScxmlStateMachinePrivate::emitRunningSubStateMachinesChanged() +void QScxmlStateMachinePrivate::emitInvokedServicesChanged() { Q_Q(QScxmlStateMachine); - emit q->runningSubStateMachinesChanged(q->runningSubStateMachines()); + emit q->invokedServicesChanged(q->invokedServices()); } QStringList QScxmlStateMachinePrivate::stateNames(const std::vector &stateIndexes) const @@ -1819,20 +1819,19 @@ bool QScxmlStateMachine::isDispatchableTarget(const QString &target) const } /*! - \property QScxmlStateMachine::runningSubStateMachines - \brief A list of running sub state machines that were invoked from the main + \property QScxmlStateMachine::invokedServices + \brief A list of SCXML services that were invoked from the main state machine (possibly recursively). */ -QVector QScxmlStateMachine::runningSubStateMachines() const +QVector QScxmlStateMachine::invokedServices() const { Q_D(const QScxmlStateMachine); - QVector result; + QVector result; for (int i = 0, ei = int(d->m_invokedServices.size()); i != ei; ++i) { - auto sub = runningSubStateMachine(i); - if (sub) - result.append(sub); + if (auto service = d->m_invokedServices[size_t(i)].service) + result.append(service); } return result; } @@ -1911,14 +1910,4 @@ bool QScxmlStateMachine::isActive(int stateIndex) const return d->m_configuration.contains(stateIndex); } -QScxmlStateMachine *QScxmlStateMachine::runningSubStateMachine(int index) const -{ - Q_D(const QScxmlStateMachine); - auto invokedService = d->m_invokedServices[size_t(index)].service; - if (auto scxmlService = dynamic_cast(invokedService)) - return scxmlService->stateMachine(); - else - return nullptr; -} - QT_END_NAMESPACE diff --git a/src/scxml/qscxmlstatemachine.h b/src/scxml/qscxmlstatemachine.h index c436b0d..b80fcae 100644 --- a/src/scxml/qscxmlstatemachine.h +++ b/src/scxml/qscxmlstatemachine.h @@ -70,7 +70,7 @@ class Q_SCXML_EXPORT QScxmlStateMachine: public QObject Q_PROPERTY(bool initialized READ isInitialized NOTIFY initializedChanged) Q_PROPERTY(QScxmlDataModel *dataModel READ dataModel WRITE setDataModel NOTIFY dataModelChanged) Q_PROPERTY(QVariantMap initialValues READ initialValues WRITE setInitialValues NOTIFY initialValuesChanged) - Q_PROPERTY(QVector runningSubStateMachines READ runningSubStateMachines NOTIFY runningSubStateMachinesChanged) + Q_PROPERTY(QVector invokedServices READ invokedServices NOTIFY invokedServicesChanged) Q_PROPERTY(QString sessionId READ sessionId CONSTANT) Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(bool invoked READ isInvoked CONSTANT) @@ -235,11 +235,11 @@ public: Q_INVOKABLE bool isDispatchableTarget(const QString &target) const; - QVector runningSubStateMachines() const; + QVector invokedServices() const; Q_SIGNALS: void runningChanged(bool running); - void runningSubStateMachinesChanged(const QVector &runningMachines); + void invokedServicesChanged(const QVector &invokedServices); void log(const QString &label, const QString &msg); void reachedStableState(); void finished(); @@ -262,7 +262,6 @@ protected: // methods for friends: #ifndef Q_QDOC // The methods below are used by the compiled state machines. bool isActive(int stateIndex) const; - QScxmlStateMachine *runningSubStateMachine(int index) const; QScxmlTableData *tableData() const; void setTableData(QScxmlTableData *tableData); #endif // Q_QDOC diff --git a/src/scxml/qscxmlstatemachine_p.h b/src/scxml/qscxmlstatemachine_p.h index a2a52b9..3ca0688 100644 --- a/src/scxml/qscxmlstatemachine_p.h +++ b/src/scxml/qscxmlstatemachine_p.h @@ -261,7 +261,7 @@ public: void resetEvent(); void emitStateActive(int stateIndex, bool active); - void emitRunningSubStateMachinesChanged(); + void emitInvokedServicesChanged(); void emitSignalForEvent(int signalIndex, const QVariant &data); private: -- cgit v1.2.3