From 4d772050b0da4ea44f456bcde1d7239007933c0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Garapich?= Date: Wed, 10 Jun 2015 01:19:36 +0200 Subject: [PATCH] refs #443 Add simulator enable/disable option * Added CPluginSelector widget * IContextSimulator starts/stops only specified listener(s) * No more "auto" CSimulatorPluginInfo --- src/blackcore/context_runtime.cpp | 1 - src/blackcore/context_simulator.h | 4 +- src/blackcore/context_simulator_empty.h | 13 ++-- src/blackcore/context_simulator_impl.cpp | 32 +++++---- src/blackcore/context_simulator_impl.h | 5 +- src/blackcore/context_simulator_proxy.cpp | 4 +- src/blackcore/context_simulator_proxy.h | 2 +- .../components/settingssimulatorcomponent.cpp | 72 +++++++------------ .../components/settingssimulatorcomponent.h | 10 ++- .../components/settingssimulatorcomponent.ui | 29 +++----- src/blackgui/pluginselector.cpp | 67 +++++++++++++++++ src/blackgui/pluginselector.h | 50 +++++++++++++ .../simulation/simulatorplugininfo.cpp | 10 --- .../simulation/simulatorplugininfo.h | 6 -- 14 files changed, 187 insertions(+), 118 deletions(-) create mode 100644 src/blackgui/pluginselector.cpp create mode 100644 src/blackgui/pluginselector.h diff --git a/src/blackcore/context_runtime.cpp b/src/blackcore/context_runtime.cpp index ce58238a4..714101af2 100644 --- a/src/blackcore/context_runtime.cpp +++ b/src/blackcore/context_runtime.cpp @@ -176,7 +176,6 @@ namespace BlackCore Q_ASSERT(c); } times.insert("Post setup, sim.connects", time.restart()); - this->m_contextSimulator->startSimulatorPlugin(CSimulatorPluginInfo::autoPlugin()); } // only where network and(!) own aircraft run locally diff --git a/src/blackcore/context_simulator.h b/src/blackcore/context_simulator.h index 2f08b45dd..b71b20dc9 100644 --- a/src/blackcore/context_simulator.h +++ b/src/blackcore/context_simulator.h @@ -99,8 +99,8 @@ namespace BlackCore //! Load and start specific simulator plugin virtual bool startSimulatorPlugin(const BlackMisc::Simulation::CSimulatorPluginInfo &simulatorInfo) = 0; - //! Stop and unload simulator plugin and listeners - virtual void stopSimulatorPlugin() = 0; + //! Stop listener or unload the given plugin (if currently loaded) + virtual void stopSimulatorPlugin(const BlackMisc::Simulation::CSimulatorPluginInfo &simulatorInfo) = 0; //! Simulator combined status virtual int getSimulatorStatus() const = 0; diff --git a/src/blackcore/context_simulator_empty.h b/src/blackcore/context_simulator_empty.h index 5ebee3dec..effef2bf9 100644 --- a/src/blackcore/context_simulator_empty.h +++ b/src/blackcore/context_simulator_empty.h @@ -50,12 +50,6 @@ namespace BlackCore return false; } - //! \copydoc IContextSimulator::stopSimulatorPlugin() - virtual void stopSimulatorPlugin() override - { - logEmptyContextWarning(Q_FUNC_INFO); - } - //! \copydoc IContextSimulator::getSimulatorStatus() virtual int getSimulatorStatus() const override { @@ -63,6 +57,13 @@ namespace BlackCore return 0; } + //! \copydoc IContextSimulator::stopSimulatorPlugin() + virtual void stopSimulatorPlugin(const BlackMisc::Simulation::CSimulatorPluginInfo &simulatorInfo) override + { + Q_UNUSED(simulatorInfo); + logEmptyContextWarning(Q_FUNC_INFO); + } + //! \copydoc IContextSimulator::getAirportsInRange() virtual BlackMisc::Aviation::CAirportList getAirportsInRange() const override { diff --git a/src/blackcore/context_simulator_impl.cpp b/src/blackcore/context_simulator_impl.cpp index 10f4c6979..cfa6543e2 100644 --- a/src/blackcore/context_simulator_impl.cpp +++ b/src/blackcore/context_simulator_impl.cpp @@ -48,7 +48,7 @@ namespace BlackCore void CContextSimulator::gracefulShutdown() { this->disconnect(); - this->stopSimulatorPlugin(); + this->unloadSimulatorPlugin(); } CSimulatorPluginInfoList CContextSimulator::getAvailableSimulatorPlugins() const @@ -61,9 +61,15 @@ namespace BlackCore return this->loadSimulatorPlugin(simulatorInfo, true); } - void CContextSimulator::stopSimulatorPlugin() + void CContextSimulator::stopSimulatorPlugin(const CSimulatorPluginInfo &simulatorInfo) { - this->unloadSimulatorPlugin(); + if (!m_simulatorPlugin.first.isUnspecified() && m_simulatorPlugin.first == simulatorInfo) + { + this->unloadSimulatorPlugin(); + } + + ISimulatorListener *listener = m_plugins->getListener(simulatorInfo.getIdentifier()); + QMetaObject::invokeMethod(listener, "stop"); } int CContextSimulator::getSimulatorStatus() const @@ -281,28 +287,24 @@ namespace BlackCore Q_ASSERT(!simulatorInfo.isUnspecified()); Q_ASSERT(CThreadUtils::isCurrentThreadApplicationThread()); // only run in main thread + if (!simulatorInfo.isValid()) + { + CLogMessage(this).error("Illegal plugin"); + return false; + } + // Is the plugin already loaded? - if (!m_simulatorPlugin.first.isUnspecified() && - (m_simulatorPlugin.first == simulatorInfo || simulatorInfo.isAuto())) + if (!m_simulatorPlugin.first.isUnspecified()) { return true; } - stopSimulatorListeners(); // we make sure all listeners are stopped and restart those we need unloadSimulatorPlugin(); // old plugin unloaded // now we have a state where no driver is loaded if (withListener) { - // hand over to listeners, when listener is done, it will call this function again - if (simulatorInfo.isAuto()) - { - this->listenForAllSimulators(); - } - else - { - this->listenForSimulator(simulatorInfo); - } + this->listenForSimulator(simulatorInfo); return false; // not a plugin yet, just listener } diff --git a/src/blackcore/context_simulator_impl.h b/src/blackcore/context_simulator_impl.h index 7f40ad8af..e0387f6c5 100644 --- a/src/blackcore/context_simulator_impl.h +++ b/src/blackcore/context_simulator_impl.h @@ -55,7 +55,7 @@ namespace BlackCore virtual bool startSimulatorPlugin(const BlackMisc::Simulation::CSimulatorPluginInfo &simulatorInfo) override; //! \copydoc IContextSimulator::stopSimulatorPlugin() - virtual void stopSimulatorPlugin() override; + virtual void stopSimulatorPlugin(const BlackMisc::Simulation::CSimulatorPluginInfo &simulatorInfo) override; //! \copydoc IContextSimulator::getSimulatorStatus() virtual int getSimulatorStatus() const override; @@ -171,9 +171,6 @@ namespace BlackCore //! Unload plugin, if desired restart listeners void unloadSimulatorPlugin(); - //! Load plugin from settings - bool loadSimulatorPluginFromSettings(); - //! Listen for single simulator void listenForSimulator(const BlackMisc::Simulation::CSimulatorPluginInfo &simulatorInfo); diff --git a/src/blackcore/context_simulator_proxy.cpp b/src/blackcore/context_simulator_proxy.cpp index dc41c86c9..548eaf5dc 100644 --- a/src/blackcore/context_simulator_proxy.cpp +++ b/src/blackcore/context_simulator_proxy.cpp @@ -166,9 +166,9 @@ namespace BlackCore return m_dBusInterface->callDBusRet(QLatin1Literal("startSimulatorPlugin"), simulatorInfo); } - void CContextSimulatorProxy::stopSimulatorPlugin() + void CContextSimulatorProxy::stopSimulatorPlugin(const BlackMisc::Simulation::CSimulatorPluginInfo &simulatorInfo) { - m_dBusInterface->callDBus(QLatin1Literal("stopSimulatorPlugin")); + m_dBusInterface->callDBus(QLatin1Literal("stopSimulatorPlugin"), simulatorInfo); } CPixmap CContextSimulatorProxy::iconForModel(const QString &modelString) const diff --git a/src/blackcore/context_simulator_proxy.h b/src/blackcore/context_simulator_proxy.h index f4f569af8..bb0b0860f 100644 --- a/src/blackcore/context_simulator_proxy.h +++ b/src/blackcore/context_simulator_proxy.h @@ -54,7 +54,7 @@ namespace BlackCore virtual bool startSimulatorPlugin(const BlackMisc::Simulation::CSimulatorPluginInfo &simulatorInfo) override; //! \copydoc IContextSimulator::stopSimulatorPlugin() - virtual void stopSimulatorPlugin() override; + virtual void stopSimulatorPlugin(const BlackMisc::Simulation::CSimulatorPluginInfo &simulatorInfo) override; //! \copydoc IContextSimulator::getSimulatorStatus() virtual int getSimulatorStatus() const override; diff --git a/src/blackgui/components/settingssimulatorcomponent.cpp b/src/blackgui/components/settingssimulatorcomponent.cpp index 8e87199d2..814a73e8a 100644 --- a/src/blackgui/components/settingssimulatorcomponent.cpp +++ b/src/blackgui/components/settingssimulatorcomponent.cpp @@ -39,13 +39,14 @@ namespace BlackGui Q_ASSERT_X(this->getIContextSimulator(), Q_FUNC_INFO, "missing simulator"); // set values - for (const auto &p : getAvailablePlugins(true)) + for (const auto &p : getAvailablePlugins()) { - ui->cb_Plugins->addItem(p.toQString(), QVariant::fromValue(p)); + ui->ps_EnabledSimulators->addPlugin(p.getIdentifier(), p.getName(), false); } // connects - connect(this->ui->cb_Plugins, static_cast (&QComboBox::currentIndexChanged), this, &CSettingsSimulatorComponent::ps_pluginHasBeenSelectedInComboBox); + connect(this->getIContextSimulator(), &IContextSimulator::simulatorPluginChanged, this, &CSettingsSimulatorComponent::ps_simulatorPluginChanged); + connect(this->ui->ps_EnabledSimulators, &CPluginSelector::pluginStateChanged, this, &CSettingsSimulatorComponent::ps_pluginStateChanged); connect(this->ui->pb_ApplyMaxAircraft, &QCheckBox::pressed, this, &CSettingsSimulatorComponent::ps_onApplyMaxRenderedAircraft); connect(this->ui->pb_ApplyTimeSync, &QCheckBox::pressed, this, &CSettingsSimulatorComponent::ps_onApplyTimeSync); connect(this->ui->pb_ApplyMaxDistance, &QCheckBox::pressed, this, &CSettingsSimulatorComponent::ps_onApplyMaxRenderedDistance); @@ -58,29 +59,6 @@ namespace BlackGui this->ps_simulatorPluginChanged(getIContextSimulator()->getSimulatorPluginInfo()); } - void CSettingsSimulatorComponent::setCurrentPluginInComboBox(const CSimulatorPluginInfo &plugin) - { - if (plugin.isUnspecified()) - { - ui->cb_Plugins->setCurrentIndex(0); - return; - } - - for (int i = 0; i < this->ui->cb_Plugins->count(); ++i) - { - QVariant data = this->ui->cb_Plugins->itemData(i); - Q_ASSERT(data.canConvert()); - CSimulatorPluginInfo p = data.value(); - - if (p.getIdentifier() == plugin.getIdentifier()) - { - if (i == this->ui->cb_Plugins->currentIndex()) { return; } - this->ui->cb_Plugins->setCurrentIndex(i); - break; - } - } - } - void CSettingsSimulatorComponent::setGuiValues() { Q_ASSERT(getIContextSimulator()); @@ -125,33 +103,37 @@ namespace BlackGui } } - CSimulatorPluginInfoList CSettingsSimulatorComponent::getAvailablePlugins(bool plusAuto) const + CSimulatorPluginInfoList CSettingsSimulatorComponent::getAvailablePlugins() const { - CSimulatorPluginInfoList l(getIContextSimulator()->getAvailableSimulatorPlugins()); - if (plusAuto) { l.push_front(CSimulatorPluginInfo::autoPlugin()); } - return l; + return getIContextSimulator()->getAvailableSimulatorPlugins(); } - void CSettingsSimulatorComponent::ps_pluginHasBeenSelectedInComboBox(int index) + void CSettingsSimulatorComponent::ps_pluginStateChanged(const QString &identifier, bool enabled) { - Q_ASSERT(this->getIContextSimulator()); - if (!this->getIContextSimulator()) { return; } + Q_ASSERT(getIContextSimulator()); - CSimulatorPluginInfoList simDrivers(getAvailablePlugins(true)); - if (simDrivers.isEmpty()) + CSimulatorPluginInfoList simDrivers(getAvailablePlugins()); + auto selected = std::find_if(simDrivers.begin(), simDrivers.end(), + [&identifier](const CSimulatorPluginInfo &info) + { + return info.getIdentifier() == identifier; + }); + + if (selected->isUnspecified()) { - CLogMessage(this).error("No drivers available"); - return; - } - if (simDrivers.size() <= index) - { - CLogMessage(this).error("Wrong driver index"); - return; + CLogMessage(this).error("Simulator plugin does not exist: %1") << identifier; } - // update - CSimulatorPluginInfo selectedPlugin = simDrivers[index]; - this->getIContextSimulator()->startSimulatorPlugin(selectedPlugin); + if (enabled) + { + getIContextSimulator()->startSimulatorPlugin(*selected); + CLogMessage(this).info("Started listening for %1") << selected->getSimulator(); + } + else + { + getIContextSimulator()->stopSimulatorPlugin(*selected); + CLogMessage(this).info("Stopped listening for %1") << selected->getSimulator(); + } // changing of GUI state will be done via received signal } diff --git a/src/blackgui/components/settingssimulatorcomponent.h b/src/blackgui/components/settingssimulatorcomponent.h index dfa3eec0e..906c37029 100644 --- a/src/blackgui/components/settingssimulatorcomponent.h +++ b/src/blackgui/components/settingssimulatorcomponent.h @@ -39,8 +39,9 @@ namespace BlackGui virtual void runtimeHasBeenSet() override; private slots: - //! Driver changed - void ps_pluginHasBeenSelectedInComboBox(int index); + //! Driver plugin enabled/disabled + //! \todo Unload plugin if user disables it while running + void ps_pluginStateChanged(const QString &identifier, bool enabled); //! Apply max.aircraft void ps_onApplyMaxRenderedAircraft(); @@ -62,14 +63,11 @@ namespace BlackGui private: - //! Smarter way to set current driver, avoids unnecessary signals and less formatting dependend - void setCurrentPluginInComboBox(const BlackMisc::Simulation::CSimulatorPluginInfo &plugin); - //! Set the GUI values void setGuiValues(); //! Available plugins, auto pseudo plugin added - BlackMisc::Simulation::CSimulatorPluginInfoList getAvailablePlugins(bool plusAuto) const; + BlackMisc::Simulation::CSimulatorPluginInfoList getAvailablePlugins() const; QScopedPointer ui; //!< UI bool m_pluginLoaded = false; //!< plugin loaded diff --git a/src/blackgui/components/settingssimulatorcomponent.ui b/src/blackgui/components/settingssimulatorcomponent.ui index 79e47381a..276b1905e 100644 --- a/src/blackgui/components/settingssimulatorcomponent.ui +++ b/src/blackgui/components/settingssimulatorcomponent.ui @@ -53,26 +53,6 @@ 6 - - - - Driver - - - - - - - - 16777215 - 16777215 - - - - QComboBox::AdjustToMinimumContentsLength - - - @@ -380,6 +360,9 @@ + + + @@ -424,6 +407,12 @@
blackgui/led.h
1 + + BlackGui::CPluginSelector + QWidget +
blackgui/pluginselector.h
+ 1 +
diff --git a/src/blackgui/pluginselector.cpp b/src/blackgui/pluginselector.cpp new file mode 100644 index 000000000..bb3f87018 --- /dev/null +++ b/src/blackgui/pluginselector.cpp @@ -0,0 +1,67 @@ +#include "pluginselector.h" + +#include +#include +#include +#include +#include + +namespace BlackGui +{ + + CPluginSelector::CPluginSelector(QWidget *parent) : QWidget(parent) + { + setObjectName("CPluginSelector"); + + QVBoxLayout *layout = new QVBoxLayout; + setLayout(layout); + } + + void CPluginSelector::addPlugin(const QString& identifier, const QString &name, bool enabled) + { + QWidget *pw = new QWidget; + QHBoxLayout *layout = new QHBoxLayout; + layout->setContentsMargins(0, 0, 0, 0); + pw->setLayout(layout); + + QCheckBox *cb = new QCheckBox(name); + cb->setProperty("pluginIdentifier", identifier); + connect(cb, &QCheckBox::stateChanged, this, &CPluginSelector::ps_handlePluginStateChange); + if (enabled) + { + cb->setCheckState(Qt::Checked); + } + else + { + cb->setCheckState(Qt::Unchecked); + } + + pw->layout()->addWidget(cb); + + /* Might be useful for #392 */ +#if 0 + QPushButton *pb = new QPushButton("..."); + pw->layout()->addWidget(pb); + + layout->setStretch(0, 1); + layout->setStretch(1, 0); +#endif + + this->layout()->addWidget(pw); + } + + void CPluginSelector::ps_handlePluginStateChange() + { + QCheckBox *cb = qobject_cast(sender()); + Q_ASSERT(cb); + + bool enabled = cb->checkState() != Qt::Unchecked; + Q_ASSERT(cb->property("pluginIdentifier").isValid()); + QString identifier = cb->property("pluginIdentifier").toString(); + Q_ASSERT(!identifier.isEmpty()); + + emit pluginStateChanged(identifier, enabled); + } + + +} // namespace diff --git a/src/blackgui/pluginselector.h b/src/blackgui/pluginselector.h new file mode 100644 index 000000000..e22a83875 --- /dev/null +++ b/src/blackgui/pluginselector.h @@ -0,0 +1,50 @@ +/* Copyright (C) 2014 + * swift project Community / Contributors + * + * This file is part of swift Project. It is subject to the license terms in the LICENSE file found in the top-level + * directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project, + * including this file, may be copied, modified, propagated, or distributed except according to the terms + * contained in the LICENSE file. + */ + +//! \file + +#ifndef PLUGINSELECTOR_H +#define PLUGINSELECTOR_H + +#include "blackgui/blackguiexport.h" + +#include + +namespace BlackGui { + + /*! + * \brief The CPluginSelector class is used to select which plugins are to be loaded + * and (optionally) configure them. + */ + class BLACKGUI_EXPORT CPluginSelector : public QWidget + { + Q_OBJECT + + signals: + //! Emitted when user enables/disables the particular plugin + void pluginStateChanged(QString identifier, bool enabled); + + public: + //! Constructor + explicit CPluginSelector(QWidget *parent = 0); + + //! Adds the new plugin to the list. + //! \param identifier Identifier of the plugin. + //! \param name Name of the plugin + //! \param enabled Defines whether the plugin is initially enabled or not + void addPlugin(const QString &identifier, const QString &name, bool enabled = true); + + private slots: + void ps_handlePluginStateChange(); + + }; + +} // namespace BlackGui + +#endif // PLUGINSELECTOR_H diff --git a/src/blackmisc/simulation/simulatorplugininfo.cpp b/src/blackmisc/simulation/simulatorplugininfo.cpp index 5f89de33b..d4376e509 100644 --- a/src/blackmisc/simulation/simulatorplugininfo.cpp +++ b/src/blackmisc/simulation/simulatorplugininfo.cpp @@ -39,21 +39,11 @@ namespace BlackMisc return m_identifier.isEmpty(); } - bool CSimulatorPluginInfo::isAuto() const - { - return (*this) == autoPlugin(); - } - QString CSimulatorPluginInfo::convertToQString(bool i18n) const { Q_UNUSED(i18n); return QString("%1 (%2)").arg(m_name, m_identifier); } - const CSimulatorPluginInfo &CSimulatorPluginInfo::autoPlugin() - { - static const CSimulatorPluginInfo p("auto", "auto", "auto", "automatic plugin selection", false); - return p; - } } // ns } // ns diff --git a/src/blackmisc/simulation/simulatorplugininfo.h b/src/blackmisc/simulation/simulatorplugininfo.h index 9f6b9e5fb..4f9bf81da 100644 --- a/src/blackmisc/simulation/simulatorplugininfo.h +++ b/src/blackmisc/simulation/simulatorplugininfo.h @@ -56,15 +56,9 @@ namespace BlackMisc //! Description const QString &getDescription() const { return m_description; } - //! Special info of type auto? - bool isAuto() const; - //! \copydoc CValueObject::convertToQString QString convertToQString(bool i18n = false) const; - //! Info representing a entry representing automatic plugin selection - static const CSimulatorPluginInfo &autoPlugin(); - private: BLACK_ENABLE_TUPLE_CONVERSION(CSimulatorPluginInfo) QString m_identifier;