Ref T275, Ref T280, Ref T245 FSX simulator improvements

* request model info
* stricter checks (asserts)
* display simulator debug messages in simulator view (not as normal status message)
This commit is contained in:
Klaus Basan
2018-06-27 01:30:04 +02:00
parent 9baa10c5f8
commit 1f689a8830
7 changed files with 94 additions and 23 deletions

View File

@@ -194,23 +194,26 @@ namespace BlackCore
return false; return false;
} }
void CSimulatorCommon::debugLogMessage(const QString &msg) const void CSimulatorCommon::debugLogMessage(const QString &msg)
{ {
if (!this->showDebugLogMessage()) { return; } if (!this->showDebugLogMessage()) { return; }
if (msg.isEmpty()) { 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 (!this->showDebugLogMessage()) { return; }
if (msg.isEmpty()) { 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 bool CSimulatorCommon::showDebugLogMessage() const
{ {
return this->getInterpolationSetupGlobal().showSimulatorDebugMessages(); const bool show = this->getInterpolationSetupGlobal().showSimulatorDebugMessages();
return show;
} }
void CSimulatorCommon::reverseLookupAndUpdateOwnAircraftModel(const BlackMisc::Simulation::CAircraftModel &model) void CSimulatorCommon::reverseLookupAndUpdateOwnAircraftModel(const BlackMisc::Simulation::CAircraftModel &model)

View File

@@ -219,11 +219,11 @@ namespace BlackCore
//! Display a debug log message based on BlackMisc::Simulation::CInterpolationAndRenderingSetup //! Display a debug log message based on BlackMisc::Simulation::CInterpolationAndRenderingSetup
//! remark shows log messages of functions calls //! 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 //! Display a debug log message based on BlackMisc::Simulation::CInterpolationAndRenderingSetup
//! remark shows log messages of functions calls //! 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? //! Show log messages?
bool showDebugLogMessage() const; bool showDebugLogMessage() const;

View File

@@ -154,12 +154,11 @@ namespace BlackMisc
// make sure we can also interpolate parts only (needed in unit tests) // make sure we can also interpolate parts only (needed in unit tests)
if (aircraftNumber < 0) { aircraftNumber = 0; } if (aircraftNumber < 0) { aircraftNumber = 0; }
const bool init = this->initIniterpolationStepData(currentTimeSinceEpoc, setup, aircraftNumber); 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 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?"); Q_ASSERT_X(m_currentTimeMsSinceEpoch > 0, Q_FUNC_INFO, "No valid timestamp, interpolator initialized?");
const CAircraftSituation interpolatedSituation = this->getInterpolatedSituation(); const CAircraftSituation interpolatedSituation = this->getInterpolatedSituation();
const CAircraftParts interpolatedParts = this->getInterpolatedOrGuessedParts(aircraftNumber); const CAircraftParts interpolatedParts = this->getInterpolatedOrGuessedParts(aircraftNumber);
result.setValues(interpolatedSituation, interpolatedParts); result.setValues(interpolatedSituation, interpolatedParts);
} }
while (false); while (false);
@@ -171,6 +170,7 @@ namespace BlackMisc
template <typename Derived> template <typename Derived>
CAircraftSituation CInterpolator<Derived>::getInterpolatedSituation() CAircraftSituation CInterpolator<Derived>::getInterpolatedSituation()
{ {
Q_ASSERT_X(!m_currentInterpolationStatus.isInterpolated(), Q_FUNC_INFO, "Expect reset status");
if (m_currentSituations.isEmpty()) if (m_currentSituations.isEmpty())
{ {
m_lastSituation = CAircraftSituation::null(); m_lastSituation = CAircraftSituation::null();
@@ -219,7 +219,10 @@ namespace BlackMisc
} }
// status // status
Q_ASSERT_X(currentSituation.hasMSLGeodeticHeight(), Q_FUNC_INFO, "No MSL altitude");
m_currentInterpolationStatus.setInterpolatedAndCheckSituation(true, currentSituation); m_currentInterpolationStatus.setInterpolatedAndCheckSituation(true, currentSituation);
m_lastSituation = currentSituation;
Q_ASSERT_X(m_currentInterpolationStatus.hasValidInterpolatedSituation(), Q_FUNC_INFO, "Expect valid situation");
// logging // logging
if (this->doLogging()) if (this->doLogging())
@@ -238,7 +241,6 @@ namespace BlackMisc
} }
// bye // bye
m_lastSituation = currentSituation;
return currentSituation; return currentSituation;
} }

View File

@@ -72,6 +72,17 @@ namespace BlackSimPlugin
char title[256]; //!< Aircraft model string 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 //! Data struct of remote aircraft parts
struct DataDefinitionRemoteAircraftPartsWithoutLights struct DataDefinitionRemoteAircraftPartsWithoutLights
{ {

View File

@@ -481,6 +481,14 @@ namespace BlackSimPlugin
return id; 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() bool CSimulatorFsxCommon::triggerAutoTraceSendId()
{ {
if (m_traceSendId) { return false; } // no need if (m_traceSendId) { return false; } // no need
@@ -755,13 +763,20 @@ namespace BlackSimPlugin
// request data on object // request data on object
this->requestPositionDataForSimObject(simObject); this->requestPositionDataForSimObject(simObject);
this->requestLightsForSimObject(simObject); this->requestLightsForSimObject(simObject);
this->requestModelInfoForSimObject(simObject);
this->removeFromAddPendingAndAddAgainAircraft(callsign); // no longer try to add this->removeFromAddPendingAndAddAgainAircraft(callsign); // no longer try to add
const bool updated = this->updateAircraftRendered(callsign, true); const bool updated = this->updateAircraftRendered(callsign, true);
if (updated) if (updated)
{ {
emit aircraftRenderingChanged(simObject.getAircraft()); 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); while (false);
@@ -773,7 +788,7 @@ namespace BlackSimPlugin
emit this->physicallyAddingRemoteModelFailed(CSimulatedAircraft(), msg); emit this->physicallyAddingRemoteModelFailed(CSimulatedAircraft(), msg);
} }
// trigger new adding // trigger new adding from pending if any
if (!m_addPendingAircraft.isEmpty()) if (!m_addPendingAircraft.isEmpty())
{ {
this->addPendingAircraftAfterAdded(); 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(", "))); 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)) if (m_simConnectObjects.contains(callsign))
{ {
const CSimConnectObject simObject = m_simConnectObjects[callsign]; const CSimConnectObject simObject = m_simConnectObjects[callsign];
@@ -1194,12 +1209,16 @@ namespace BlackSimPlugin
CSimConnectObject &simObject = m_simConnectObjects[callsign]; CSimConnectObject &simObject = m_simConnectObjects[callsign];
if (simObject.isPendingRemoved()) { return true; } 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(); const bool stillWaitingForLights = !simObject.hasCurrentLightsInSimulator();
if (pendingAdded || stillWaitingForLights) if (pendingAdded || stillWaitingForLights)
{ {
// problem: we try to delete an aircraft just requested to be added // problem: we try to delete an aircraft just requested to be added
// best solution so far, call remove again with a delay // 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 simObject.fakeCurrentLightsInSimulator(); // next time looks like we have lights
QPointer<CSimulatorFsxCommon> myself(this); QPointer<CSimulatorFsxCommon> myself(this);
QTimer::singleShot(2000, this, [ = ] QTimer::singleShot(2000, this, [ = ]
@@ -1210,8 +1229,10 @@ namespace BlackSimPlugin
return false; // not yet deleted return false; // not yet deleted
} }
// avoid further data from simulator // no more data from simulator
this->stopRequestingDataForSimObject(simObject); this->stopRequestingDataForSimObject(simObject);
// mark as removed
simObject.setPendingRemoved(true); 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())); } 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) bool CSimulatorFsxCommon::requestLightsForSimObject(const CSimConnectObject &simObject)
{ {
if (!simObject.hasValidRequestAndObjectId()) { return false; } if (!this->isValidSimObjectNotPendingRemoved(simObject)) { return false; }
if (simObject.isPendingRemoved()) { return false; }
if (!m_simConnectObjects.contains(simObject.getCallsign())) { return false; } // removed in meantime
if (!m_hSimConnect) { return false; } if (!m_hSimConnect) { return false; }
// always request, not only when something has changed // always request, not only when something has changed
@@ -1740,6 +1759,26 @@ namespace BlackSimPlugin
return false; 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) bool CSimulatorFsxCommon::stopRequestingDataForSimObject(const CSimConnectObject &simObject)
{ {
if (!simObject.hasValidRequestAndObjectId()) { return false; } if (!simObject.hasValidRequestAndObjectId()) { return false; }
@@ -1938,15 +1977,15 @@ namespace BlackSimPlugin
CCallsignSet CSimulatorFsxCommon::physicallyRemoveAircraftNotInProvider() CCallsignSet CSimulatorFsxCommon::physicallyRemoveAircraftNotInProvider()
{ {
const CCallsignSet toBeRemoved(getCallsignsMissingInProvider()); const CCallsignSet callsignsToBeRemoved(getCallsignsMissingInProvider());
if (toBeRemoved.isEmpty()) { return toBeRemoved; } if (callsignsToBeRemoved.isEmpty()) { return callsignsToBeRemoved; }
for (const CCallsign &callsign : toBeRemoved) for (const CCallsign &callsign : callsignsToBeRemoved)
{ {
this->physicallyRemoveRemoteAircraft(callsign); this->physicallyRemoveRemoteAircraft(callsign);
} }
if (this->showDebugLogMessage()) { this->debugLogMessage(Q_FUNC_INFO, QString("CS: '%1'").arg(toBeRemoved.toStringList().join(", "))); } if (this->showDebugLogMessage()) { this->debugLogMessage(Q_FUNC_INFO, QString("CS: '%1'").arg(callsignsToBeRemoved.toStringList().join(", "))); }
return toBeRemoved; return callsignsToBeRemoved;
} }
CSimulatorFsxCommonListener::CSimulatorFsxCommonListener(const CSimulatorPluginInfo &info) : CSimulatorFsxCommonListener::CSimulatorFsxCommonListener(const CSimulatorPluginInfo &info) :

View File

@@ -204,6 +204,9 @@ namespace BlackSimPlugin
//! Get new request id, overflow safe //! Get new request id, overflow safe
SIMCONNECT_DATA_REQUEST_ID obtainRequestIdForSimObjTerrainProbe(); SIMCONNECT_DATA_REQUEST_ID obtainRequestIdForSimObjTerrainProbe();
//! Valid CSimConnectObject which is NOT pendig removed
bool isValidSimObjectNotPendingRemoved(const CSimConnectObject &simObject) const;
//! Register help //! Register help
static void registerHelp(); static void registerHelp();
@@ -380,6 +383,9 @@ namespace BlackSimPlugin
//! Request lights for a CSimConnectObject //! Request lights for a CSimConnectObject
bool requestLightsForSimObject(const CSimConnectObject &simObject); bool requestLightsForSimObject(const CSimConnectObject &simObject);
//! Model info for a CSimConnectObject
bool requestModelInfoForSimObject(const CSimConnectObject &simObject);
//! Stop requesting data for CSimConnectObject //! Stop requesting data for CSimConnectObject
bool stopRequestingDataForSimObject(const CSimConnectObject &simObject); bool stopRequestingDataForSimObject(const CSimConnectObject &simObject);

View File

@@ -274,6 +274,16 @@ namespace BlackSimPlugin
simulatorFsxP3D->triggerUpdateRemoteAircraftFromSimulator(simObject, *remoteAircraftSimData); simulatorFsxP3D->triggerUpdateRemoteAircraftFromSimulator(simObject, *remoteAircraftSimData);
} }
} // position } // position
else if (subRequest == CSimConnectDefinitions::SimObjectModel)
{
static_assert(sizeof(DataDefinitionRemoteAircraftModel) == 168 + 256, "DataDefinitionRemoteAircraftModel has an incorrect size.");
const DataDefinitionRemoteAircraftModel *remoteAircraftModel = reinterpret_cast<const DataDefinitionRemoteAircraftModel *>(&pObjData->dwData);
// extra check, but ids should be the same
if (objectId == simObject.getObjectId())
{
Q_UNUSED(remoteAircraftModel);
}
} // model
else if (subRequest == CSimConnectDefinitions::SimObjectLights) else if (subRequest == CSimConnectDefinitions::SimObjectLights)
{ {
static_assert(sizeof(DataDefinitionRemoteAircraftLights) == 8 * sizeof(double), "DataDefinitionRemoteAircraftLights has an incorrect size."); static_assert(sizeof(DataDefinitionRemoteAircraftLights) == 8 * sizeof(double), "DataDefinitionRemoteAircraftLights has an incorrect size.");