From de43caf451375a44bdc56520e37e450a5cb71d84 Mon Sep 17 00:00:00 2001 From: Klaus Basan Date: Fri, 15 May 2015 18:50:41 +0200 Subject: [PATCH] refs #420, refs #421 Adjusted FSX driver to emit correct status flags and unloading * added unload function to disconnect signals / slots and simulator * changed remote provider to return signal/slot connections to manually disconnect functor connects * flag so pause can freeze or continue AI aircraft * slightly changed unload behaviour in simulator context Remark: Tested for FSX only Solves #424 for FSX --- src/blackcore/airspace_monitor.cpp | 27 +++---- src/blackcore/airspace_monitor.h | 5 +- src/blackcore/context_network_impl.cpp | 8 +- src/blackcore/context_network_impl.h | 6 +- src/blackcore/context_runtime.h | 2 +- src/blackcore/context_simulator_impl.cpp | 19 ++--- src/blackcore/simulator.cpp | 16 ++++ src/blackcore/simulator.h | 8 +- src/blackcore/simulator_common.cpp | 75 +++++++++++-------- src/blackcore/simulator_common.h | 9 +++ .../simulation/remoteaircraftprovider.h | 9 +-- .../remoteaircraftproviderdummy.cpp | 22 +++--- .../simulation/remoteaircraftproviderdummy.h | 5 +- src/plugins/simulator/fsx/simulator_fsx.cpp | 27 ++++--- src/plugins/simulator/fsx/simulator_fsx.h | 25 ++++--- .../fsx/simulator_fsx_simconnectproc.cpp | 39 +++++++--- 16 files changed, 172 insertions(+), 130 deletions(-) diff --git a/src/blackcore/airspace_monitor.cpp b/src/blackcore/airspace_monitor.cpp index dedb8ca89..cb9b1b3b4 100644 --- a/src/blackcore/airspace_monitor.cpp +++ b/src/blackcore/airspace_monitor.cpp @@ -129,29 +129,22 @@ namespace BlackCore return m_aircraftSupportingParts; } - bool CAirspaceMonitor::connectRemoteAircraftProviderSignals( + QList CAirspaceMonitor::connectRemoteAircraftProviderSignals( std::function situationSlot, std::function partsSlot, std::function removedAircraftSlot, std::function aircraftSnapshotSlot ) { - bool s1 = connect(this, &CAirspaceMonitor::addedAircraftSituation, situationSlot); - Q_ASSERT(s1); - bool s2 = connect(this, &CAirspaceMonitor::addedAircraftParts, partsSlot); - Q_ASSERT(s2); - bool s3 = connect(this, &CAirspaceMonitor::removedAircraft, removedAircraftSlot); - Q_ASSERT(s3); - bool s4 = connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, aircraftSnapshotSlot); - Q_ASSERT(s4); - - return s1 && s2 && s3 && s4; - } - - bool CAirspaceMonitor::disconnectRemoteAircraftProviderSignals(QObject *receiver) - { - if (!receiver) { return false; } - return this->disconnect(receiver); + QMetaObject::Connection c1 = connect(this, &CAirspaceMonitor::addedAircraftSituation, situationSlot); + Q_ASSERT(c1); + QMetaObject::Connection c2 = connect(this, &CAirspaceMonitor::addedAircraftParts, partsSlot); + Q_ASSERT(c2); + QMetaObject::Connection c3 = connect(this, &CAirspaceMonitor::removedAircraft, removedAircraftSlot); + Q_ASSERT(c3); + QMetaObject::Connection c4 = this->connect(this->m_analyzer, &CAirspaceAnalyzer::airspaceAircraftSnapshot, aircraftSnapshotSlot); + Q_ASSERT(c4); + return QList({ c1, c2, c3, c4}); } bool CAirspaceMonitor::updateAircraftEnabled(const CCallsign &callsign, bool enabledForRedering, const QString &originator) diff --git a/src/blackcore/airspace_monitor.h b/src/blackcore/airspace_monitor.h index 25071eac3..c6566e927 100644 --- a/src/blackcore/airspace_monitor.h +++ b/src/blackcore/airspace_monitor.h @@ -147,16 +147,13 @@ namespace BlackCore void testAddAircraftParts(const BlackMisc::Aviation::CAircraftParts &parts, bool incremental); //! \copydoc IRemoteAircraftProvider::connectRemoteAircraftProviderSignals - virtual bool connectRemoteAircraftProviderSignals( + virtual QList connectRemoteAircraftProviderSignals( std::function addedSituationSlot, std::function addedPartsSlot, std::function removedAircraftSlot, std::function aircraftSnapshotSlot ) override; - //! \copydoc IRemoteAircraftProvider::disconnectRemoteAircraftProviderSignals - virtual bool disconnectRemoteAircraftProviderSignals(QObject *receiver) override; - //! Is interim position sending enabled? bool isFastPositionSendingEnabled() const; diff --git a/src/blackcore/context_network_impl.cpp b/src/blackcore/context_network_impl.cpp index 440498517..3fbe82673 100644 --- a/src/blackcore/context_network_impl.cpp +++ b/src/blackcore/context_network_impl.cpp @@ -135,7 +135,7 @@ namespace BlackCore return m_airspace->remoteAircraftSupportingParts(); } - bool CContextNetwork::connectRemoteAircraftProviderSignals( + QList CContextNetwork::connectRemoteAircraftProviderSignals( std::function situationSlot, std::function partsSlot, std::function removedAircraftSlot, @@ -145,12 +145,6 @@ namespace BlackCore return this->m_airspace->connectRemoteAircraftProviderSignals(situationSlot, partsSlot, removedAircraftSlot, aircraftSnapshotSlot); } - bool CContextNetwork::disconnectRemoteAircraftProviderSignals(QObject *receiver) - { - Q_ASSERT(this->m_airspace); - return this->m_airspace->disconnectRemoteAircraftProviderSignals(receiver); - } - void CContextNetwork::gracefulShutdown() { if (this->m_vatsimBookingReader) { this->m_vatsimBookingReader->requestStop(); this->m_vatsimBookingReader->quit(); } diff --git a/src/blackcore/context_network_impl.h b/src/blackcore/context_network_impl.h index 74d784688..9f49d5ef1 100644 --- a/src/blackcore/context_network_impl.h +++ b/src/blackcore/context_network_impl.h @@ -74,17 +74,13 @@ namespace BlackCore //! \copydoc IRemoteAircraftProvider::connectSignals //! \ingroup remoteaircraftprovider - virtual bool connectRemoteAircraftProviderSignals( + virtual QList connectRemoteAircraftProviderSignals( std::function addedSituationSlot, std::function addedPartsSlot, std::function removedAircraftSlot, std::function aircraftSnapshotSlot ) override; - //! \copydoc IRemoteAircraftProvider::disconnectRemoteAircraftProviderSignals - //! \ingroup remoteaircraftprovider - virtual bool disconnectRemoteAircraftProviderSignals(QObject *receiver) override; - //! \copydoc IRemoteAircraftProvider::updateAircraftRendered //! \ingroup remoteaircraftprovider virtual bool updateAircraftRendered(const BlackMisc::Aviation::CCallsign &callsign, bool rendered, const QString &originator) override; diff --git a/src/blackcore/context_runtime.h b/src/blackcore/context_runtime.h index 1b30c18dc..e1eeea01a 100644 --- a/src/blackcore/context_runtime.h +++ b/src/blackcore/context_runtime.h @@ -158,7 +158,7 @@ namespace BlackCore bool parseCommandLine(const QString commandLine, const QString &originator); private: - bool m_init = false; /*!< flag */ + bool m_init = false; //!< flag // DBus CDBusServer *m_dbusServer = nullptr; diff --git a/src/blackcore/context_simulator_impl.cpp b/src/blackcore/context_simulator_impl.cpp index ef2377e9f..4b6af3276 100644 --- a/src/blackcore/context_simulator_impl.cpp +++ b/src/blackcore/context_simulator_impl.cpp @@ -542,16 +542,10 @@ namespace BlackCore Q_ASSERT(this->getIContextNetwork()->isLocalObject()); Q_ASSERT(m_simulatorPlugin->simulator); - // disconnect from simulator - if (m_simulatorPlugin->simulator->isConnected()) - { - m_simulatorPlugin->simulator->disconnectFrom(); - } + // unload and disconnect + m_simulatorPlugin->simulator->unload(); // disconnect signals - this->getRuntime()->getCContextNetwork()->disconnectRemoteAircraftProviderSignals(m_simulatorPlugin->simulator); - m_simulatorPlugin->simulator->disconnect(); - CLogHandler::instance()->disconnect(m_simulatorPlugin->simulator); this->disconnect(m_simulatorPlugin->simulator); m_simulatorPlugin->simulator->deleteLater(); @@ -599,8 +593,15 @@ namespace BlackCore if (!(status & ISimulator::Connected)) { + // we got disconnected unloadSimulatorPlugin(); - listenForSimulatorFromSettings(); + + // do not immediately listen again, but allow some time for the simulator to shutdown + // otherwise we risk reconnecting to a closing simulator + BlackMisc::singleShot(1000, QThread::currentThread(), [ = ]() + { + listenForSimulatorFromSettings(); + }); } emit simulatorStatusChanged(status); } diff --git a/src/blackcore/simulator.cpp b/src/blackcore/simulator.cpp index 5909d828f..f4d9c1ec7 100644 --- a/src/blackcore/simulator.cpp +++ b/src/blackcore/simulator.cpp @@ -28,6 +28,22 @@ namespace BlackCore return o; } + QString ISimulator::statusToString(int status) + { + if (status > 0) + { + QString s; + if (status & Connected) { s.append("Connected"); } + if (status & Running) { if (!s.isEmpty()) { s.append(", "); } s.append("Simulating"); } + if (status & Paused) { if (!s.isEmpty()) { s.append(", "); } s.append("Paused"); } + return s; + } + else + { + return "Disconnected"; + } + } + void ISimulator::emitSimulatorCombinedStatus() { int status = diff --git a/src/blackcore/simulator.h b/src/blackcore/simulator.h index 36cbf14e5..c9f390aed 100644 --- a/src/blackcore/simulator.h +++ b/src/blackcore/simulator.h @@ -45,7 +45,7 @@ namespace BlackCore Paused = 1 << 2, //!< Is the simulator paused? }; - //! Render all aircraft + //! Render all aircraft if number of aircraft >= MaxAircraftInfinite const int MaxAircraftInfinite = 100; //! Destructor @@ -174,9 +174,15 @@ namespace BlackCore //! Highlight the aircraft for given time (or disable highlight) virtual void highlightAircraft(const BlackMisc::Simulation::CSimulatedAircraft &aircraftToHighlight, bool enableHighlight, const BlackMisc::PhysicalQuantities::CTime &displayTime) = 0; + //! Driver will be unloaded + virtual void unload() = 0; + //! Originator const QString &simulatorOriginator(); + //! Status to string + static QString statusToString(int status); + signals: //! Simulator combined status void simulatorStatusChanged(int status); diff --git a/src/blackcore/simulator_common.cpp b/src/blackcore/simulator_common.cpp index d2ee55cbc..684a97659 100644 --- a/src/blackcore/simulator_common.cpp +++ b/src/blackcore/simulator_common.cpp @@ -11,6 +11,7 @@ #include "blackcore/interpolator.h" #include "blackcore/blackcorefreefunctions.h" #include "blackmisc/logmessage.h" +#include "blackmisc/loghandler.h" #include "blackmisc/collection.h" using namespace BlackMisc; @@ -31,24 +32,25 @@ namespace BlackCore m_simulatorPluginInfo(info) { this->setObjectName(info.getIdentifier()); + + // provider signals + m_remoteAircraftProviderConnections = this->m_remoteAircraftProvider->connectRemoteAircraftProviderSignals( + std::bind(&CSimulatorCommon::ps_remoteProviderAddAircraftSituation, this, std::placeholders::_1), + std::bind(&CSimulatorCommon::ps_remoteProviderAddAircraftParts, this, std::placeholders::_1), + std::bind(&CSimulatorCommon::ps_remoteProviderRemovedAircraft, this, std::placeholders::_1), + std::bind(static_cast(&CSimulatorCommon::ps_recalculateRenderedAircraft), this, std::placeholders::_1)); + + // timer this->m_oneSecondTimer.setObjectName(this->objectName().append(":m_oneSecondTimer")); connect(&m_oneSecondTimer, &QTimer::timeout, this, &CSimulatorCommon::ps_oneSecondTimer); this->m_oneSecondTimer.start(1000); - // provider signals - bool c = remoteAircraftProvider->connectRemoteAircraftProviderSignals( - std::bind(&CSimulatorCommon::ps_remoteProviderAddAircraftSituation, this, std::placeholders::_1), - std::bind(&CSimulatorCommon::ps_remoteProviderAddAircraftParts, this, std::placeholders::_1), - std::bind(&CSimulatorCommon::ps_remoteProviderRemovedAircraft, this, std::placeholders::_1), - std::bind(static_cast(&CSimulatorCommon::ps_recalculateRenderedAircraft), this, std::placeholders::_1) - ); - Q_ASSERT(c); - Q_UNUSED(c); - // info CLogMessage(this).info("Initialized simulator driver %1") << m_simulatorPluginInfo.toQString(); } + CSimulatorCommon::~CSimulatorCommon() { } + bool CSimulatorCommon::logicallyAddRemoteAircraft(const CSimulatedAircraft &remoteAircraft) { if (!remoteAircraft.isEnabled()) { return false; } @@ -195,6 +197,18 @@ namespace BlackCore return m_simulatorSetup; } + void CSimulatorCommon::unload() + { + this->disconnectFrom(); // disconnect from simulator + for (QMetaObject::Connection &c : m_remoteAircraftProviderConnections) + { + QObject::disconnect(c); + } + m_remoteAircraftProviderConnections.clear(); + this->disconnect(); + CLogHandler::instance()->disconnect(); + } + CLength CSimulatorCommon::getRenderedDistanceBoundary() const { return CLength(20.0, CLengthUnit::NM()); @@ -282,31 +296,32 @@ namespace BlackCore // when changing back from restricted->unrestricted an one time update is required if (!snapshot.isRestricted() && !snapshot.isRestrictionChanged()) { return; } - // we will handle snapshot - emit airspaceSnapshotHandled(); - - - // restricted snapshot values - if (!snapshot.isRenderingEnabled()) + // restricted snapshot values? + if (snapshot.isRenderingEnabled()) { - this->physicallyRemoveAllRemoteAircraft(); - return; - } + CCallsignSet callsignsInSimulator(physicallyRenderedAircraft()); + CCallsignSet callsignsToBeRemoved(callsignsInSimulator.difference(snapshot.getEnabledAircraftCallsignsByDistance())); + CCallsignSet callsignsToBeAdded(snapshot.getEnabledAircraftCallsignsByDistance().difference(callsignsInSimulator)); + this->physicallyRemoveMultipleRemoteAircraft(callsignsToBeRemoved); - CCallsignSet callsignsInSimulator(physicallyRenderedAircraft()); - CCallsignSet callsignsToBeRemoved(callsignsInSimulator.difference(snapshot.getEnabledAircraftCallsignsByDistance())); - CCallsignSet callsignsToBeAdded(snapshot.getEnabledAircraftCallsignsByDistance().difference(callsignsInSimulator)); - this->physicallyRemoveMultipleRemoteAircraft(callsignsToBeRemoved); - - if (!callsignsToBeAdded.isEmpty()) - { - CSimulatedAircraftList aircraftToBeAdded(getAircraftInRange().findByCallsigns(callsignsToBeAdded)); // thread safe copy - for (const CSimulatedAircraft &aircraft : aircraftToBeAdded) + if (!callsignsToBeAdded.isEmpty()) { - Q_ASSERT_X(aircraft.isEnabled(), Q_FUNC_INFO, "Disabled aircraft detected as to be added"); - this->physicallyAddRemoteAircraft(aircraft); + CSimulatedAircraftList aircraftToBeAdded(getAircraftInRange().findByCallsigns(callsignsToBeAdded)); // thread safe copy + for (const CSimulatedAircraft &aircraft : aircraftToBeAdded) + { + Q_ASSERT_X(aircraft.isEnabled(), Q_FUNC_INFO, "Disabled aircraft detected as to be added"); + this->physicallyAddRemoteAircraft(aircraft); + } } } + else + { + this->physicallyRemoveAllRemoteAircraft(); + } + + // we handled snapshot + emit airspaceSnapshotHandled(); + } void CSimulatorCommon::ps_remoteProviderAddAircraftSituation(const CAircraftSituation &situation) diff --git a/src/blackcore/simulator_common.h b/src/blackcore/simulator_common.h index c676fdbb3..598fb88ca 100644 --- a/src/blackcore/simulator_common.h +++ b/src/blackcore/simulator_common.h @@ -41,6 +41,9 @@ namespace BlackCore Q_OBJECT public: + //! Destructor + virtual ~CSimulatorCommon(); + //! \copydoc ISimulator::getMaxRenderedAircraft virtual int getMaxRenderedAircraft() const override; @@ -83,6 +86,9 @@ namespace BlackCore //! \copydoc IContextSimulator::getSimulatorSetup virtual const BlackMisc::Simulation::CSimulatorSetup &getSimulatorSetup() const override; + //! \copydoc IContextSimulator::unload + virtual void unload(); + //! \copydoc IContextSimulator::deleteAllRenderingRestrictions virtual void deleteAllRenderingRestrictions() override; @@ -132,6 +138,7 @@ namespace BlackCore bool m_debugMessages = false; //!< Display debug messages bool m_blinkCycle = false; //!< use for highlighting + bool m_pausedSimFreezesInterpolation = false; //!< paused simulator will also pause interpolation (so AI aircraft will hold) IInterpolator *m_interpolator = nullptr; //!< interpolator instance qint64 m_highlightEndTimeMsEpoch = 0; //!< end highlighting int m_timerCounter = 0; //!< allows to calculate n seconds @@ -142,6 +149,8 @@ namespace BlackCore BlackMisc::Aviation::CCallsignSet m_callsignsToBeRendered; //!< callsigns which will be rendered int m_maxRenderedAircraft = MaxAircraftInfinite; //!< max.rendered aircraft BlackMisc::PhysicalQuantities::CLength m_maxRenderedDistance { 0.0, BlackMisc::PhysicalQuantities::CLengthUnit::nullUnit()}; //!< max.distance for rendering + QList m_remoteAircraftProviderConnections; //!< connected signal/slots + }; } // namespace diff --git a/src/blackmisc/simulation/remoteaircraftprovider.h b/src/blackmisc/simulation/remoteaircraftprovider.h index 2e8f6b916..6ab931eb1 100644 --- a/src/blackmisc/simulation/remoteaircraftprovider.h +++ b/src/blackmisc/simulation/remoteaircraftprovider.h @@ -100,17 +100,14 @@ namespace BlackMisc virtual ~IRemoteAircraftProvider() {} //! Connect signals to slot receiver. As the interface is no QObject, slots can not be connected directly. - virtual bool connectRemoteAircraftProviderSignals( + //! In order to disconnect a list of connections is provided, which have to be disconnected manually. + //! \note connections are direct as functors have no parameter for connection type + virtual QList connectRemoteAircraftProviderSignals( std::function addedSituationSlot, std::function addedPartsSlot, std::function removedAircraftSlot, std::function aircraftSnapshot ) = 0; - - //! Disconnect signals from receiver. As the interface is no QObject, slots can not be connected directly. - virtual bool disconnectRemoteAircraftProviderSignals( - QObject *receiver - ) = 0; }; //! Class which can be directly used to access an \sa IRemoteAircraftProvider object diff --git a/src/blackmisc/simulation/remoteaircraftproviderdummy.cpp b/src/blackmisc/simulation/remoteaircraftproviderdummy.cpp index 8d1d65be6..d5d0e4855 100644 --- a/src/blackmisc/simulation/remoteaircraftproviderdummy.cpp +++ b/src/blackmisc/simulation/remoteaircraftproviderdummy.cpp @@ -65,25 +65,21 @@ namespace BlackMisc return remoteAircraftParts(callsign).size() > 0; } - bool CRemoteAircraftProviderDummy::connectRemoteAircraftProviderSignals( + QList CRemoteAircraftProviderDummy::connectRemoteAircraftProviderSignals( std::function situationSlot, std::function partsSlot, std::function removedAircraftSlot, std::function aircraftSnapshotSlot ) { - bool s1 = connect(this, &CRemoteAircraftProviderDummy::addedRemoteAircraftSituation, situationSlot); - bool s2 = connect(this, &CRemoteAircraftProviderDummy::addedRemoteAircraftParts, partsSlot); - bool s3 = connect(this, &CRemoteAircraftProviderDummy::removedRemoteAircraft, removedAircraftSlot); - bool s4 = connect(this, &CRemoteAircraftProviderDummy::airspaceAircraftSnapshot, aircraftSnapshotSlot); - - return s1 && s2 && s3 && s4; - } - - bool CRemoteAircraftProviderDummy::disconnectRemoteAircraftProviderSignals(QObject *receiver) - { - if (!receiver) { return false; } - return this->disconnect(receiver); + QList c( + { + connect(this, &CRemoteAircraftProviderDummy::addedRemoteAircraftSituation, situationSlot) , + connect(this, &CRemoteAircraftProviderDummy::addedRemoteAircraftParts, partsSlot) , + connect(this, &CRemoteAircraftProviderDummy::removedRemoteAircraft, removedAircraftSlot) , + connect(this, &CRemoteAircraftProviderDummy::airspaceAircraftSnapshot, aircraftSnapshotSlot) + }); + return c; } bool CRemoteAircraftProviderDummy::updateAircraftEnabled(const CCallsign &callsign, bool enabledForRendering, const QString &originator) diff --git a/src/blackmisc/simulation/remoteaircraftproviderdummy.h b/src/blackmisc/simulation/remoteaircraftproviderdummy.h index 6535f2c02..9fbe5af91 100644 --- a/src/blackmisc/simulation/remoteaircraftproviderdummy.h +++ b/src/blackmisc/simulation/remoteaircraftproviderdummy.h @@ -60,16 +60,13 @@ namespace BlackMisc virtual bool isRemoteAircraftSupportingParts(const Aviation::CCallsign &callsign) const override; //! \copydoc IRemoteAircraftProvider::connectRemoteAircraftProviderSignals - virtual bool connectRemoteAircraftProviderSignals( + virtual QList connectRemoteAircraftProviderSignals( std::function addedSituationSlot, std::function addedPartsSlot, std::function removedAircraftSlot, std::function aircraftSnapshotSlot ) override; - //! \copydoc IRemoteAircraftProvider::disconnectRemoteAircraftProviderSignals - virtual bool disconnectRemoteAircraftProviderSignals(QObject *receiver) override; - //! \copydoc IRemoteAircraftProvider::updateAircraftEnabled virtual bool updateAircraftEnabled(const BlackMisc::Aviation::CCallsign &callsign, bool enabledForRendering, const QString &originator) override; diff --git a/src/plugins/simulator/fsx/simulator_fsx.cpp b/src/plugins/simulator/fsx/simulator_fsx.cpp index 19011d375..95ede72f9 100644 --- a/src/plugins/simulator/fsx/simulator_fsx.cpp +++ b/src/plugins/simulator/fsx/simulator_fsx.cpp @@ -56,6 +56,7 @@ namespace BlackSimPlugin CSimulatorFsx::~CSimulatorFsx() { disconnectFrom(); + // fsuipc is disconnected in CSimulatorFsCommon } bool CSimulatorFsx::isConnected() const @@ -168,7 +169,7 @@ namespace BlackSimPlugin emit modelMatchingCompleted(aircraftAfterModelApplied); // create AI - if (isSimulating()) + if (isConnected()) { //! \todo FSX driver if exists, recreate (new model?, new ICAO code) QByteArray m = aircraftModel.getModelString().toLocal8Bit(); @@ -304,7 +305,9 @@ namespace BlackSimPlugin void CSimulatorFsx::onSimRunning() { if (m_simRunning) { return; } - m_simRunning = true; + qDebug() << "onSimRunning"; + m_simRunning = true; // only place where this should be set to true + m_simConnected = true; HRESULT hr = SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraft, CSimConnectDefinitions::DataOwnAircraft, SIMCONNECT_OBJECT_ID_USER, SIMCONNECT_PERIOD_VISUAL_FRAME); @@ -340,11 +343,7 @@ namespace BlackSimPlugin void CSimulatorFsx::onSimStopped() { - if (m_simRunning) - { - m_simRunning = false; - mapperInstance()->gracefulShutdown(); // stop background reading if ongoing - } + m_simRunning = false; emitSimulatorCombinedStatus(); } @@ -355,8 +354,14 @@ namespace BlackSimPlugin void CSimulatorFsx::onSimExit() { + // reset complete state, we are going down m_simConnected = false; - this->onSimStopped(); + m_simRunning = false; + m_simPaused = false; + + // stop background reading if ongoing + mapperInstance()->gracefulShutdown(); + emitSimulatorCombinedStatus(); } void CSimulatorFsx::updateOwnAircraftFromSimulator(DataDefinitionOwnAircraft simulatorOwnAircraft) @@ -503,12 +508,13 @@ namespace BlackSimPlugin initDataDefinitionsWhenConnected(); m_simconnectTimerId = startTimer(10); m_simConnected = true; - emitSimulatorCombinedStatus(); } else { + if (m_simconnectTimerId >= 0) { killTimer(m_simconnectTimerId); } m_simConnected = false; + m_simRunning = false; emitSimulatorCombinedStatus(); } } @@ -549,6 +555,7 @@ namespace BlackSimPlugin hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventObjectRemoved, "ObjectRemoved"); hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventFrame, "Frame"); hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventPause, "Pause"); + hr += SimConnect_SubscribeToSystemEvent(m_hSimConnect, SystemEventFlightLoaded, "FlightLoaded"); if (hr != S_OK) { CLogMessage(this).error("FSX plugin error: %1") << "SimConnect_SubscribeToSystemEvent failed"; @@ -624,7 +631,7 @@ namespace BlackSimPlugin Q_ASSERT_X(BlackCore::isCurrentThreadCreatingThread(this), Q_FUNC_INFO, "thread"); // nothing to do, reset request id and exit - if (this->isPaused()) { return; } // no interpolation while paused + if (this->isPaused() && this->m_pausedSimFreezesInterpolation) { return; } // no interpolation while paused int remoteAircraftNo = this->getAircraftInRangeCount(); if (remoteAircraftNo < 1) { m_interpolationRequest = 0; return; } diff --git a/src/plugins/simulator/fsx/simulator_fsx.h b/src/plugins/simulator/fsx/simulator_fsx.h index 95bc48d63..291af332b 100644 --- a/src/plugins/simulator/fsx/simulator_fsx.h +++ b/src/plugins/simulator/fsx/simulator_fsx.h @@ -49,6 +49,7 @@ namespace BlackSimPlugin SystemEventSlewToggle, SystemEventFrame, SystemEventPause, + SystemEventFlightLoaded, EventPauseToggle, EventFreezeLat, EventFreezeAlt, @@ -127,15 +128,6 @@ namespace BlackSimPlugin //! \copydoc ISimulator::physicallyRenderedAircraft virtual BlackMisc::Aviation::CCallsignSet physicallyRenderedAircraft() const override; - //! Called when sim has started - void onSimRunning(); - - //! Called when sim has stopped - void onSimStopped(); - - //! Slot called every visual frame - void onSimFrame(); - //! Called when data about our own aircraft are received void updateOwnAircraftFromSimulator(DataDefinitionOwnAircraft simulatorOwnAircraft); @@ -145,9 +137,6 @@ namespace BlackSimPlugin //! Set ID of a SimConnect object void setSimConnectObjectID(DWORD requestID, DWORD objectID); - //! \private - void onSimExit(); - protected: //! Timer event (our SimConnect event loop), runs \sa ps_dispatch //! \sa m_simconnectTimerId @@ -161,6 +150,18 @@ namespace BlackSimPlugin void ps_connectToFinished(); private: + //! Called when sim has started + void onSimRunning(); + + //! Slot called every visual frame + void onSimFrame(); + + //! Called when simulator has stopped, e.g. by selecting the "select aircraft screen" + void onSimStopped(); + + //! Simulator is going down + void onSimExit(); + //! Remove a remote aircraft bool physicallyRemoveRemoteAircraft(const CSimConnectObject &simObject); diff --git a/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp b/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp index e30ddfb95..53dc972f2 100644 --- a/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp +++ b/src/plugins/simulator/fsx/simulator_fsx_simconnectproc.cpp @@ -60,18 +60,18 @@ namespace BlackSimPlugin } case SIMCONNECT_RECV_ID_QUIT: { - simulatorFsx->onSimExit(); // TODO: What is the difference to sim stopped? + simulatorFsx->onSimExit(); break; } case SIMCONNECT_RECV_ID_EVENT: { SIMCONNECT_RECV_EVENT *event = static_cast(pData); - switch (event->uEventID) { case SystemEventSimStatus: { - if (event->dwData) + bool running = event->dwData ? true : false; + if (running) { simulatorFsx->onSimRunning(); } @@ -83,22 +83,27 @@ namespace BlackSimPlugin } case SystemEventPause: { - simulatorFsx->m_simPaused = event->dwData ? true : false; + bool p = event->dwData ? true : false; + simulatorFsx->m_simPaused = p; + simulatorFsx->emitSimulatorCombinedStatus(); break; } + default: + break; } break; } case SIMCONNECT_RECV_ID_EVENT_OBJECT_ADDREMOVE: { SIMCONNECT_RECV_EVENT_OBJECT_ADDREMOVE *event = static_cast(pData); - if (event->uEventID == SystemEventObjectAdded) + switch (event->uEventID) { - // - } - else if (event->uEventID == SystemEventObjectRemoved) - { - // + case SystemEventObjectAdded: + break; + case SystemEventObjectRemoved: + break; + default: + break; } break; } @@ -171,7 +176,7 @@ namespace BlackSimPlugin for (unsigned i = 0; i < pAirportList->dwArraySize; ++i) { SIMCONNECT_DATA_FACILITY_AIRPORT *pFacilityAirport = pAirportList->rgData + i; - if (!pFacilityAirport) break; + if (!pFacilityAirport) { break; } const QString icao(pFacilityAirport->Icao); if (icao.isEmpty()) { continue; } // airfield without ICAO code if (!CAirportIcaoCode::isValidIcaoDesignator(icao)) { continue; } // tiny airfields in SIM @@ -200,6 +205,18 @@ namespace BlackSimPlugin } break; } + case SIMCONNECT_RECV_ID_EVENT_FILENAME: + { + SIMCONNECT_RECV_EVENT_FILENAME *event = static_cast(pData); + switch (event->uEventID) + { + case SystemEventFlightLoaded: + break; + default: + break; + } + break; + } default: break;