diff --git a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp index baea5dc25..0cd24e530 100644 --- a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp +++ b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.cpp @@ -23,32 +23,53 @@ namespace BlackSimPlugin const QString &CSimConnectDefinitions::requestToString(Request request) { static const QString ownAircraft("RequestOwnAircraft"); - static const QString removeAircraft("RequestRemoveAircraft"); static const QString title("RequestOwnAircraftTitle"); static const QString simEnv("RequestSimEnvironment"); static const QString sbData("RequestSbData"); - static const QString unknown("unknown"); + static const QString facility("RequestFacility"); static const QString end(""); - static const QString simdata("range simdata"); - static const QString probe("range probe"); - static const QString lights("range lights"); + static const QString unknown("unknown"); switch (request) { case RequestOwnAircraft: return ownAircraft; - case RequestRemoveAircraft: return removeAircraft; case RequestOwnAircraftTitle: return title; case RequestSimEnvironment: return simEnv; case RequestSbData: return sbData; - case RequestRangeForLights: return lights; - case RequestRangeForProbe: return probe; - case RequestRangeForSimData: return simdata; + case RequestFacility: return facility; case RequestEndMarker: return end; default: break; } return unknown; } + const QString &CSimConnectDefinitions::simObjectRequestToString(SimObjectRequest simObjectRequest) + { + static const QString baseId("base id"); + static const QString add("add"); + static const QString remove("remove"); + static const QString lights("lights"); + static const QString pos("position"); + static const QString model("model"); + static const QString misc("misc"); + static const QString end(""); + static const QString unknown("unknown"); + + switch (simObjectRequest) + { + case SimObjectBaseId: return baseId; + case SimObjectAdd: return add; + case SimObjectRemove: return remove; + case SimObjectLights: return lights; + case SimObjectPositionData: return pos; + case SimObjectModel: return model; + case SimObjectMisc: return misc; + case SimObjectEndMarker: return end; + default: break; + } + return unknown; + } + CSimConnectDefinitions::CSimConnectDefinitions() { } HRESULT CSimConnectDefinitions::initDataDefinitionsWhenConnected(const HANDLE hSimConnect) @@ -132,6 +153,8 @@ namespace BlackSimPlugin hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts, "GENERAL ENG COMBUSTION:4", "Bool"); // Lights (other definition) + hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataOwnAircraftTitle, "TITLE", NULL, SIMCONNECT_DATATYPE_STRING256); + hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT STROBE", "Bool"); hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT LANDING", "Bool"); hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftLights, "LIGHT TAXI", "Bool"); @@ -157,11 +180,22 @@ namespace BlackSimPlugin hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition, "PLANE ALTITUDE", "Feet"); hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition, "GROUND ALTITUDE", "Feet"); hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftGetPosition, "STATIC CG TO GROUND", "Feet"); - if (hr != S_OK) { - CLogMessage(static_cast(nullptr)).error("SimConnect error: initRemoteAircraftSimData %1") << hr; + CLogMessage(static_cast(nullptr)).error("SimConnect error: initRemoteAircraftSimData DataRemoteAircraftGetPosition %1") << hr; } + + hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData, "ATC TYPE", NULL, SIMCONNECT_DATATYPE_STRING32); + hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData, "ATC MODEL", NULL, SIMCONNECT_DATATYPE_STRING32); + hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData, "ATC ID", NULL, SIMCONNECT_DATATYPE_STRING32); + hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData, "ATC AIRLINE", NULL, SIMCONNECT_DATATYPE_STRING64); + hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData, "ATC FLIGHT NUMBER", NULL, SIMCONNECT_DATATYPE_STRING8); + hr += SimConnect_AddToDataDefinition(hSimConnect, CSimConnectDefinitions::DataRemoteAircraftModelData, "TITLE", NULL, SIMCONNECT_DATATYPE_STRING256); + if (hr != S_OK) + { + CLogMessage(static_cast(nullptr)).error("SimConnect error: initRemoteAircraftSimData DataRemoteAircraftModelData %1") << hr; + } + return hr; } @@ -180,7 +214,7 @@ namespace BlackSimPlugin HRESULT CSimConnectDefinitions::initSbDataArea(const HANDLE hSimConnect) { HRESULT hr = S_OK; - DWORD sbSize = sizeof(DataDefinitionClientAreaSb); + const DWORD sbSize = sizeof(DataDefinitionClientAreaSb); // We need to know the client area 'name' and map it to a client ID hr += SimConnect_MapClientDataNameToID(hSimConnect, "SquawkBox Data", ClientAreaSquawkBox); diff --git a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h index 62fb8d896..3b68d5725 100644 --- a/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h +++ b/src/plugins/simulator/fsxcommon/simconnectdatadefinition.h @@ -130,8 +130,8 @@ namespace BlackSimPlugin BlackMisc::Aviation::CAircraftLights toLights() const; }; - //! Data for AI object sent back from simulator - struct DataDefinitionRemoteAircraftSimData + //! Data for AI object and probe sent back from simulator + struct DataDefinitionPosData { double latitudeDeg; //!< Latitude (deg) double longitudeDeg; //!< Longitude (deg) @@ -195,6 +195,7 @@ namespace BlackSimPlugin DataRemoteAircraftParts, DataRemoteAircraftSetPosition, //!< the position which will be set DataRemoteAircraftGetPosition, //!< get position to evaluate altitude / AGL + DataRemoteAircraftModelData, //!< model data eventually used and reported back from simulator DataSimEnvironment, DataClientAreaSb, //!< whole SB area DataClientAreaSbIdent, //!< ident single value @@ -205,19 +206,32 @@ namespace BlackSimPlugin enum Request { RequestOwnAircraft, - RequestRemoveAircraft, RequestOwnAircraftTitle, RequestSimEnvironment, - RequestSbData, //!< SB client area / XPDR mode - RequestRangeForSimData, //!< range for sim data - RequestRangeForProbe, //!< range for probe - RequestRangeForLights, //!< range for lights - RequestEndMarker //!< free request ids can start here + RequestSbData, //!< SB client area / XPDR mode + RequestFacility, + RequestEndMarker //!< free request ids can start here + }; + + //! SimObject requests used for AI aircraft and probes + enum SimObjectRequest + { + SimObjectBaseId, //!< base id without specific request + SimObjectAdd, + SimObjectRemove, + SimObjectPositionData, + SimObjectLights, + SimObjectModel, + SimObjectMisc, + SimObjectEndMarker //!< end marker, do NOT remove, also means invalid }; //! Request to string static const QString &requestToString(Request request); + //! Request to string + static const QString &simObjectRequestToString(SimObjectRequest simObjectRequest); + //! Constructor CSimConnectDefinitions(); diff --git a/src/plugins/simulator/fsxcommon/simconnectobject.cpp b/src/plugins/simulator/fsxcommon/simconnectobject.cpp index 494fcf40d..7ffad7011 100644 --- a/src/plugins/simulator/fsxcommon/simconnectobject.cpp +++ b/src/plugins/simulator/fsxcommon/simconnectobject.cpp @@ -8,9 +8,15 @@ */ #include "simconnectobject.h" +#include "blackmisc/stringutils.h" +#include "simulatorfsxcommon.h" +#include "blackcore/simulator.h" #include "blackcore/simulator.h" #include "blackmisc/simulation/interpolatormulti.h" +#include "blackconfig/buildconfig.h" +using namespace BlackConfig; +using namespace BlackMisc; using namespace BlackMisc::Aviation; using namespace BlackMisc::Simulation; using namespace BlackCore; @@ -47,6 +53,36 @@ namespace BlackSimPlugin m_callsignByteArray = aircraft.getCallsignAsString().toLatin1(); } + void CSimConnectObject::setRequestId(DWORD id) + { + m_requestId = id; + m_validRequestId = true; + const SimObjectType type = requestIdToType(id); + this->setType(type); + } + + DWORD CSimConnectObject::getRequestId(CSimConnectDefinitions::SimObjectRequest offset) const + { + if (CBuildConfig::isLocalDeveloperDebugBuild()) + { + const SimObjectType type = requestIdToType(m_requestId); + Q_ASSERT_X(type == this->getType(), Q_FUNC_INFO, "Type mismatch"); + } + + DWORD os = 0; + switch (this->getType()) + { + case TerrainProbe: + os = static_cast(CSimulatorFsxCommon::offsetSimObjTerrainProbe(offset)); + break; + case Aircraft: + default: + os = static_cast(CSimulatorFsxCommon::offsetSimObjAircraft(offset)); + break; + } + return os + m_requestId; + } + void CSimConnectObject::setObjectId(DWORD id) { m_objectId = id; @@ -130,6 +166,34 @@ namespace BlackSimPlugin return m_interpolator->getLastInterpolatedSituation(mode); } + QString CSimConnectObject::toQString() const + { + static const QString s("CS: '%1' obj: %2 req: %3 conf.added: %4 pend.rem.: %5"); + return s.arg(this->getCallsign().asString()).arg(m_objectId).arg(m_requestId).arg(boolToYesNo(m_confirmedAdded), boolToYesNo(m_pendingRemoved)); + } + + CSimConnectObject::SimObjectType CSimConnectObject::requestIdToType(DWORD requestId) + { + if (CSimulatorFsxCommon::isRequestForSimObjTerrainProbe(requestId)) { return TerrainProbe; } + if (CSimulatorFsxCommon::isRequestForSimObjAircraft(requestId)) { return Aircraft; } + Q_ASSERT_X(false, Q_FUNC_INFO, "Wrong range"); + return Aircraft; + } + + const QString &CSimConnectObject::typeToString(CSimConnectObject::SimObjectType type) + { + static const QString a("aircraft"); + static const QString p("probe"); + static const QString u("unknown"); + switch (type) + { + case Aircraft: return a; + case TerrainProbe: return p; + default: break; + } + return u; + } + bool CSimConnectObjects::setSimConnectObjectIdForRequestId(DWORD requestId, DWORD objectId) { // First check, if this request id belongs to us diff --git a/src/plugins/simulator/fsxcommon/simconnectobject.h b/src/plugins/simulator/fsxcommon/simconnectobject.h index f1424ef87..330232fae 100644 --- a/src/plugins/simulator/fsxcommon/simconnectobject.h +++ b/src/plugins/simulator/fsxcommon/simconnectobject.h @@ -31,7 +31,7 @@ namespace BlackSimPlugin enum SimObjectType { Aircraft, - Probe + TerrainProbe }; //! Constructor @@ -93,18 +93,21 @@ namespace BlackSimPlugin void setSimDataPeriod(SIMCONNECT_PERIOD period) { m_requestSimDataPeriod = period; } //! Set Simconnect request id - void setRequestId(DWORD id) { m_requestId = id; m_validRequestId = true; } + void setRequestId(DWORD id); - //! Get Simconnect request id + //! Get SimConnect request id DWORD getRequestId() const { return m_requestId; } + //! Get SimConnect with offset + DWORD getRequestId(CSimConnectDefinitions::SimObjectRequest offset) const; + //! Set Simconnect object id void setObjectId(DWORD id); - //! Get Simconnect object id + //! Get SimConnect object id DWORD getObjectId() const { return m_objectId; } - //! Get Simconnect object id + //! Get SimConnect object id QString getObjectIdAsString() const { return QString::number(this->getObjectId()); } //! Valid request id? @@ -179,6 +182,15 @@ namespace BlackSimPlugin //! Interpolator BlackMisc::Simulation::CInterpolatorMulti *getInterpolator() const { return m_interpolator.data(); } + //! SimObject as string + QString toQString() const; + + //! Type of id + static SimObjectType requestIdToType(DWORD requestId); + + //! Type to string + static const QString &typeToString(SimObjectType type); + private: BlackMisc::Simulation::CSimulatedAircraft m_aircraft; //!< corresponding aircraft SimObjectType m_type = Aircraft; diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp index 6a98f9ab8..f8a3e92fb 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.cpp @@ -18,6 +18,7 @@ #include "blackmisc/simulation/simulatorplugininfo.h" #include "blackmisc/aviation/airportlist.h" #include "blackmisc/geo/elevationplane.h" +#include "blackmisc/math/mathutils.h" #include "blackmisc/logmessage.h" #include "blackmisc/statusmessagelist.h" #include "blackmisc/threadutils.h" @@ -34,6 +35,7 @@ using namespace BlackMisc::Aviation; using namespace BlackMisc::PhysicalQuantities; using namespace BlackMisc::Geo; using namespace BlackMisc::Network; +using namespace BlackMisc::Math; using namespace BlackMisc::Simulation; using namespace BlackMisc::Simulation::FsCommon; using namespace BlackMisc::Simulation::Fsx; @@ -77,7 +79,7 @@ namespace BlackSimPlugin bool CSimulatorFsxCommon::isSimulating() const { - return m_simSimulating; + return m_simSimulating && this->isConnected(); } bool CSimulatorFsxCommon::connectTo() @@ -260,10 +262,9 @@ namespace BlackSimPlugin { static const QString specificInfo("dispatch #: %1 %2 times (cur/max): %3ms (%4ms) %5ms (%6ms) %7 %8 simData#: %9"); return specificInfo. - arg(DispatchProc).arg(m_dispatchProcEmpty). + arg(m_dispatchProcCount).arg(m_dispatchProcEmptyCount). arg(m_dispatchTimeMs).arg(m_dispatchProcTimeMs).arg(m_dispatchMaxTimeMs).arg(m_dispatchProcMaxTimeMs). - arg(CSimConnectUtilities::simConnectReceiveIdToString(m_dispatchMaxTimeReceiveId), - CSimConnectDefinitions::requestToString(m_dispatchMaxTimeRequest)). + arg(CSimConnectUtilities::simConnectReceiveIdToString(m_dispatchReceiveIdMaxTime), requestIdToString(m_dispatchRequestIdMaxTime)). arg(m_requestSimObjectDataCount); } @@ -318,19 +319,34 @@ namespace BlackSimPlugin void CSimulatorFsxCommon::resetAircraftStatistics() { m_dispatchProcCount = 0; - m_dispatchProcEmpty = 0; + m_dispatchProcEmptyCount = 0; m_dispatchMaxTimeMs = -1; m_dispatchProcMaxTimeMs = -1; m_dispatchTimeMs = -1; m_dispatchProcTimeMs = -1; m_requestSimObjectDataCount = 0; - m_dispatchLastReceiveId = SIMCONNECT_RECV_ID_NULL; - m_dispatchMaxTimeReceiveId = SIMCONNECT_RECV_ID_NULL; - m_dispatchLastRequest = CSimConnectDefinitions::RequestEndMarker; - m_dispatchMaxTimeRequest = CSimConnectDefinitions::RequestEndMarker; + m_dispatchReceiveIdLast = SIMCONNECT_RECV_ID_NULL; + m_dispatchReceiveIdMaxTime = SIMCONNECT_RECV_ID_NULL; + m_dispatchRequestIdLast = CSimConnectDefinitions::RequestEndMarker; + m_dispatchRequestIdMaxTime = CSimConnectDefinitions::RequestEndMarker; CSimulatorPluginCommon::resetAircraftStatistics(); } + CSimConnectDefinitions::SimObjectRequest CSimulatorFsxCommon::requestToSimObjectRequest(DWORD requestId) + { + DWORD v = static_cast(CSimConnectDefinitions::SimObjectEndMarker); + if (isRequestForSimObjAircraft(requestId)) + { + v = (requestId - RequestSimObjAircraftStart) / MaxSimObjAircraft; + } + else if (isRequestForSimObjTerrainProbe(requestId)) + { + v = (requestId - RequestSimObjTerrainProbeStart) / MaxSimObjProbes; + } + Q_ASSERT_X(v <= CSimConnectDefinitions::SimObjectEndMarker, Q_FUNC_INFO, "Invalid value"); + return static_cast(v); + } + bool CSimulatorFsxCommon::stillDisplayReceiveExceptions() { m_receiveExceptionCount++; @@ -451,17 +467,17 @@ namespace BlackSimPlugin }); } - SIMCONNECT_DATA_REQUEST_ID CSimulatorFsxCommon::obtainRequestIdForSimData() + SIMCONNECT_DATA_REQUEST_ID CSimulatorFsxCommon::obtainRequestIdForSimObjAircraft() { - const SIMCONNECT_DATA_REQUEST_ID id = m_requestIdSimData++; - if (id > RequestIdSimDataEnd) { m_requestIdSimData = RequestIdSimDataStart; } + const SIMCONNECT_DATA_REQUEST_ID id = m_requestIdSimObjAircraft++; + if (id > RequestSimObjAircraftEnd) { m_requestIdSimObjAircraft = RequestSimObjAircraftStart; } return id; } - SIMCONNECT_DATA_REQUEST_ID CSimulatorFsxCommon::obtainRequestIdForProbe() + SIMCONNECT_DATA_REQUEST_ID CSimulatorFsxCommon::obtainRequestIdForSimObjTerrainProbe() { - const SIMCONNECT_DATA_REQUEST_ID id = m_requestIdProbe++; - if (id > RequestIdTerrainProbeEnd) { m_requestIdProbe = RequestIdTerrainProbeStart; } + const SIMCONNECT_DATA_REQUEST_ID id = m_requestIdSimObjTerrainProbe++; + if (id > RequestSimObjTerrainProbeEnd) { m_requestIdSimObjTerrainProbe = RequestSimObjTerrainProbeStart; } return id; } @@ -471,6 +487,7 @@ namespace BlackSimPlugin if (this->isShuttingDownOrDisconnected()) { return false; } const qint64 ts = QDateTime::currentMSecsSinceEpoch(); m_traceAutoTs = ts; // auto trace on + CLogMessage(this).warning("Triggered auto trace until %1") << ts; const QPointer myself(this); QTimer::singleShot(AutoTraceOffsetMs * 1.2, this, [ = ] { @@ -478,6 +495,7 @@ namespace BlackSimPlugin if (myself.isNull()) { return; } if (myself->m_traceAutoTs == ts) { + CLogMessage(this).warning("Auto trace id off"); myself->m_traceAutoTs = -1; } }); @@ -581,7 +599,7 @@ namespace BlackSimPlugin } } - void CSimulatorFsxCommon::triggerUpdateRemoteAircraftFromSimulator(const CSimConnectObject &simObject, const DataDefinitionRemoteAircraftSimData &remoteAircraftData) + void CSimulatorFsxCommon::triggerUpdateRemoteAircraftFromSimulator(const CSimConnectObject &simObject, const DataDefinitionPosData &remoteAircraftData) { if (this->isShuttingDownOrDisconnected()) { return; } QPointer myself(this); @@ -592,7 +610,7 @@ namespace BlackSimPlugin }); } - void CSimulatorFsxCommon::updateRemoteAircraftFromSimulator(const CSimConnectObject &simObject, const DataDefinitionRemoteAircraftSimData &remoteAircraftData) + void CSimulatorFsxCommon::updateRemoteAircraftFromSimulator(const CSimConnectObject &simObject, const DataDefinitionPosData &remoteAircraftData) { if (this->isShuttingDownOrDisconnected()) { return; } @@ -627,7 +645,7 @@ namespace BlackSimPlugin } } - void CSimulatorFsxCommon::updateProbeFromSimulator(const CCallsign &callsign, const DataDefinitionRemoteAircraftSimData &remoteAircraftData) + void CSimulatorFsxCommon::updateProbeFromSimulator(const CCallsign &callsign, const DataDefinitionPosData &remoteAircraftData) { const CElevationPlane elevation(remoteAircraftData.latitudeDeg, remoteAircraftData.longitudeDeg, remoteAircraftData.elevationFt, CElevationPlane::singlePointRadius()); this->callbackReceivedRequestedElevation(elevation, callsign); @@ -721,8 +739,8 @@ namespace BlackSimPlugin simObject.setConfirmedAdded(true); // P3D also has SimConnect_AIReleaseControlEx which also allows to destroy the aircraft - const SIMCONNECT_DATA_REQUEST_ID requestId = this->obtainRequestIdForSimData(); const DWORD objectId = simObject.getObjectId(); + const SIMCONNECT_DATA_REQUEST_ID requestId = simObject.getRequestId(CSimConnectDefinitions::SimObjectMisc); HRESULT hr = SimConnect_AIReleaseControl(m_hSimConnect, objectId, requestId); hr += SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventFreezeLat, 1, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); hr += SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventFreezeAlt, 1, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY); @@ -826,14 +844,14 @@ namespace BlackSimPlugin if (simObject.isPendingRemoved()) { // good case, object has been removed - // we can remove the sim object + // we can remove the simulator object } else { // object was removed, but removal was not requested by us // this means we are out of the reality bubble or something else went wrong // Possible reasons: - // 1) out of reality bubble + // 1) out of reality bubble, because we move to another airport or other reasons // 2) wrong position (in ground etc.) // 3) Simulator not running (ie in stopped mode) CStatusMessage msg; @@ -959,8 +977,8 @@ namespace BlackSimPlugin Q_ASSERT_X(m_dispatchProc, Q_FUNC_INFO, "Missing DispatchProc"); // statistics - m_dispatchLastReceiveId = SIMCONNECT_RECV_ID_NULL; - m_dispatchLastRequest = CSimConnectDefinitions::RequestEndMarker; + m_dispatchReceiveIdLast = SIMCONNECT_RECV_ID_NULL; + m_dispatchRequestIdLast = CSimConnectDefinitions::RequestEndMarker; const qint64 start = QDateTime::currentMSecsSinceEpoch(); // process @@ -972,8 +990,8 @@ namespace BlackSimPlugin if (m_dispatchMaxTimeMs < m_dispatchTimeMs) { m_dispatchMaxTimeMs = m_dispatchTimeMs; - m_dispatchMaxTimeReceiveId = m_dispatchLastReceiveId; - m_dispatchMaxTimeRequest = m_dispatchLastRequest; + m_dispatchReceiveIdMaxTime = m_dispatchReceiveIdLast; + m_dispatchRequestIdMaxTime = m_dispatchRequestIdLast; } // error handling @@ -1022,7 +1040,7 @@ namespace BlackSimPlugin m_addPendingSimObjTimer.start(AddPendingAircraftIntervalMs); // restart const bool hasPendingAdded = m_simConnectObjects.containsPendingAdded(); - bool canAdd = m_simSimulating && m_simConnected && !hasPendingAdded; + bool canAdd = this->isSimulating() && !hasPendingAdded; Q_ASSERT_X(!hasPendingAdded || m_simConnectObjects.countPendingAdded() < 2, Q_FUNC_INFO, "There must be only 0..1 pending objects"); if (this->showDebugLogMessage()) @@ -1103,7 +1121,7 @@ namespace BlackSimPlugin // FSX/P3D adding bool adding = false; // will be added flag - const SIMCONNECT_DATA_REQUEST_ID requestId = this->obtainRequestIdForSimData(); + const SIMCONNECT_DATA_REQUEST_ID requestId = this->obtainRequestIdForSimObjAircraft(); // add const SIMCONNECT_DATA_INITPOSITION initialPosition = CSimulatorFsxCommon::aircraftSituationToFsxPosition(newRemoteAircraft.getSituation(), sendGround); const QString modelString(newRemoteAircraft.getModelString()); if (this->showDebugLogMessage()) { this->debugLogMessage(Q_FUNC_INFO, QString("CS: '%1' model: '%2' request: %3, init pos: %4").arg(callsign.toQString(), modelString).arg(requestId).arg(fsxPositionToString(initialPosition))); } @@ -1136,7 +1154,7 @@ namespace BlackSimPlugin static const QString pseudoCallsign("swift pr: %1"); // max 12 chars const int index = m_simConnectProbes.size() + 1; const CCallsign cs(pseudoCallsign.arg(index)); - const SIMCONNECT_DATA_REQUEST_ID requestId = this->obtainRequestIdForProbe(); + const SIMCONNECT_DATA_REQUEST_ID requestId = this->obtainRequestIdForSimObjTerrainProbe(); // add const SIMCONNECT_DATA_INITPOSITION initialPosition = CSimulatorFsxCommon::coordinateToFsxPosition(coordinate); // const HRESULT hr = SimConnect_AICreateNonATCAircraft(m_hSimConnect, qPrintable(modelString), qPrintable(cs.asString().right(12)), initialPosition, requestId); const HRESULT hr = SimConnect_AICreateSimulatedObject(m_hSimConnect, qPrintable(modelString), initialPosition, requestId); @@ -1149,10 +1167,10 @@ namespace BlackSimPlugin const CAircraftModel model(modelString, CAircraftModel::TypeTerrainProbe, QStringLiteral("swift terrain probe"), CAircraftIcaoCode::unassignedIcao()); const CAircraftSituation situation(cs, coordinate); const CSimulatedAircraft pseudoAircraft(cs, model, CUser("123456", "swift", cs), situation); - CSimConnectObject simObj(CSimConnectObject::Probe); - simObj.setRequestId(requestId); - simObj.setAircraft(pseudoAircraft); - m_simConnectProbes.insert(cs, simObj); + CSimConnectObject simObject(CSimConnectObject::TerrainProbe); + simObject.setRequestId(requestId); + simObject.setAircraft(pseudoAircraft); + m_simConnectProbes.insert(cs, simObject); } else { @@ -1198,7 +1216,7 @@ namespace BlackSimPlugin 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())); } // call in SIM - const SIMCONNECT_DATA_REQUEST_ID requestId = this->obtainRequestIdForSimData(); + const SIMCONNECT_DATA_REQUEST_ID requestId = simObject.getRequestId(CSimConnectDefinitions::SimObjectRemove); const HRESULT result = SimConnect_AIRemoveObject(m_hSimConnect, static_cast(simObject.getObjectId()), requestId); if (result == S_OK) { @@ -1309,7 +1327,7 @@ namespace BlackSimPlugin } // facility - SIMCONNECT_DATA_REQUEST_ID requestId = this->obtainRequestIdForSimData(); + SIMCONNECT_DATA_REQUEST_ID requestId = static_cast(CSimConnectDefinitions::RequestFacility); hr += SimConnect_SubscribeToFacilities(m_hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, requestId); if (hr != S_OK) { @@ -1397,7 +1415,7 @@ namespace BlackSimPlugin if (hr == S_OK) { this->rememberLastSent(result); // remember - if (this->isTracingSendId()) { this->traceSendId(objectId, Q_FUNC_INFO); } + if (this->isTracingSendId()) { this->traceSendId(objectId, Q_FUNC_INFO, simObject.toQString()); } this->removedClampedLog(callsign); } else @@ -1658,8 +1676,9 @@ namespace BlackSimPlugin if (!m_simConnectObjects.contains(simObject.getCallsign())) { return false; } // removed in meantime // always request, not only when something has changed + const SIMCONNECT_DATA_REQUEST_ID reqId = static_cast(simObject.getRequestId(CSimConnectDefinitions::SimObjectPositionData)); const HRESULT result = SimConnect_RequestDataOnSimObject( - m_hSimConnect, simObject.getRequestId() + RequestSimDataOffset, + m_hSimConnect, reqId, CSimConnectDefinitions::DataRemoteAircraftGetPosition, simObject.getObjectId(), period); @@ -1681,20 +1700,21 @@ namespace BlackSimPlugin if (m_simConnectProbes.countConfirmedAdded() < 1) { return false; } if (!m_simConnectObjects.contains(callsign)) { return false; } // removed in meantime - const DWORD id = this->obtainRequestIdForProbe(); - const DWORD objectId = m_simConnectProbes.values().front().getObjectId(); + const CSimConnectObject simObject = m_simConnectProbes.values().front(); + const SIMCONNECT_DATA_REQUEST_ID requestId = simObject.getRequestId(CSimConnectDefinitions::SimObjectPositionData); + const DWORD objectId = simObject.getObjectId(); const HRESULT result = SimConnect_RequestDataOnSimObject( - m_hSimConnect, id, + m_hSimConnect, requestId, CSimConnectDefinitions::DataRemoteAircraftGetPosition, objectId, SIMCONNECT_PERIOD_ONCE); if (result == S_OK) { - if (this->isTracingSendId()) { this->traceSendId(id, Q_FUNC_INFO); } - m_pendingProbeRequests.insert(id, callsign); + if (this->isTracingSendId()) { this->traceSendId(requestId, Q_FUNC_INFO); } + m_pendingProbeRequests.insert(requestId, callsign); return true; } - CLogMessage(this).error("Cannot request terrain probe data for id '%1' ''%2") << id << callsign.asString(); + CLogMessage(this).error("Cannot request terrain probe data for id '%1' ''%2") << requestId << callsign.asString(); return false; } @@ -1706,8 +1726,9 @@ namespace BlackSimPlugin if (!m_hSimConnect) { return false; } // always request, not only when something has changed + const SIMCONNECT_DATA_REQUEST_ID requestId = simObject.getRequestId(CSimConnectDefinitions::SimObjectLights); const HRESULT result = SimConnect_RequestDataOnSimObject( - m_hSimConnect, simObject.getRequestId() + RequestLightsOffset, + m_hSimConnect, requestId, CSimConnectDefinitions::DataRemoteAircraftLights, simObject.getObjectId(), SIMCONNECT_PERIOD_SECOND); if (result == S_OK) @@ -1725,14 +1746,16 @@ namespace BlackSimPlugin if (!m_hSimConnect) { return false; } // stop by setting SIMCONNECT_PERIOD_NEVER + SIMCONNECT_DATA_REQUEST_ID requestId = simObject.getRequestId(CSimConnectDefinitions::SimObjectPositionData); HRESULT result = SimConnect_RequestDataOnSimObject( - m_hSimConnect, simObject.getRequestId() + RequestSimDataOffset, + m_hSimConnect, requestId, CSimConnectDefinitions::DataRemoteAircraftGetPosition, simObject.getObjectId(), SIMCONNECT_PERIOD_NEVER); if (result == S_OK) { if (this->isTracingSendId()) { this->traceSendId(simObject.getObjectId(), Q_FUNC_INFO, "Position");} } + requestId = simObject.getRequestId(CSimConnectDefinitions::SimObjectLights); result = SimConnect_RequestDataOnSimObject( - m_hSimConnect, simObject.getRequestId() + RequestLightsOffset, + m_hSimConnect, requestId, CSimConnectDefinitions::DataRemoteAircraftLights, simObject.getObjectId(), SIMCONNECT_PERIOD_NEVER); if (result == S_OK) { if (this->isTracingSendId()) { this->traceSendId(simObject.getObjectId(), Q_FUNC_INFO, "Lights");} } @@ -1760,7 +1783,7 @@ namespace BlackSimPlugin m_simSimulating = false; m_syncDeferredCounter = 0; m_skipCockpitUpdateCycles = 0; - m_requestIdSimData = static_cast(RequestIdSimDataStart); + m_requestIdSimObjAircraft = static_cast(RequestSimObjAircraftStart); m_dispatchErrors = 0; m_receiveExceptionCount = 0; m_sendIdTraces.clear(); @@ -1829,18 +1852,18 @@ namespace BlackSimPlugin { if (m_simConnectProbes.isEmpty()) { return 0; } int c = 0; - for (const CSimConnectObject &simObject : m_simConnectProbes.values()) + for (const CSimConnectObject &probeSimObject : m_simConnectProbes.values()) { - if (!simObject.isConfirmedAdded()) { continue; } - const SIMCONNECT_DATA_REQUEST_ID requestId = this->obtainRequestIdForProbe(); - const HRESULT result = SimConnect_AIRemoveObject(m_hSimConnect, static_cast(simObject.getObjectId()), requestId); + if (!probeSimObject.isConfirmedAdded()) { continue; } + const SIMCONNECT_DATA_REQUEST_ID requestId = probeSimObject.getRequestId(CSimConnectDefinitions::SimObjectRemove); + const HRESULT result = SimConnect_AIRemoveObject(m_hSimConnect, static_cast(probeSimObject.getObjectId()), requestId); if (result == S_OK) { c++; } else { - CLogMessage(this).warning("Removing probe '%1' from simulator failed") << simObject.getObjectId(); + CLogMessage(this).warning("Removing probe '%1' from simulator failed") << probeSimObject.getObjectId(); } } m_simConnectProbes.clear(); @@ -1880,6 +1903,39 @@ namespace BlackSimPlugin return QString::fromLatin1(fsxChar, size); } + QString CSimulatorFsxCommon::requestIdToString(DWORD requestId) + { + if (requestId <= CSimConnectDefinitions::RequestEndMarker) + { + return CSimConnectDefinitions::requestToString(static_cast(requestId)); + } + + const CSimConnectDefinitions::SimObjectRequest simRequest = requestToSimObjectRequest(requestId); + const CSimConnectObject::SimObjectType simType = CSimConnectObject::requestIdToType(requestId); + + static const QString req("%1 %2 %3"); + return req.arg(requestId).arg(CSimConnectObject::typeToString(simType)).arg(CSimConnectDefinitions::simObjectRequestToString(simRequest)); + } + + DWORD CSimulatorFsxCommon::unitTestRequestId(CSimConnectObject::SimObjectType type) + { + int start; + int end; + switch (type) + { + case CSimConnectObject::TerrainProbe: + start = RequestSimObjTerrainProbeStart; end = RequestSimObjTerrainProbeEnd; + break; + case CSimConnectObject::Aircraft: + default: + start = RequestSimObjAircraftStart; end = RequestSimObjAircraftEnd; + break; + } + + const int id = CMathUtils::randomInteger(start, end); + return static_cast(id); + } + CCallsignSet CSimulatorFsxCommon::physicallyRemoveAircraftNotInProvider() { const CCallsignSet toBeRemoved(getCallsignsMissingInProvider()); diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h index 4eeb25138..8357c28c5 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h +++ b/src/plugins/simulator/fsxcommon/simulatorfsxcommon.h @@ -145,6 +145,19 @@ namespace BlackSimPlugin //! \copydoc BlackCore::CSimulatorCommon::resetAircraftStatistics virtual void resetAircraftStatistics() override; + //! Request for sim data (request in range of sim data)? + static bool isRequestForSimObjAircraft(DWORD requestId) { return requestId >= RequestSimObjAircraftStart && requestId <= RequestSimObjAircraftRangeEnd; } + + //! Request for probe (elevation)? + static bool isRequestForSimObjTerrainProbe(DWORD requestId) { return requestId >= RequestSimObjTerrainProbeStart && requestId <= RequestSimObjTerrainProbeRangeEnd; } + + //! Sub request type + static CSimConnectDefinitions::SimObjectRequest requestToSimObjectRequest(DWORD requestId); + + //! Random unit text request id + //! \private + static DWORD unitTestRequestId(CSimConnectObject::SimObjectType type); + protected: //! SimConnect callback //! \note all tasks called in this function (i.e, all called functions) must perform fast or shall be called asynchronously @@ -179,30 +192,21 @@ namespace BlackSimPlugin //! @} virtual bool parseDetails(const BlackMisc::CSimpleCommandParser &parser) override; - //! Get new request id, overflow safe - SIMCONNECT_DATA_REQUEST_ID obtainRequestIdForSimData(); - - //! Get new request id, overflow safe - SIMCONNECT_DATA_REQUEST_ID obtainRequestIdForProbe(); - //! Trigger tracing ids for some while bool triggerAutoTraceSendId(); - //! Request for sim data (request in range of sim data)? - static bool isRequestForSimData(DWORD requestId) { return requestId >= (RequestIdSimDataStart + RequestSimDataOffset) && requestId < (RequestIdSimDataStart + RequestSimDataOffset + MaxSimObjects); } + //! Callsign for pending request + BlackMisc::Aviation::CCallsign getCallsignForPendingProbeRequests(DWORD requestId, bool remove); - //! Request for lights (request in range of lights)? - static bool isRequestForLights(DWORD requestId) { return requestId >= (RequestIdSimDataStart + RequestLightsOffset) && requestId < (RequestIdSimDataStart + RequestLightsOffset + MaxSimObjects); } + //! Get new request id, overflow safe + SIMCONNECT_DATA_REQUEST_ID obtainRequestIdForSimObjAircraft(); - //! Request for probe (elevation)? - static bool isRequestForProbe(DWORD requestId) { return requestId >= RequestIdTerrainProbeStart && requestId <= RequestIdTerrainProbeEnd; } + //! Get new request id, overflow safe + SIMCONNECT_DATA_REQUEST_ID obtainRequestIdForSimObjTerrainProbe(); //! Register help static void registerHelp(); - //! Callsign for pending request - BlackMisc::Aviation::CCallsign getCallsignForPendingProbeRequests(DWORD requestId, bool remove); - static constexpr qint64 AutoTraceOffsetMs = 10 * 1000; //!< how long do we trace? HANDLE m_hSimConnect = nullptr; //!< handle to SimConnect object DispatchProc m_dispatchProc = &CSimulatorFsxCommon::SimConnectProc; //!< called function for dispatch, can be overriden by specialized P3D function @@ -309,13 +313,13 @@ namespace BlackSimPlugin //! Call CSimulatorFsxCommon::updateRemoteAircraftFromSimulator asynchronously //! \remark can help not to send SimConnect data in event loop - void triggerUpdateRemoteAircraftFromSimulator(const CSimConnectObject &simObject, const DataDefinitionRemoteAircraftSimData &remoteAircraftData); + void triggerUpdateRemoteAircraftFromSimulator(const CSimConnectObject &simObject, const DataDefinitionPosData &remoteAircraftData); //! Remote aircraft data sent from simulator - void updateRemoteAircraftFromSimulator(const CSimConnectObject &simObject, const DataDefinitionRemoteAircraftSimData &remoteAircraftData); + void updateRemoteAircraftFromSimulator(const CSimConnectObject &simObject, const DataDefinitionPosData &remoteAircraftData); //! Probe data sent from simulator - void updateProbeFromSimulator(const BlackMisc::Aviation::CCallsign &callsign, const DataDefinitionRemoteAircraftSimData &remoteAircraftData); + void updateProbeFromSimulator(const BlackMisc::Aviation::CCallsign &callsign, const DataDefinitionPosData &remoteAircraftData); //! Update from SB client area //! \threadsafe @@ -404,16 +408,23 @@ namespace BlackSimPlugin static QString fsxCharToQString(const char *fsxChar, int size = -1); static constexpr int GuessRemoteAircraftPartsCycle = 20; //!< guess every n-th cycle - static constexpr int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles before updating cockpit again - static constexpr int IgnoreReceiveExceptions = 10; //!< skip exceptions when displayed more than x times - static constexpr int MaxSimObjects = 10000; //!< max.number of SimObjects at the same time - static constexpr int MaxSendIdTraces = 10000; //!< max.traces of send id - static constexpr int RequestIdSimDataStart = static_cast(CSimConnectDefinitions::RequestEndMarker); - static constexpr int RequestIdSimDataEnd = RequestIdSimDataStart + MaxSimObjects - 1; - static constexpr int RequestSimDataOffset = 0 * MaxSimObjects; //!< range for sim data requests - static constexpr int RequestLightsOffset = 1 * MaxSimObjects; //!< range for lights - static constexpr int RequestIdTerrainProbeStart = 2 * MaxSimObjects + RequestIdSimDataEnd + 1; //!< range for terrain probe - static constexpr int RequestIdTerrainProbeEnd = (RequestIdTerrainProbeStart + 1000) - 1; + static constexpr int SkipUpdateCyclesForCockpit = 10; //!< skip x cycles before updating cockpit again + static constexpr int IgnoreReceiveExceptions = 10; //!< skip exceptions when displayed more than x times + static constexpr int MaxSendIdTraces = 10000; //!< max.traces of send id + static constexpr int MaxSimObjAircraft = 10000; //!< max.number of SimObjects at the same time + static constexpr int MaxSimObjProbes = 100; //!< max. probes + + // -- range for sim data, each sim object will get its own request id and use the offset ranges + static constexpr int RequestSimObjAircraftStart = static_cast(CSimConnectDefinitions::RequestEndMarker); + static constexpr int RequestSimObjAircraftEnd = RequestSimObjAircraftStart - 1 + MaxSimObjAircraft; + static constexpr int RequestSimObjAircraftRangeEnd = RequestSimObjAircraftStart - 1 + static_cast(CSimConnectDefinitions::SimObjectEndMarker) * MaxSimObjAircraft; + + // -- range for probe data, each probe object will get its own request id and use the offset ranges + static constexpr int RequestSimObjTerrainProbeStart = RequestSimObjAircraftRangeEnd + 1 ; + static constexpr int RequestSimObjTerrainProbeEnd = RequestSimObjTerrainProbeStart - 1 + MaxSimObjProbes; + static constexpr int RequestSimObjTerrainProbeRangeEnd = RequestSimObjTerrainProbeStart - 1 + static_cast(CSimConnectDefinitions::SimObjectEndMarker) * MaxSimObjProbes; + + // times static constexpr int AddPendingAircraftIntervalMs = 20 * 1000; static constexpr int DispatchIntervalMs = 10; //!< how often with run the FSX event queue static constexpr int DeferSimulatingFlagMs = 1500; //!< simulating can jitter at startup (simulating->stopped->simulating, multiple start events), so we defer detection @@ -432,16 +443,16 @@ namespace BlackSimPlugin // tracing dispatch performance int m_dispatchErrors = 0; //!< number of dispatched failed, \sa dispatch int m_dispatchProcCount = 0; //!< number of dispatchProc counts - int m_dispatchProcEmpty = 0; //!< number dispatchProc doing nothing + int m_dispatchProcEmptyCount = 0; //!< number dispatchProc doing nothing qint64 m_dispatchTimeMs = -1; qint64 m_dispatchMaxTimeMs = -1; qint64 m_dispatchProcTimeMs = -1; qint64 m_dispatchProcMaxTimeMs = -1; - SIMCONNECT_RECV_ID m_dispatchLastReceiveId = SIMCONNECT_RECV_ID_NULL; //!< last receive id from dispatching - SIMCONNECT_RECV_ID m_dispatchMaxTimeReceiveId = SIMCONNECT_RECV_ID_NULL; //!< receive id corresponding to max.time - CSimConnectDefinitions::Request m_dispatchLastRequest = CSimConnectDefinitions::RequestEndMarker; //!< request id if any - CSimConnectDefinitions::Request m_dispatchMaxTimeRequest = CSimConnectDefinitions::RequestEndMarker; //!< request id corresponding to max.time + SIMCONNECT_RECV_ID m_dispatchReceiveIdLast = SIMCONNECT_RECV_ID_NULL; //!< last receive id from dispatching + SIMCONNECT_RECV_ID m_dispatchReceiveIdMaxTime = SIMCONNECT_RECV_ID_NULL; //!< receive id corresponding to max.time + DWORD m_dispatchRequestIdLast = -1; //!< request id if any + DWORD m_dispatchRequestIdMaxTime = -1; //!< max.time request // sending via SimConnect QList m_sendIdTraces; //!< Send id traces for debugging @@ -450,10 +461,19 @@ namespace BlackSimPlugin // objects CSimConnectObjects m_simConnectObjectsPositionAndPartsTraces; //!< position/parts received, but object not yet added, excluded, disabled etc. - SIMCONNECT_DATA_REQUEST_ID m_requestIdSimData = static_cast(RequestIdSimDataStart); //!< request id, use obtainRequestIdForSimData() to get id - SIMCONNECT_DATA_REQUEST_ID m_requestIdProbe = static_cast(RequestIdTerrainProbeStart); //!< request id, use obtainRequestIdForProbe() to get id + SIMCONNECT_DATA_REQUEST_ID m_requestIdSimObjAircraft = static_cast(RequestSimObjAircraftStart); //!< request id, use obtainRequestIdForSimObjAircraft to get id + SIMCONNECT_DATA_REQUEST_ID m_requestIdSimObjTerrainProbe = static_cast(RequestSimObjTerrainProbeStart); //!< request id, use obtainRequestIdForSimObjTerrainProbe to get id BlackMisc::Simulation::CSimulatedAircraftList m_addPendingAircraft; //!< aircraft awaiting to be added QTimer m_addPendingSimObjTimer; //!< updating of SimObjects awaiting to be added + + //! Request id to string + static QString requestIdToString(DWORD requestId); + + public: + //! Offsets @{ + static DWORD offsetSimObjAircraft(CSimConnectDefinitions::SimObjectRequest req) { return MaxSimObjAircraft * req; } + static DWORD offsetSimObjTerrainProbe(CSimConnectDefinitions::SimObjectRequest req) { return MaxSimObjProbes * req; } + //! @} }; //! Listener for FSX diff --git a/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp b/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp index e43df3604..2d2071a25 100644 --- a/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp +++ b/src/plugins/simulator/fsxcommon/simulatorfsxsimconnectproc.cpp @@ -8,15 +8,17 @@ */ #include "simulatorfsxcommon.h" -#include "blackcore/application.h" #include "simconnectdatadefinition.h" +#include "blackcore/application.h" #include "blackmisc/simulation/fscommon/bcdconversions.h" #include "blackmisc/simulation/fsx/simconnectutilities.h" #include "blackmisc/simulation/simulatorplugininfo.h" #include "blackmisc/aviation/airportlist.h" #include "blackmisc/logmessage.h" +#include "blackconfig/buildconfig.h" using namespace BlackCore; +using namespace BlackConfig; using namespace BlackMisc; using namespace BlackMisc::Simulation; using namespace BlackMisc::Aviation; @@ -39,7 +41,7 @@ namespace BlackSimPlugin const qint64 procTimeStart = QDateTime::currentMSecsSinceEpoch(); CSimulatorFsxCommon *simulatorFsxP3D = static_cast(pContext); const SIMCONNECT_RECV_ID recvId = static_cast(pData->dwID); - simulatorFsxP3D->m_dispatchLastReceiveId = recvId; + simulatorFsxP3D->m_dispatchReceiveIdLast = recvId; simulatorFsxP3D->m_dispatchProcCount++; switch (recvId) { @@ -67,7 +69,7 @@ namespace BlackSimPlugin switch (exceptionId) { case SIMCONNECT_EXCEPTION_OPERATION_INVALID_FOR_OBJECT_TYPE: break; - case SIMCONNECT_EXCEPTION_UNRECOGNIZED_ID: break; + case SIMCONNECT_EXCEPTION_UNRECOGNIZED_ID: break; // Specifies that the client event, request ID, data definition ID, or object ID was not recognized case SIMCONNECT_EXCEPTION_CREATE_OBJECT_FAILED: break; default: break; } @@ -176,10 +178,11 @@ namespace BlackSimPlugin { const SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *event = static_cast(pData); const DWORD requestId = event->dwRequestID; - const DWORD objectId = event->dwObjectID; - + const DWORD objectId = event->dwObjectID; bool success = false; - if (CSimulatorFsxCommon::isRequestForProbe(requestId)) + simulatorFsxP3D->m_dispatchRequestIdLast = requestId; + + if (CSimulatorFsxCommon::isRequestForSimObjTerrainProbe(requestId)) { success = simulatorFsxP3D->setSimConnectProbeId(requestId, objectId); if (!success) { break; } // not an request ID of ours @@ -194,7 +197,7 @@ namespace BlackSimPlugin CLogMessage(simulatorFsxP3D).error("Cannot add probe '%1' id: %2") << simObject.getCallsign() << objectId; } } - else if (CSimulatorFsxCommon::isRequestForSimData(requestId)) + else if (CSimulatorFsxCommon::isRequestForSimObjAircraft(requestId)) { success = simulatorFsxP3D->setSimConnectObjectId(requestId, objectId); if (!success) { break; } // not an request ID of ours @@ -219,13 +222,13 @@ namespace BlackSimPlugin { const SIMCONNECT_RECV_SIMOBJECT_DATA *pObjData = (SIMCONNECT_RECV_SIMOBJECT_DATA *) pData; const DWORD requestId = pObjData->dwRequestID; + simulatorFsxP3D->m_dispatchRequestIdLast = requestId; switch (requestId) { case CSimConnectDefinitions::RequestOwnAircraft: { static_assert(sizeof(DataDefinitionOwnAircraft) == 31 * sizeof(double), "DataDefinitionOwnAircraft has an incorrect size."); - simulatorFsxP3D->m_dispatchLastRequest = CSimConnectDefinitions::RequestOwnAircraft; const DataDefinitionOwnAircraft *ownAircaft = (DataDefinitionOwnAircraft *)&pObjData->dwData; simulatorFsxP3D->updateOwnAircraftFromSimulator(*ownAircaft); break; @@ -233,14 +236,12 @@ namespace BlackSimPlugin case CSimConnectDefinitions::RequestOwnAircraftTitle: { const DataDefinitionOwnAircraftModel *dataDefinitionModel = (DataDefinitionOwnAircraftModel *) &pObjData->dwData; - simulatorFsxP3D->m_dispatchLastRequest = CSimConnectDefinitions::RequestOwnAircraftTitle; const CAircraftModel model(dataDefinitionModel->title, CAircraftModel::TypeOwnSimulatorModel); simulatorFsxP3D->reverseLookupAndUpdateOwnAircraftModel(model); break; } case CSimConnectDefinitions::RequestSimEnvironment: { - simulatorFsxP3D->m_dispatchLastRequest = CSimConnectDefinitions::RequestSimEnvironment; const DataDefinitionSimEnvironment *simEnv = (DataDefinitionSimEnvironment *) &pObjData->dwData; if (simulatorFsxP3D->isTimeSynchronized()) { @@ -257,57 +258,82 @@ namespace BlackSimPlugin default: { const DWORD objectId = pObjData->dwObjectID; - if (CSimulatorFsxCommon::isRequestForSimData(requestId)) + + if (CSimulatorFsxCommon::isRequestForSimObjAircraft(requestId)) { - static_assert(sizeof(DataDefinitionRemoteAircraftSimData) == 5 * sizeof(double), "DataDefinitionRemoteAircraftSimData has an incorrect size."); - simulatorFsxP3D->m_dispatchLastRequest = CSimConnectDefinitions::RequestRangeForSimData; const CSimConnectObject simObject = simulatorFsxP3D->getSimObjectForObjectId(objectId); if (!simObject.hasValidRequestAndObjectId()) { break; } - const DataDefinitionRemoteAircraftSimData *remoteAircraftSimData = (DataDefinitionRemoteAircraftSimData *)&pObjData->dwData; - // extra check, but ids should be the same - if (objectId == simObject.getObjectId()) + const CSimConnectDefinitions::SimObjectRequest subRequest = CSimulatorFsxCommon::requestToSimObjectRequest(requestId); + + if (subRequest == CSimConnectDefinitions::SimObjectPositionData) { - simulatorFsxP3D->triggerUpdateRemoteAircraftFromSimulator(simObject, *remoteAircraftSimData); - } - } - else if (CSimulatorFsxCommon::isRequestForProbe(requestId)) - { - static_assert(sizeof(DataDefinitionRemoteAircraftSimData) == 5 * sizeof(double), "DataDefinitionRemoteAircraftSimData has an incorrect size."); - simulatorFsxP3D->m_dispatchLastRequest = CSimConnectDefinitions::RequestRangeForProbe; - const CSimConnectObject probeObj = simulatorFsxP3D->getProbeForObjectId(objectId); - if (!probeObj.hasValidRequestAndObjectId()) { break; } - const DataDefinitionRemoteAircraftSimData *probeSimData = (DataDefinitionRemoteAircraftSimData *)&pObjData->dwData; - // extra check, but ids should be the same - if (objectId == probeObj.getObjectId()) - { - const CCallsign cs = simulatorFsxP3D->m_pendingProbeRequests.value(requestId); - if (cs.isEmpty()) { break; } - simulatorFsxP3D->updateProbeFromSimulator(cs, *probeSimData); - } - } - else if (CSimulatorFsxCommon::isRequestForLights(requestId)) - { - static_assert(sizeof(DataDefinitionRemoteAircraftLights) == 8 * sizeof(double), "DataDefinitionRemoteAircraftLights has an incorrect size."); - simulatorFsxP3D->m_dispatchLastRequest = CSimConnectDefinitions::RequestRangeForLights; - const CSimConnectObject simObj = simulatorFsxP3D->getSimObjectForObjectId(objectId); - if (!simObj.hasValidRequestAndObjectId()) { break; } - const DataDefinitionRemoteAircraftLights *remoteAircraftLights = (DataDefinitionRemoteAircraftLights *)&pObjData->dwData; - // extra check, but ids should be the same - if (objectId == simObj.getObjectId()) - { - const CCallsign callsign(simObj.getCallsign()); - const CAircraftLights lights(remoteAircraftLights->toLights()); // as in simulator - simulatorFsxP3D->setCurrentLights(callsign, lights); - if (simObj.getLightsAsSent().isNull()) + static_assert(sizeof(DataDefinitionPosData) == 5 * sizeof(double), "DataDefinitionPosData has an incorrect size."); + const DataDefinitionPosData *remoteAircraftSimData = reinterpret_cast(&pObjData->dwData); + // extra check, but ids should be the same + if (objectId == simObject.getObjectId()) { - // allows to compare for toggle - simulatorFsxP3D->setLightsAsSent(callsign, lights); + simulatorFsxP3D->triggerUpdateRemoteAircraftFromSimulator(simObject, *remoteAircraftSimData); + } + } // position + else if (subRequest == CSimConnectDefinitions::SimObjectLights) + { + static_assert(sizeof(DataDefinitionRemoteAircraftLights) == 8 * sizeof(double), "DataDefinitionRemoteAircraftLights has an incorrect size."); + const DataDefinitionRemoteAircraftLights *remoteAircraftLights = reinterpret_cast(&pObjData->dwData); + // extra check, but ids should be the same + if (objectId == simObject.getObjectId()) + { + const CCallsign callsign(simObject.getCallsign()); + const CAircraftLights lights(remoteAircraftLights->toLights()); // as in simulator + simulatorFsxP3D->setCurrentLights(callsign, lights); + if (simObject.getLightsAsSent().isNull()) + { + // allows to compare for toggle + simulatorFsxP3D->setLightsAsSent(callsign, lights); + } + } + break; + } // lights + else + { + if (CBuildConfig::isLocalDeveloperDebugBuild()) + { + CLogMessage(simulatorFsxP3D).error("Unknown subrequest (aircraft): '%1' %2") + << CSimConnectDefinitions::simObjectRequestToString(subRequest) + << simObject.toQString(); } } } + else if (CSimulatorFsxCommon::isRequestForSimObjTerrainProbe(requestId)) + { + const CSimConnectObject probeObj = simulatorFsxP3D->getProbeForObjectId(objectId); + if (!probeObj.hasValidRequestAndObjectId()) { break; } + const CSimConnectDefinitions::SimObjectRequest subRequest = CSimulatorFsxCommon::requestToSimObjectRequest(requestId); + + if (subRequest == CSimConnectDefinitions::SimObjectPositionData) + { + static_assert(sizeof(DataDefinitionPosData) == 5 * sizeof(double), "DataDefinitionRemoteAircraftSimData has an incorrect size."); + const DataDefinitionPosData *probeSimData = (DataDefinitionPosData *)&pObjData->dwData; + // extra check, but ids should be the same + if (objectId == probeObj.getObjectId()) + { + const CCallsign cs = simulatorFsxP3D->m_pendingProbeRequests.value(requestId); + if (cs.isEmpty()) { break; } + simulatorFsxP3D->updateProbeFromSimulator(cs, *probeSimData); + } + } + else + { + if (CBuildConfig::isLocalDeveloperDebugBuild()) + { + CLogMessage(simulatorFsxP3D).error("Unknown subrequest (probe): '%1' %2") + << CSimConnectDefinitions::simObjectRequestToString(subRequest) + << probeObj.toQString(); + } + } + } // probe break; } - break; + break; // default (SIMCONNECT_RECV_ID_SIMOBJECT_DATA) } break; // SIMCONNECT_RECV_ID_SIMOBJECT_DATA } @@ -356,7 +382,7 @@ namespace BlackSimPlugin break; // SIMCONNECT_RECV_ID_EVENT_FILENAME } default: - simulatorFsxP3D->m_dispatchProcEmpty++; + simulatorFsxP3D->m_dispatchProcEmptyCount++; break; } // main switch diff --git a/src/plugins/simulator/p3d/simulatorp3d.cpp b/src/plugins/simulator/p3d/simulatorp3d.cpp index 252b3f56f..be2cb6720 100644 --- a/src/plugins/simulator/p3d/simulatorp3d.cpp +++ b/src/plugins/simulator/p3d/simulatorp3d.cpp @@ -64,7 +64,7 @@ namespace BlackSimPlugin // https://www.prepar3d.com/SDKv4/sdk/simconnect_api/references/structures_and_enumerations.html#SIMCONNECT_RECV_GROUND_INFO const SIMCONNECT_RECV_GROUND_INFO *pObjData = (SIMCONNECT_RECV_GROUND_INFO *) pData; const DWORD requestId = pObjData->dwRequestID; - if (!CSimulatorFsxCommon::isRequestForProbe(requestId)) { break; } + if (!CSimulatorFsxCommon::isRequestForSimObjTerrainProbe(requestId)) { break; } // valid elevation request // https://www.prepar3d.com/SDKv4/sdk/simconnect_api/references/structures_and_enumerations.html#SIMCONNECT_DATA_GROUND_INFO if (pObjData->dwArraySize != 1) { break; } @@ -100,7 +100,7 @@ namespace BlackSimPlugin const DWORD dwGridWidth = 1.0; const DWORD dwGridHeight = 1.0; - const SIMCONNECT_DATA_REQUEST_ID requestId = this->obtainRequestIdForProbe(); + const SIMCONNECT_DATA_REQUEST_ID requestId = this->obtainRequestIdForSimObjTerrainProbe(); // P3D we use new request id each time (no simobject) // returns SIMCONNECT_RECV_GROUND_INFO -> SIMCONNECT_DATA_GROUND_INFO const HRESULT hr = SimConnect_RequestGroundInfo( diff --git a/src/plugins/simulator/p3d/simulatorp3d.h b/src/plugins/simulator/p3d/simulatorp3d.h index 65052104d..5b09dad66 100644 --- a/src/plugins/simulator/p3d/simulatorp3d.h +++ b/src/plugins/simulator/p3d/simulatorp3d.h @@ -44,7 +44,7 @@ namespace BlackSimPlugin //! \copydoc BlackMisc::Simulation::ISimulationEnvironmentProvider::requestElevation virtual bool requestElevation(const BlackMisc::Geo::ICoordinateGeodetic &reference, const BlackMisc::Aviation::CCallsign &callsign) override; - //! \copydoc ISimulator::followAircraft + //! \copydoc BlackCore::ISimulator::followAircraft virtual bool followAircraft(const BlackMisc::Aviation::CCallsign &callsign) override; protected: