From 94eb33d22845314b4b4f350764aeccdbb14756b0 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Thu, 28 May 2015 20:13:03 +0200 Subject: [PATCH] refs #431, infinite recursion in driver unload * Trivial changes to avoid changedStatus signal when nothing changed * Do not reload plugin when already loaded --- src/blackcore/context_simulator_impl.cpp | 37 +++++++++++-------- src/blackcore/simulator.cpp | 8 +++- src/blackcore/simulator.h | 8 ++-- src/plugins/simulator/fs9/simulator_fs9.cpp | 2 +- src/plugins/simulator/fsx/simulator_fsx.cpp | 8 ++-- .../fsx/simulator_fsx_simconnectproc.cpp | 7 +++- .../simulator/xplane/simulator_xplane.cpp | 1 + 7 files changed, 45 insertions(+), 26 deletions(-) diff --git a/src/blackcore/context_simulator_impl.cpp b/src/blackcore/context_simulator_impl.cpp index 46964878d..0d8078922 100644 --- a/src/blackcore/context_simulator_impl.cpp +++ b/src/blackcore/context_simulator_impl.cpp @@ -35,6 +35,7 @@ namespace BlackCore IContextSimulator(mode, runtime), m_mapper(new QSignalMapper(this)) { + this->setObjectName("CContextSimulator"); findSimulatorPlugins(); // Maps listener instance connect(m_mapper, static_cast(&QSignalMapper::mapped), this, &CContextSimulator::ps_simulatorStarted); @@ -363,6 +364,12 @@ namespace BlackCore return false; } + // Is the plugin already loaded? + if (m_simulatorPlugin && m_simulatorPlugin->info == simulatorInfo) + { + return true; + } + ISimulatorFactory *factory = getSimulatorFactory(simulatorInfo); Q_ASSERT(factory); @@ -416,6 +423,7 @@ namespace BlackCore settingsChanged(static_cast(IContextSettings::SettingsSimulator)); // try to connect + //! \todo #417: we want to change this to connectTo, as the listener already checks the avialability of the simulator m_simulatorPlugin->simulator->asyncConnectTo(); if (m_simulatorPlugin) // can be already nullptr if connectTo() is synchronous and fails @@ -541,25 +549,24 @@ namespace BlackCore void CContextSimulator::unloadSimulatorPlugin() { - if (m_simulatorPlugin) - { - // depending on shutdown order, network might already have been deleted - emit simulatorPluginChanged(CSimulatorPluginInfo()); + if (!m_simulatorPlugin) { return; } - Q_ASSERT(this->getIContextNetwork()); - Q_ASSERT(this->getIContextNetwork()->isLocalObject()); - Q_ASSERT(m_simulatorPlugin->simulator); + // depending on shutdown order, network might already have been deleted + emit simulatorPluginChanged(CSimulatorPluginInfo()); - // unload and disconnect - m_simulatorPlugin->simulator->unload(); + Q_ASSERT(this->getIContextNetwork()); + Q_ASSERT(this->getIContextNetwork()->isLocalObject()); + Q_ASSERT(m_simulatorPlugin->simulator); - // disconnect signals - this->disconnect(m_simulatorPlugin->simulator); + // unload and disconnect + m_simulatorPlugin->simulator->unload(); - m_simulatorPlugin->simulator->deleteLater(); - m_simulatorPlugin->simulator = nullptr; - m_simulatorPlugin = nullptr; - } + // disconnect signals + this->disconnect(m_simulatorPlugin->simulator); + + m_simulatorPlugin->simulator->deleteLater(); + m_simulatorPlugin->simulator = nullptr; + m_simulatorPlugin = nullptr; } void CContextSimulator::ps_addRemoteAircraft(const CSimulatedAircraft &remoteAircraft) diff --git a/src/blackcore/simulator.cpp b/src/blackcore/simulator.cpp index 188ec502a..ed49f8e58 100644 --- a/src/blackcore/simulator.cpp +++ b/src/blackcore/simulator.cpp @@ -45,9 +45,13 @@ namespace BlackCore } } - void ISimulator::emitSimulatorCombinedStatus() + void ISimulator::emitSimulatorCombinedStatus(int oldStatus) { - emit simulatorStatusChanged(getSimulatorStatus()); + int newStatus = getSimulatorStatus(); + if (oldStatus != newStatus) + { + emit simulatorStatusChanged(newStatus); + } } ISimulatorListener::ISimulatorListener(QObject *parent) : QObject(parent) diff --git a/src/blackcore/simulator.h b/src/blackcore/simulator.h index cdd24b88d..49bd50e39 100644 --- a/src/blackcore/simulator.h +++ b/src/blackcore/simulator.h @@ -34,8 +34,8 @@ namespace BlackCore //! Interface to a simulator. class BLACKCORE_EXPORT ISimulator : - public QObject, - public BlackMisc::COriginatorAware + public QObject, + public BlackMisc::COriginatorAware { Q_OBJECT @@ -73,6 +73,7 @@ namespace BlackCore virtual bool connectTo() = 0; //! Connect asynchronously to simulator + //! \deprecated #417 virtual void asyncConnectTo() = 0; //! Disconnect from simulator @@ -226,8 +227,9 @@ namespace BlackCore virtual int physicallyRemoveAllRemoteAircraft() = 0; //! Emit the combined status + //! \param oldStatus optionally one can capture and provide the old status for comparison. In case of equal status values no signal will be sent //! \sa simulatorStatusChanged; - void emitSimulatorCombinedStatus(); + void emitSimulatorCombinedStatus(int oldStatus = -1); }; //! Interface to a simulator listener. diff --git a/src/plugins/simulator/fs9/simulator_fs9.cpp b/src/plugins/simulator/fs9/simulator_fs9.cpp index 77c486253..43501aa9f 100644 --- a/src/plugins/simulator/fs9/simulator_fs9.cpp +++ b/src/plugins/simulator/fs9/simulator_fs9.cpp @@ -96,7 +96,7 @@ namespace BlackSimPlugin bool CSimulatorFs9::disconnectFrom() { - if (!m_simConnected) return true; + if (!m_simConnected) { return true; } // Don't forward messages when disconnected disconnect(m_connectionHostMessages); diff --git a/src/plugins/simulator/fsx/simulator_fsx.cpp b/src/plugins/simulator/fsx/simulator_fsx.cpp index 2bdf96ce1..b68382373 100644 --- a/src/plugins/simulator/fsx/simulator_fsx.cpp +++ b/src/plugins/simulator/fsx/simulator_fsx.cpp @@ -80,12 +80,13 @@ namespace BlackSimPlugin bool CSimulatorFsx::connectTo() { if (m_simConnected) { return true; } + int oldStatus = getSimulatorStatus(); if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0))) { m_simConnected = false; m_simPaused = false; m_simSimulating = false; - emitSimulatorCombinedStatus(); + emitSimulatorCombinedStatus(oldStatus); return false; } else @@ -96,7 +97,7 @@ namespace BlackSimPlugin initWhenConnected(); m_simconnectTimerId = startTimer(10); m_simConnected = true; - emitSimulatorCombinedStatus(); + emitSimulatorCombinedStatus(oldStatus); return true; } @@ -352,8 +353,9 @@ namespace BlackSimPlugin void CSimulatorFsx::onSimStopped() { + int oldStatus = getSimulatorStatus(); m_simSimulating = false; - emitSimulatorCombinedStatus(); + emitSimulatorCombinedStatus(oldStatus); } void CSimulatorFsx::onSimFrame() diff --git a/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp b/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp index 53dc972f2..c38f17404 100644 --- a/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp +++ b/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp @@ -84,8 +84,11 @@ namespace BlackSimPlugin case SystemEventPause: { bool p = event->dwData ? true : false; - simulatorFsx->m_simPaused = p; - simulatorFsx->emitSimulatorCombinedStatus(); + if (simulatorFsx->m_simPaused != p) + { + simulatorFsx->m_simPaused = p; + simulatorFsx->emitSimulatorCombinedStatus(); + } break; } default: diff --git a/src/plugins/simulator/xplane/simulator_xplane.cpp b/src/plugins/simulator/xplane/simulator_xplane.cpp index 713c7467c..ca9cfb5e6 100644 --- a/src/plugins/simulator/xplane/simulator_xplane.cpp +++ b/src/plugins/simulator/xplane/simulator_xplane.cpp @@ -193,6 +193,7 @@ namespace BlackSimPlugin bool CSimulatorXPlane::disconnectFrom() { + if (!this->isConnected()) { return true; } // avoid emit if already disconnected if (m_traffic) { m_traffic->cleanup();