diff options
author | Dominik Holland <dominik.holland@pelagicore.com> | 2018-10-12 14:07:27 +0200 |
---|---|---|
committer | Dominik Holland <dominik.holland@pelagicore.com> | 2018-10-29 10:47:49 +0000 |
commit | 3c44b7c2e68bb8df12e7317c3e094732019cba2b (patch) | |
tree | e0519bb6f46d87554ee874695e2d48833e4eb6bd /src | |
parent | 5b1c4b033d0d08782cbafcf7fba9eef07f0d430d (diff) | |
download | qtivi-3c44b7c2e68bb8df12e7317c3e094732019cba2b.tar.gz |
Refactor the simulation_backend for zoned interfaces
The backend now provides all properties as Q_PROPERTY independent on
whether they are zoned or not.
In addition all properties can also be part of a zone. All zones are
provided to the QIviSimulationEngine using the zones property.
Removed all boundary checks from the autogenerated C++ code. These
will be added later again as part of the autogenerated QML code instead.
Task-number: AUTOSUITE-629
Change-Id: I0bed939e5cdf8fbce9a09ebf1647b58ba8506428
Reviewed-by: Robert Griebl <robert.griebl@pelagicore.com>
Diffstat (limited to 'src')
6 files changed, 146 insertions, 166 deletions
diff --git a/src/plugins/ivivehiclefunctions/qiviconcretewindowcontrolbackend.cpp b/src/plugins/ivivehiclefunctions/qiviconcretewindowcontrolbackend.cpp index 9c0c165..f32f4d9 100644 --- a/src/plugins/ivivehiclefunctions/qiviconcretewindowcontrolbackend.cpp +++ b/src/plugins/ivivehiclefunctions/qiviconcretewindowcontrolbackend.cpp @@ -133,9 +133,9 @@ QIviConcreteWindowControlBackend::~QIviConcreteWindowControlBackend() void QIviConcreteWindowControlBackend::setBlindMode(QtIviVehicleFunctionsModule::BlindMode blindMode, const QString &zone) { - if (!m_zoneMap.contains(zone)) + if (!availableZones().contains(zone)) return; - if (m_zoneMap[zone].blindMode == blindMode) + if (zoneAt(zone)->blindMode() == blindMode) return; if (blindMode == QtIviVehicleFunctionsModule::BlindOpen) @@ -148,10 +148,10 @@ void QIviConcreteWindowControlBackend::setBlindMode(QtIviVehicleFunctionsModule: QIviPendingReply<void> QIviConcreteWindowControlBackend::open(const QString &zone) { - if (!m_zoneMap.contains(zone)) + if (!availableZones().contains(zone)) return QIviPendingReply<void>::createFailedReply(); - if (m_zoneMap[zone].state == QtIviVehicleFunctionsModule::Open) + if (zoneAt(zone)->state() == QtIviVehicleFunctionsModule::Open) return QIviPendingReply<void>::createFailedReply(); qWarning() << "SIMULATION open Window:" << zone; @@ -163,10 +163,10 @@ QIviPendingReply<void> QIviConcreteWindowControlBackend::open(const QString &zon QIviPendingReply<void> QIviConcreteWindowControlBackend::close(const QString &zone) { - if (!m_zoneMap.contains(zone)) + if (!availableZones().contains(zone)) return QIviPendingReply<void>::createFailedReply(); - if (m_zoneMap[zone].state == QtIviVehicleFunctionsModule::Closed) + if (zoneAt(zone)->state() == QtIviVehicleFunctionsModule::Closed) return QIviPendingReply<void>::createFailedReply(); qWarning() << "SIMULATION close Window:" << zone; @@ -178,31 +178,31 @@ QIviPendingReply<void> QIviConcreteWindowControlBackend::close(const QString &zo QtIviVehicleFunctionsModule::WindowState QIviConcreteWindowControlBackend::windowState(QString zone) { - Q_ASSERT(m_zoneMap.contains(zone)); - return m_zoneMap[zone].state; + Q_ASSERT(availableZones().contains(zone)); + return zoneAt(zone)->state(); } void QIviConcreteWindowControlBackend::setWindowState(QtIviVehicleFunctionsModule::WindowState state, const QString &zone) { - if (m_zoneMap[zone].state == state) + if (zoneAt(zone)->state() == state) return; qWarning() << "SIMULATION window state for Zone" << zone << "changed to" << state; - m_zoneMap[zone].state = state; + zoneAt(zone)->setState(state); emit stateChanged(state, zone); } QtIviVehicleFunctionsModule::WindowState QIviConcreteWindowControlBackend::blindState(QString zone) { - Q_ASSERT(m_zoneMap.contains(zone)); - return m_zoneMap[zone].blindState; + Q_ASSERT(availableZones().contains(zone)); + return zoneAt(zone)->blindState(); } void QIviConcreteWindowControlBackend::setBlindState(QtIviVehicleFunctionsModule::WindowState state, const QString &zone) { - if (m_zoneMap[zone].blindState == state) + if (zoneAt(zone)->blindState() == state) return; qWarning() << "SIMULATION blind state for Zone" << zone << "changed to" << state; - m_zoneMap[zone].blindState = state; + zoneAt(zone)->setBlindState(state); emit blindStateChanged(state, zone); } diff --git a/src/tools/ivigenerator/ivigenerator.pro b/src/tools/ivigenerator/ivigenerator.pro index 960235a..1690b83 100644 --- a/src/tools/ivigenerator/ivigenerator.pro +++ b/src/tools/ivigenerator/ivigenerator.pro @@ -35,7 +35,6 @@ templates_frontend.path = $$[QT_HOST_BINS]/ivigenerator/templates_frontend templates_backend_simulator.files += \ templates_backend_simulator/backend.cpp.tpl \ templates_backend_simulator/backend.h.tpl \ - templates_backend_simulator/backend_range.cpp.tpl \ templates_backend_simulator/pagingmodel.h.tpl \ templates_backend_simulator/pagingmodel.cpp.tpl \ templates_backend_simulator/plugin.cpp.tpl \ diff --git a/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl b/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl index b91dbfa..8dbe5d7 100644 --- a/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl +++ b/src/tools/ivigenerator/templates_backend_simulator/backend.cpp.tpl @@ -40,6 +40,7 @@ {% import 'qtivi_macros.j2' as ivi %} {% include "generated_comment.cpp.tpl" %} {% set class = '{0}Backend'.format(interface) %} +{% set zone_class = '{0}Zone'.format(interface) %} {% set interface_zoned = interface.tags.config and interface.tags.config.zoned %} #include "{{class|lower}}.h" @@ -58,6 +59,38 @@ QT_BEGIN_NAMESPACE +{% if interface_zoned %} +{{zone_class}}::{{zone_class}}(const QString &zone, {{class}}Interface *parent) + : QObject(parent) + , m_parent(parent) + , m_zone(zone) +{% for property in interface.properties %} +{% if not property.type.is_model %} + , m_{{ property }}({{property|default_value}}) +{% endif %} +{% endfor %} +{ +} + +{% for property in interface.properties %} +{{ivi.prop_getter(property, zone_class, model_interface = true)}} +{ + return m_{{property}}; +} +{% endfor %} + +{% for property in interface.properties %} +{{ivi.prop_setter(property, zone_class, model_interface = true)}} +{ + if (m_{{property}} == {{property}}) + return; + m_{{property}} = {{property}}; + emit {{property}}Changed({{property}}); + emit m_parent->{{property}}Changed({{property}}, m_zone); +} +{% endfor %} +{% endif %} + /*! \class {{class}} \inmodule {{module}} @@ -71,18 +104,18 @@ QT_BEGIN_NAMESPACE {{class}}::{{class}}(QIviSimulationEngine *engine, QObject *parent) : {{class}}Interface(parent) {% for property in interface.properties %} -{% if not property.tags.config_simulator or not property.tags.config_simulator.zoned %} {% if not property.type.is_model %} , m_{{ property }}({{property|default_value}}) {% endif %} -{% endif %} {% endfor %} + , m_zones(new QQmlPropertyMap(this)) {% if 'simulator' in features %} , mWorker(nullptr) {% endif %} { //In some cases the engine is unused, this doesn't do any harm if it is still used Q_UNUSED(engine) + qRegisterMetaType<QQmlPropertyMap*>(); {% for property in interface.properties %} {% if not property.tags.config_simulator or not property.tags.config_simulator.zoned %} @@ -95,20 +128,6 @@ QT_BEGIN_NAMESPACE {% endfor %} {{module.module_name|upperfirst}}Module::registerTypes(); -{% set zones = interface.tags.config_simulator.zones if interface.tags.config_simulator and interface.tags.config_simulator.zones else {} %} -{% for zone_id in zones %} - ZoneBackend {{zone_id|lowerfirst}}Zone; -{% for property in interface.properties %} -{% if property.tags.config_simulator and property.tags.config_simulator.zoned %} -{% if property.type.is_model %} - {{zone_id|lowerfirst}}Zone.{{property}} = new {{property|upperfirst}}Model(this); -{% else %} - {{zone_id|lowerfirst}}Zone.{{property}} = {{property|default_value(zone_id)}}; -{% endif %} -{% endif %} -{% endfor %} - m_zoneMap.insert("{{zone_id}}", {{zone_id|lowerfirst}}Zone); -{% endfor %} } {{class}}::~{{class}}() @@ -128,11 +147,12 @@ QT_BEGIN_NAMESPACE */ QStringList {{class}}::availableZones() const { -{% if interface.tags.config_simulator and interface.tags.config_simulator.zoned %} - return m_zoneMap.keys(); -{% else %} - return QStringList(); -{% endif%} + QStringList zones; + QIVI_SIMULATION_TRY_CALL_FUNC({{class}}, "availableZones", zones = return_value.toStringList()); + + for (const QString &zone : zones) + const_cast<{{class}}*>(this)->addZone(zone); + return zones; } {% endif %} @@ -155,12 +175,10 @@ void {{class}}::initialize() {% endfor %} {% if interface.tags.config.zoned %} - const auto zones = availableZones(); - for (const QString &zone : zones) { + for (const QString &zone : m_zones->keys()) { + {{interface}}Zone *zo = zoneAt(zone); {% for property in interface.properties %} -{% if property.tags.config_simulator and property.tags.config_simulator.zoned %} - emit {{property}}Changed(m_zoneMap[zone].{{property}}, zone); -{% endif %} + emit {{property}}Changed(zo->{{property|getter_name}}(), zone); {% endfor %} } {% endif %} @@ -186,15 +204,26 @@ void {{class}}::initialize() emit initializationDone(); } +{% if interface_zoned %} +void {{class}}::addZone(const QString &zone) +{ + m_zones->insert(zone, QVariant::fromValue(new {{zone_class}}(zone, this))); +} + +{{zone_class}}* {{class}}::zoneAt(const QString &zone) +{ + return m_zones->value(zone).value<{{zone_class}}*>(); +} +{% endif %} {% for property in interface.properties %} -{% if not interface_zoned %} {{ivi.prop_getter(property, class, model_interface = true)}} { return m_{{property}}; } -{% endif %} +{% endfor %} +{% for property in interface.properties %} /*! \fn virtual {{ivi.prop_setter(property, class, interface_zoned)}} @@ -203,45 +232,26 @@ void {{class}}::initialize() {{ivi.prop_setter(property, class, interface_zoned, model_interface = true)}} { QIVI_SIMULATION_TRY_CALL({{class}}, "{{property|setter_name}}", void, {{property}}); -{% if property.tags.config_simulator and property.tags.config_simulator.unsupported %} - Q_UNUSED({{ property }}); -{% if interface_zoned %} - Q_UNUSED(zone); -{% endif %} - qWarning() << "SIMULATION Setting {{ property | upperfirst }} is not supported!"; - -{% else %} -{% set zoned = property.tags.config_simulator and property.tags.config_simulator.zoned %} -{% if zoned and interface_zoned %} - if (!m_zoneMap.contains(zone)) - return; - - if (m_zoneMap[zone].{{property}} == {{property}}) - return; -{% include "backend_range.cpp.tpl" %} - qWarning() << "SIMULATION {{ property | upperfirst }} for Zone" << zone << "changed to" << {{property}}; - - m_zoneMap[zone].{{property}} = {{property}}; - emit {{ property }}Changed({{property}}, zone); -{% if 'simulator' in features %} - if (mWorker) - mWorker->call("{{property|setter_name}}", {{property}}, zone); -{% endif %} -{% else %} - if ({% if interface_zoned %}!zone.isEmpty() || {%endif%}m_{{ property }} == {{property}}) +{% if interface_zoned %} + if (zone.isEmpty()) { + if (m_{{property}} == {{property}}) + return; + m_{{property}} = {{property}}; + emit {{property}}Changed({{property}}, QString()); + } else { + {{interface}}Zone *zo = zoneAt(zone); + if (zo) + zo->{{property|setter_name}}({{property}}); + else + qWarning() << "No such Zone"; + } +{% else %} + if (m_{{property}} == {{property}}) return; -{% include "backend_range.cpp.tpl" %} - qWarning() << "SIMULATION {{ property | upperfirst }} changed to" << {{property}}; - m_{{property}} = {{property}}; - emit {{property}}Changed(m_{{property}}{% if interface_zoned%}, QString(){% endif %}); -{% if 'simulator' in features %} - if (mWorker) - mWorker->call("{{property|setter_name}}", {{property}}{% if interface_zoned%}, QString(){% endif %}); -{% endif %} -{% endif %} -{% endif %} + emit {{property}}Changed(m_{{property}}); +{% endif %} } {% endfor %} diff --git a/src/tools/ivigenerator/templates_backend_simulator/backend.h.tpl b/src/tools/ivigenerator/templates_backend_simulator/backend.h.tpl index 38c7490..1ab4a29 100644 --- a/src/tools/ivigenerator/templates_backend_simulator/backend.h.tpl +++ b/src/tools/ivigenerator/templates_backend_simulator/backend.h.tpl @@ -40,12 +40,14 @@ {% import 'qtivi_macros.j2' as ivi %} {% include "generated_comment.cpp.tpl" %} {% set class = '{0}Backend'.format(interface) %} +{% set zone_class = '{0}Zone'.format(interface) %} {% set interface_zoned = interface.tags.config and interface.tags.config.zoned %} {% set oncedefine = '{0}_{1}_H_'.format(module.module_name|upper, class|upper) %} #ifndef {{oncedefine}} #define {{oncedefine}} #include <QObject> +#include <QQmlPropertyMap> {% if module.tags.config.module %} #include <{{module.tags.config.module}}/{{class}}Interface> {% else %} @@ -67,20 +69,61 @@ class QSimulatorConnectionWorker; class QIviSimulationEngine; +{% if interface_zoned %} +class {{zone_class}} : public QObject +{ + Q_OBJECT +{% for property in interface.properties %} +{% if property.type.is_model %} +{% set type = 'QIviPagingModelInterface *' %} +{% else %} +{% set type = property|return_type %} +{% endif %} + Q_PROPERTY({{type}} {{property}} READ {{property|getter_name}} WRITE {{property|setter_name}} NOTIFY {{property.name}}Changed FINAL) +{% endfor %} +public: + explicit {{zone_class}}(const QString &zone, {{class}}Interface *parent = nullptr); + +{% for property in interface.properties %} + {{ivi.prop_getter(property, model_interface = true)}}; +{% endfor %} + +public Q_SLOTS: +{% for property in interface.properties %} + {{ivi.prop_setter(property, model_interface = true)}}; +{% endfor %} + +signals: +{% for property in interface.properties %} + {{ivi.prop_notify(property, model_interface = true)}}; +{% endfor %} + +private: + {{class}}Interface *m_parent; + QString m_zone; +{% for property in interface.properties %} +{% if property.type.is_model %} + QIviPagingModelInterface *m_{{ property }}; +{% else %} + {{ property|return_type }} m_{{ property }}; +{% endif %} +{% endfor %} +}; +{% endif %} + class {{class}} : public {{class}}Interface { Q_OBJECT {% for property in interface.properties %} -{% if not interface_zoned %} {% if property.type.is_model %} {% set type = 'QIviPagingModelInterface *' %} {% else %} {% set type = property|return_type %} {% endif %} Q_PROPERTY({{type}} {{property}} READ {{property|getter_name}} WRITE {{property|setter_name}} NOTIFY {{property.name}}Changed FINAL) -{% endif %} {% endfor %} + Q_PROPERTY(QQmlPropertyMap *zones READ zones CONSTANT) public: explicit {{class}}(QObject *parent = nullptr); explicit {{class}}(QIviSimulationEngine *engine, QObject *parent = nullptr); @@ -91,15 +134,21 @@ public: {% endif %} Q_INVOKABLE void initialize() override; +{% if interface_zoned %} + void addZone(const QString &zone); + {{zone_class}}* zoneAt(const QString &zone); +{% endif %} {% for property in interface.properties %} -{% if not interface_zoned %} {{ivi.prop_getter(property, model_interface = true)}}; -{% endif %} {% endfor %} + QQmlPropertyMap *zones() const { return m_zones; } public Q_SLOTS: {% for property in interface.properties %} +{% if interface_zoned %} + {{ivi.prop_setter(property)}} { {{property|setter_name}}({{property}}, QString()); } +{% endif %} {% if not property.readonly and not property.const and not property.type.is_model %} virtual {{ivi.prop_setter(property, zoned = interface_zoned)}} override; {% else %} @@ -113,29 +162,16 @@ public Q_SLOTS: protected: {% for property in interface.properties %} -{% if not property.tags.config_simulator or not property.tags.config_simulator.zoned %} +{#{% if not property.tags.config_simulator or not property.tags.config_simulator.zoned %}#} {% if property.type.is_model %} QIviPagingModelInterface *m_{{ property }}; {% else %} {{ property|return_type }} m_{{ property }}; {% endif %} -{% endif %} +{#{% endif %}#} {% endfor %} + QQmlPropertyMap *m_zones; -{% if interface_zoned %} - struct ZoneBackend { -{% for property in interface.properties %} -{% if property.tags.config_simulator and property.tags.config_simulator.zoned %} -{% if property.type.is_model %} -QIviPagingModelInterface *{{ property }}; -{% else %} -{{ property|return_type }} {{ property }}; -{% endif %} -{% endif %} -{% endfor %} - }; - QMap<QString,ZoneBackend> m_zoneMap; -{% endif %} {% if 'simulator' in features %} QSimulatorConnection *mConnection; QSimulatorConnectionWorker *mWorker; diff --git a/src/tools/ivigenerator/templates_backend_simulator/backend_range.cpp.tpl b/src/tools/ivigenerator/templates_backend_simulator/backend_range.cpp.tpl deleted file mode 100644 index b959420..0000000 --- a/src/tools/ivigenerator/templates_backend_simulator/backend_range.cpp.tpl +++ /dev/null @@ -1,67 +0,0 @@ -{# -# Copyright (C) 2017 Klaralvdalens Datakonsult AB (KDAB). -# Copyright (C) 2018 Pelagicore AG -# Contact: https://www.qt.io/licensing/ -# -# This file is part of the QtIvi module of the Qt Toolkit. -# -# $QT_BEGIN_LICENSE:LGPL-QTAS$ -# Commercial License Usage -# Licensees holding valid commercial Qt Automotive Suite 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$ -# -# SPDX-License-Identifier: LGPL-3.0 -#} -{% set range_low_val = property|range_low %} -{% set range_high_val = property|range_high %} -{% set domain_val = property|domain_values %} -{% if range_low_val or range_high_val or domain_val %} -{% if range_low_val and range_high_val %} -{% set condition = property ~ ' < ' ~ range_low_val ~ ' || ' ~ property ~ ' > ' ~ range_high_val %} -{% set message = range_low_val ~ '-' ~ range_high_val %} -{% elif range_low_val %} -{% set condition = property ~ ' < ' ~ range_low_val %} -{% set message = '>' ~ range_low_val %} -{% elif range_high_val %} -{% set condition = property ~ ' > ' ~ range_high_val %} -{% set message = '<' ~ range_high_val %} -{% elif domain_val %} -{% set condition = "!domain.contains(" ~ property ~ ")" %} -{% set message = domain_val %} - static QVector<{{ property|return_type }}> domain({{domain_val|replace("'", "\"")|replace("[", "{")|replace("]", "}")}}); -{% endif %} - if ({{condition}}) { - qWarning() << "SIMULATION {{property}} change out of range ({{message}}):" << {{property}}; -{% if zoned and interface_zoned %} - emit {{property}}Changed({{property}}, zone); -{% else %} - emit {{property}}Changed(m_{{property}}{% if interface_zoned%}, QString(){% endif %}); -{% endif %} - return; - } -{% endif %} diff --git a/src/tools/ivigenerator/templates_backend_simulator/plugin.cpp.tpl b/src/tools/ivigenerator/templates_backend_simulator/plugin.cpp.tpl index fef7b01..ae5c48f 100644 --- a/src/tools/ivigenerator/templates_backend_simulator/plugin.cpp.tpl +++ b/src/tools/ivigenerator/templates_backend_simulator/plugin.cpp.tpl @@ -71,6 +71,8 @@ extern {{class}}::InterfaceBuilder {{module.tags.config.interfaceBuilder}}; {% else %} {% for interface in module.interfaces %} auto {{interface}}Instance = new {{interface}}Backend(m_simulationEngine, this); + //Register the types for the SimulationEngine + {{module.module_name|upperfirst}}Module::registerQmlTypes("{{module.name|lower}}.simulation", 1, 0); m_simulationEngine->registerSimulationInstance({{interface}}Instance, "{{module.name|lower}}.simulation", 1, 0, "{{interface}}Backend"); m_interfaces << {{interface}}Instance; {% endfor %} |