Ref T275, improved request id handling for FSX/P3D

* base reange for request IDs
* all operations use offsets
* we can conclude what an id is used for (debugging)

plus

* minor Doxygen fixes
* some renamings
This commit is contained in:
Klaus Basan
2018-06-25 01:50:20 +02:00
parent e6ac7eb4df
commit 7a745d2ce6
9 changed files with 392 additions and 166 deletions

View File

@@ -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("<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("<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<CSimConnectDefinitions *>(nullptr)).error("SimConnect error: initRemoteAircraftSimData %1") << hr;
CLogMessage(static_cast<CSimConnectDefinitions *>(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<CSimConnectDefinitions *>(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);

View File

@@ -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();

View File

@@ -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<DWORD>(CSimulatorFsxCommon::offsetSimObjTerrainProbe(offset));
break;
case Aircraft:
default:
os = static_cast<DWORD>(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

View File

@@ -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;

View File

@@ -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<DWORD>(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<CSimConnectDefinitions::SimObjectRequest>(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<CSimulatorFsxCommon> 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<CSimulatorFsxCommon> 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<SIMCONNECT_OBJECT_ID>(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<SIMCONNECT_DATA_REQUEST_ID>(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<SIMCONNECT_DATA_REQUEST_ID>(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<SIMCONNECT_DATA_REQUEST_ID>(RequestIdSimDataStart);
m_requestIdSimObjAircraft = static_cast<SIMCONNECT_DATA_REQUEST_ID>(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<SIMCONNECT_OBJECT_ID>(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<SIMCONNECT_OBJECT_ID>(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<CSimConnectDefinitions::Request>(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<DWORD>(id);
}
CCallsignSet CSimulatorFsxCommon::physicallyRemoveAircraftNotInProvider()
{
const CCallsignSet toBeRemoved(getCallsignsMissingInProvider());

View File

@@ -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<int>(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<int>(CSimConnectDefinitions::RequestEndMarker);
static constexpr int RequestSimObjAircraftEnd = RequestSimObjAircraftStart - 1 + MaxSimObjAircraft;
static constexpr int RequestSimObjAircraftRangeEnd = RequestSimObjAircraftStart - 1 + static_cast<int>(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<int>(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<TraceFsxSendId> 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<SIMCONNECT_DATA_REQUEST_ID>(RequestIdSimDataStart); //!< request id, use obtainRequestIdForSimData() to get id
SIMCONNECT_DATA_REQUEST_ID m_requestIdProbe = static_cast<SIMCONNECT_DATA_REQUEST_ID>(RequestIdTerrainProbeStart); //!< request id, use obtainRequestIdForProbe() to get id
SIMCONNECT_DATA_REQUEST_ID m_requestIdSimObjAircraft = static_cast<SIMCONNECT_DATA_REQUEST_ID>(RequestSimObjAircraftStart); //!< request id, use obtainRequestIdForSimObjAircraft to get id
SIMCONNECT_DATA_REQUEST_ID m_requestIdSimObjTerrainProbe = static_cast<SIMCONNECT_DATA_REQUEST_ID>(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

View File

@@ -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<CSimulatorFsxCommon *>(pContext);
const SIMCONNECT_RECV_ID recvId = static_cast<SIMCONNECT_RECV_ID>(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<SIMCONNECT_RECV_ASSIGNED_OBJECT_ID *>(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<const DataDefinitionPosData *>(&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<const DataDefinitionRemoteAircraftLights *>(&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

View File

@@ -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(

View File

@@ -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: