diff --git a/src/blackcore/simulator_common.cpp b/src/blackcore/simulator_common.cpp index 684a97659..6e45f1405 100644 --- a/src/blackcore/simulator_common.cpp +++ b/src/blackcore/simulator_common.cpp @@ -200,6 +200,8 @@ namespace BlackCore void CSimulatorCommon::unload() { this->disconnectFrom(); // disconnect from simulator + + // disconnect as many signals as possible for (QMetaObject::Connection &c : m_remoteAircraftProviderConnections) { QObject::disconnect(c); diff --git a/src/plugins/simulator/fs9/simulator_fs9.cpp b/src/plugins/simulator/fs9/simulator_fs9.cpp index 36ecfdd27..9f4881f82 100644 --- a/src/plugins/simulator/fs9/simulator_fs9.cpp +++ b/src/plugins/simulator/fs9/simulator_fs9.cpp @@ -88,7 +88,9 @@ namespace BlackSimPlugin bool CSimulatorFs9::disconnectFrom() { disconnectAllClients(); - m_fsuipc->disconnect(); + + // disconnect FSUIPC and status + CSimulatorFsCommon::disconnectFrom(); return true; } diff --git a/src/plugins/simulator/fscommon/simulator_fscommon.cpp b/src/plugins/simulator/fscommon/simulator_fscommon.cpp index e226b434d..053d6ade2 100644 --- a/src/plugins/simulator/fscommon/simulator_fscommon.cpp +++ b/src/plugins/simulator/fscommon/simulator_fscommon.cpp @@ -50,6 +50,10 @@ namespace BlackSimPlugin bool CSimulatorFsCommon::disconnectFrom() { if (this->m_fsuipc) { this->m_fsuipc->disconnect(); } + + // reset flags + m_simPaused = false; + emitSimulatorCombinedStatus(); return true; } diff --git a/src/plugins/simulator/fsx/simulator_fsx.cpp b/src/plugins/simulator/fsx/simulator_fsx.cpp index 22a6ca2e4..092709469 100644 --- a/src/plugins/simulator/fsx/simulator_fsx.cpp +++ b/src/plugins/simulator/fsx/simulator_fsx.cpp @@ -66,7 +66,7 @@ namespace BlackSimPlugin bool CSimulatorFsx::isSimulating() const { - return m_simRunning; + return m_simSimulating; } bool CSimulatorFsx::connectTo() @@ -74,6 +74,9 @@ namespace BlackSimPlugin if (m_simConnected) { return true; } if (FAILED(SimConnect_Open(&m_hSimConnect, BlackMisc::CProject::systemNameAndVersionChar(), nullptr, 0, 0, 0))) { + m_simConnected = false; + m_simPaused = false; + m_simSimulating = false; emitSimulatorCombinedStatus(); return false; } @@ -85,7 +88,6 @@ namespace BlackSimPlugin initWhenConnected(); m_simconnectTimerId = startTimer(10); m_simConnected = true; - emitSimulatorCombinedStatus(); return true; } @@ -109,22 +111,28 @@ namespace BlackSimPlugin bool CSimulatorFsx::disconnectFrom() { if (!m_simConnected) { return true; } - if (m_hSimConnect) - { - SimConnect_Close(m_hSimConnect); - this->m_fsuipc->disconnect(); - } + + // stop mapper init + //! \todo mapper shutdown in FSX, review keep it? + // mapperInstance()->gracefulShutdown(); if (m_simconnectTimerId) { killTimer(m_simconnectTimerId); } - m_hSimConnect = nullptr; - m_simconnectTimerId = -1; - m_simConnected = false; + if (m_hSimConnect) + { + SimConnect_Close(m_hSimConnect); + m_hSimConnect = nullptr; + } - emitSimulatorCombinedStatus(); + m_simConnected = false; + m_simSimulating = false; + m_simconnectTimerId = -1; + + // emit status and disconnect FSUIPC + CSimulatorFsCommon::disconnectFrom(); return true; } @@ -295,9 +303,8 @@ namespace BlackSimPlugin void CSimulatorFsx::onSimRunning() { - if (m_simRunning) { return; } - qDebug() << "onSimRunning"; - m_simRunning = true; // only place where this should be set to true + if (m_simSimulating) { return; } + m_simSimulating = true; // only place where this should be set to true m_simConnected = true; HRESULT hr = SimConnect_RequestDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::RequestOwnAircraft, CSimConnectDefinitions::DataOwnAircraft, @@ -334,7 +341,7 @@ namespace BlackSimPlugin void CSimulatorFsx::onSimStopped() { - m_simRunning = false; + m_simSimulating = false; emitSimulatorCombinedStatus(); } @@ -346,13 +353,7 @@ namespace BlackSimPlugin void CSimulatorFsx::onSimExit() { // reset complete state, we are going down - m_simConnected = false; - m_simRunning = false; - m_simPaused = false; - - // stop background reading if ongoing - mapperInstance()->gracefulShutdown(); - emitSimulatorCombinedStatus(); + disconnectFrom(); } void CSimulatorFsx::updateOwnAircraftFromSimulator(DataDefinitionOwnAircraft simulatorOwnAircraft) @@ -477,7 +478,24 @@ namespace BlackSimPlugin void CSimulatorFsx::ps_dispatch() { - SimConnect_CallDispatch(m_hSimConnect, SimConnectProc, this); + HRESULT hr = SimConnect_CallDispatch(m_hSimConnect, SimConnectProc, this); + if (hr != S_OK) + { + m_dispatchErrors++; + if (m_dispatchErrors == 2) + { + // 2nd time, an error / avoid multiple messages + // idea: if it happens once ignore + CLogMessage(this).error("FSX: Dispatch error"); + } + else if (m_dispatchErrors > 5) + { + // this normally happens during a FSX crash or shutdown + this->disconnectFrom(); + } + return; + } + m_dispatchErrors = 0; if (m_useFsuipc && m_fsuipc) { CSimulatedAircraft fsuipcAircraft(getOwnAircraft()); @@ -505,7 +523,7 @@ namespace BlackSimPlugin { if (m_simconnectTimerId >= 0) { killTimer(m_simconnectTimerId); } m_simConnected = false; - m_simRunning = false; + m_simSimulating = false; emitSimulatorCombinedStatus(); } } diff --git a/src/plugins/simulator/fsx/simulator_fsx.h b/src/plugins/simulator/fsx/simulator_fsx.h index bb5e8023c..d1c86cb83 100644 --- a/src/plugins/simulator/fsx/simulator_fsx.h +++ b/src/plugins/simulator/fsx/simulator_fsx.h @@ -186,15 +186,16 @@ namespace BlackSimPlugin static const int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles before updating cockpit again bool m_simConnected = false; //!< Is simulator connected? - bool m_simRunning = false; //!< Simulator running? + bool m_simSimulating = false; //!< Simulator running? bool m_useSbOffsets = true; //!< with SB offsets int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time int m_simconnectTimerId = -1; //!< Timer identifier int m_skipCockpitUpdateCycles = 0; //!< Skip some update cycles to allow changes in simulator cockpit to be set int m_interpolationRequest = 0; //!< current interpolation request int m_interpolationsSkipped = 0; //!< number of skipped interpolation request - HANDLE m_hSimConnect = nullptr; //!< Handle to SimConnect object int m_nextObjID = 1; //!< object ID TODO: also used as request id, where to we place other request ids as for facilities + int m_dispatchErrors = 0; //!< numer of dispatched failed, \sa ps_dispatch + HANDLE m_hSimConnect = nullptr; //!< Handle to SimConnect object QHash m_simConnectObjects; QFutureWatcher m_watcherConnect;