diff --git a/src/blackcore/simulatorcommon.cpp b/src/blackcore/simulatorcommon.cpp index f32863cf7..28ac78f07 100644 --- a/src/blackcore/simulatorcommon.cpp +++ b/src/blackcore/simulatorcommon.cpp @@ -194,23 +194,26 @@ namespace BlackCore return false; } - void CSimulatorCommon::debugLogMessage(const QString &msg) const + void CSimulatorCommon::debugLogMessage(const QString &msg) { if (!this->showDebugLogMessage()) { return; } if (msg.isEmpty()) { return; } - CLogMessage(this).info(msg); + const CStatusMessage m = CStatusMessage(this).info("%1") << msg; + emit this->driverMessages(m); } - void CSimulatorCommon::debugLogMessage(const QString &funcInfo, const QString &msg) const + void CSimulatorCommon::debugLogMessage(const QString &funcInfo, const QString &msg) { if (!this->showDebugLogMessage()) { return; } if (msg.isEmpty()) { return; } - CLogMessage(this).info("%1 %2") << msg << funcInfo; + const CStatusMessage m = CStatusMessage(this).info("%1 %2") << msg << funcInfo; + emit this->driverMessages(m); } bool CSimulatorCommon::showDebugLogMessage() const { - return this->getInterpolationSetupGlobal().showSimulatorDebugMessages(); + const bool show = this->getInterpolationSetupGlobal().showSimulatorDebugMessages(); + return show; } void CSimulatorCommon::reverseLookupAndUpdateOwnAircraftModel(const BlackMisc::Simulation::CAircraftModel &model) diff --git a/src/blackcore/simulatorcommon.h b/src/blackcore/simulatorcommon.h index 91f0a44a6..a4217eab3 100644 --- a/src/blackcore/simulatorcommon.h +++ b/src/blackcore/simulatorcommon.h @@ -219,11 +219,11 @@ namespace BlackCore //! Display a debug log message based on BlackMisc::Simulation::CInterpolationAndRenderingSetup //! remark shows log messages of functions calls - void debugLogMessage(const QString &msg) const; + void debugLogMessage(const QString &msg); //! Display a debug log message based on BlackMisc::Simulation::CInterpolationAndRenderingSetup //! remark shows log messages of functions calls - void debugLogMessage(const QString &funcInfo, const QString &msg) const; + void debugLogMessage(const QString &funcInfo, const QString &msg); //! Show log messages? bool showDebugLogMessage() const; diff --git a/src/blackmisc/simulation/interpolator.cpp b/src/blackmisc/simulation/interpolator.cpp index 6c9cca1c8..19a84bf82 100644 --- a/src/blackmisc/simulation/interpolator.cpp +++ b/src/blackmisc/simulation/interpolator.cpp @@ -154,12 +154,11 @@ namespace BlackMisc // make sure we can also interpolate parts only (needed in unit tests) if (aircraftNumber < 0) { aircraftNumber = 0; } const bool init = this->initIniterpolationStepData(currentTimeSinceEpoc, setup, aircraftNumber); + Q_ASSERT_X(!m_currentInterpolationStatus.isInterpolated(), Q_FUNC_INFO, "Expect reset status"); if (!m_unitTest && !init) { break; } // failure in real scenarios, unit tests move on - Q_ASSERT_X(m_currentTimeMsSinceEpoch > 0, Q_FUNC_INFO, "No valid timestamp, interpolator initialized?"); const CAircraftSituation interpolatedSituation = this->getInterpolatedSituation(); const CAircraftParts interpolatedParts = this->getInterpolatedOrGuessedParts(aircraftNumber); - result.setValues(interpolatedSituation, interpolatedParts); } while (false); @@ -171,6 +170,7 @@ namespace BlackMisc template CAircraftSituation CInterpolator::getInterpolatedSituation() { + Q_ASSERT_X(!m_currentInterpolationStatus.isInterpolated(), Q_FUNC_INFO, "Expect reset status"); if (m_currentSituations.isEmpty()) { m_lastSituation = CAircraftSituation::null(); @@ -219,7 +219,10 @@ namespace BlackMisc } // status + Q_ASSERT_X(currentSituation.hasMSLGeodeticHeight(), Q_FUNC_INFO, "No MSL altitude"); m_currentInterpolationStatus.setInterpolatedAndCheckSituation(true, currentSituation); + m_lastSituation = currentSituation; + Q_ASSERT_X(m_currentInterpolationStatus.hasValidInterpolatedSituation(), Q_FUNC_INFO, "Expect valid situation"); // logging if (this->doLogging()) @@ -238,7 +241,6 @@ namespace BlackMisc } // bye - m_lastSituation = currentSituation; return currentSituation; } diff --git a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h index 3b68d5725..3f42a2c49 100644 --- a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h +++ b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h @@ -72,6 +72,17 @@ namespace BlackSimPlugin char title[256]; //!< Aircraft model string }; + //! Data struct of aircraft model data + struct DataDefinitionRemoteAircraftModel + { + char atcType[32]; //!< type + char atcModel[32]; //!< model + char atcId[32]; //!< id + char atcAirlineNumber[64]; //!< airline number + char atcFlightNumber[8]; //!< flight number (168) + char title[256]; //!< Aircraft model string + }; + //! Data struct of remote aircraft parts struct DataDefinitionRemoteAircraftPartsWithoutLights { diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp index f8a3e92fb..9a6d0a5ce 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp @@ -481,6 +481,14 @@ namespace BlackSimPlugin return id; } + bool CSimulatorFsxCommon::isValidSimObjectNotPendingRemoved(const CSimConnectObject &simObject) const + { + if (!simObject.hasValidRequestAndObjectId()) { return false; } + if (simObject.isPendingRemoved()) { return false; } + if (!m_simConnectObjects.contains(simObject.getCallsign())) { return false; } // removed in meantime + return true; + } + bool CSimulatorFsxCommon::triggerAutoTraceSendId() { if (m_traceSendId) { return false; } // no need @@ -755,13 +763,20 @@ namespace BlackSimPlugin // request data on object this->requestPositionDataForSimObject(simObject); this->requestLightsForSimObject(simObject); + this->requestModelInfoForSimObject(simObject); this->removeFromAddPendingAndAddAgainAircraft(callsign); // no longer try to add const bool updated = this->updateAircraftRendered(callsign, true); if (updated) { emit aircraftRenderingChanged(simObject.getAircraft()); - if (this->showDebugLogMessage()) { this->debugLogMessage(Q_FUNC_INFO, QString("CS: '%1' model: '%2' verified, request/object id: %3 %4").arg(callsign.toQString(), remoteAircraft.getModelString()).arg(requestId).arg(objectId)); } + static const QString debugMsg("CS: '%1' model: '%2' verified, request/object id: %3 %4"); + if (this->showDebugLogMessage()) { this->debugLogMessage(Q_FUNC_INFO, debugMsg.arg(callsign.toQString(), remoteAircraft.getModelString()).arg(requestId).arg(objectId)); } + } + else + { + CLogMessage(this).warning("Verified aircraft '%1' model '%2', request/object id: %3 %4 already rendered") << + callsign.asString() << remoteAircraft.getModelString() << objectId; } } while (false); @@ -773,7 +788,7 @@ namespace BlackSimPlugin emit this->physicallyAddingRemoteModelFailed(CSimulatedAircraft(), msg); } - // trigger new adding + // trigger new adding from pending if any if (!m_addPendingAircraft.isEmpty()) { this->addPendingAircraftAfterAdded(); @@ -1049,7 +1064,7 @@ namespace BlackSimPlugin this->debugLogMessage(Q_FUNC_INFO, QString("CS: '%1' pending callsigns: '%2', pending objects: '%3'").arg(newRemoteAircraft.getCallsignAsString(), m_addPendingAircraft.getCallsignStrings().join(", "), m_simConnectObjects.getPendingAddedCallsigns().getCallsignStrings().join(", "))); } - // do we need to remove/add again because something has changed + // do we need to remove/add again because something has changed? if (m_simConnectObjects.contains(callsign)) { const CSimConnectObject simObject = m_simConnectObjects[callsign]; @@ -1194,12 +1209,16 @@ namespace BlackSimPlugin CSimConnectObject &simObject = m_simConnectObjects[callsign]; if (simObject.isPendingRemoved()) { return true; } - const bool pendingAdded = simObject.isPendingAdded(); + // check for pending objects + m_addPendingAircraft.removeByCallsign(callsign); // just in case still in list of pending aircraft + const bool pendingAdded = simObject.isPendingAdded(); // already added in simulator, but not yet confirmed const bool stillWaitingForLights = !simObject.hasCurrentLightsInSimulator(); if (pendingAdded || stillWaitingForLights) { // problem: we try to delete an aircraft just requested to be added // best solution so far, call remove again with a delay + CLogMessage(this).warning("Object: %1 pending added: %2 / lights: %3 about to be removed") + << simObject.toQString() << boolToYesNo(pendingAdded) << boolToYesNo(stillWaitingForLights); simObject.fakeCurrentLightsInSimulator(); // next time looks like we have lights QPointer myself(this); QTimer::singleShot(2000, this, [ = ] @@ -1210,8 +1229,10 @@ namespace BlackSimPlugin return false; // not yet deleted } - // avoid further data from simulator + // no more data from simulator this->stopRequestingDataForSimObject(simObject); + + // mark as removed simObject.setPendingRemoved(true); if (this->showDebugLogMessage()) { this->debugLogMessage(Q_FUNC_INFO, QString("CS: '%1' request/object id: %2/%3").arg(callsign.toQString()).arg(simObject.getRequestId()).arg(simObject.getObjectId())); } @@ -1720,9 +1741,7 @@ namespace BlackSimPlugin bool CSimulatorFsxCommon::requestLightsForSimObject(const CSimConnectObject &simObject) { - if (!simObject.hasValidRequestAndObjectId()) { return false; } - if (simObject.isPendingRemoved()) { return false; } - if (!m_simConnectObjects.contains(simObject.getCallsign())) { return false; } // removed in meantime + if (!this->isValidSimObjectNotPendingRemoved(simObject)) { return false; } if (!m_hSimConnect) { return false; } // always request, not only when something has changed @@ -1740,6 +1759,26 @@ namespace BlackSimPlugin return false; } + bool CSimulatorFsxCommon::requestModelInfoForSimObject(const CSimConnectObject &simObject) + { + if (!this->isValidSimObjectNotPendingRemoved(simObject)) { return false; } + if (!m_hSimConnect) { return false; } + + // always request, not only when something has changed + const SIMCONNECT_DATA_REQUEST_ID requestId = simObject.getRequestId(CSimConnectDefinitions::SimObjectModel); + const HRESULT result = SimConnect_RequestDataOnSimObject( + m_hSimConnect, requestId, + CSimConnectDefinitions::DataRemoteAircraftModelData, simObject.getObjectId(), + SIMCONNECT_PERIOD_ONCE); + if (result == S_OK) + { + if (this->isTracingSendId()) { this->traceSendId(simObject.getObjectId(), Q_FUNC_INFO);} + return true; + } + CLogMessage(this).error("Cannot request model info on object '%1'") << simObject.getObjectId(); + return false; + } + bool CSimulatorFsxCommon::stopRequestingDataForSimObject(const CSimConnectObject &simObject) { if (!simObject.hasValidRequestAndObjectId()) { return false; } @@ -1938,15 +1977,15 @@ namespace BlackSimPlugin CCallsignSet CSimulatorFsxCommon::physicallyRemoveAircraftNotInProvider() { - const CCallsignSet toBeRemoved(getCallsignsMissingInProvider()); - if (toBeRemoved.isEmpty()) { return toBeRemoved; } - for (const CCallsign &callsign : toBeRemoved) + const CCallsignSet callsignsToBeRemoved(getCallsignsMissingInProvider()); + if (callsignsToBeRemoved.isEmpty()) { return callsignsToBeRemoved; } + for (const CCallsign &callsign : callsignsToBeRemoved) { this->physicallyRemoveRemoteAircraft(callsign); } - if (this->showDebugLogMessage()) { this->debugLogMessage(Q_FUNC_INFO, QString("CS: '%1'").arg(toBeRemoved.toStringList().join(", "))); } - return toBeRemoved; + if (this->showDebugLogMessage()) { this->debugLogMessage(Q_FUNC_INFO, QString("CS: '%1'").arg(callsignsToBeRemoved.toStringList().join(", "))); } + return callsignsToBeRemoved; } CSimulatorFsxCommonListener::CSimulatorFsxCommonListener(const CSimulatorPluginInfo &info) : diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h index 8357c28c5..078a9c746 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h @@ -204,6 +204,9 @@ namespace BlackSimPlugin //! Get new request id, overflow safe SIMCONNECT_DATA_REQUEST_ID obtainRequestIdForSimObjTerrainProbe(); + //! Valid CSimConnectObject which is NOT pendig removed + bool isValidSimObjectNotPendingRemoved(const CSimConnectObject &simObject) const; + //! Register help static void registerHelp(); @@ -380,6 +383,9 @@ namespace BlackSimPlugin //! Request lights for a CSimConnectObject bool requestLightsForSimObject(const CSimConnectObject &simObject); + //! Model info for a CSimConnectObject + bool requestModelInfoForSimObject(const CSimConnectObject &simObject); + //! Stop requesting data for CSimConnectObject bool stopRequestingDataForSimObject(const CSimConnectObject &simObject); diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp index e3891f7a5..166cadd1b 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp +++ b/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp @@ -274,6 +274,16 @@ namespace BlackSimPlugin simulatorFsxP3D->triggerUpdateRemoteAircraftFromSimulator(simObject, *remoteAircraftSimData); } } // position + else if (subRequest == CSimConnectDefinitions::SimObjectModel) + { + static_assert(sizeof(DataDefinitionRemoteAircraftModel) == 168 + 256, "DataDefinitionRemoteAircraftModel has an incorrect size."); + const DataDefinitionRemoteAircraftModel *remoteAircraftModel = reinterpret_cast(&pObjData->dwData); + // extra check, but ids should be the same + if (objectId == simObject.getObjectId()) + { + Q_UNUSED(remoteAircraftModel); + } + } // model else if (subRequest == CSimConnectDefinitions::SimObjectLights) { static_assert(sizeof(DataDefinitionRemoteAircraftLights) == 8 * sizeof(double), "DataDefinitionRemoteAircraftLights has an incorrect size.");