refs #873, use events for lights

* added members for sim objects
* receive lights for (remote) aircraft from simulator
* update lights
* utility functions for request ids
This commit is contained in:
Klaus Basan
2017-01-31 05:16:15 +01:00
committed by Mathew Sutcliffe
parent 9c2682f386
commit a61abfcb8b
4 changed files with 176 additions and 74 deletions

View File

@@ -13,7 +13,7 @@
#define BLACKSIMPLUGIN_SIMCONNECT_OBJECT_H
#include "blackmisc/simulation/simulatedaircraft.h"
#include "simconnect/SimConnect.h"
#include "simconnectdatadefinition.h"
#include <QSharedPointer>
namespace BlackMisc { namespace Simulation { class IInterpolator; } }
@@ -43,6 +43,24 @@ namespace BlackSimPlugin
//! Simulated aircraft model string
const QString &getAircraftModelString() const { return m_aircraft.getModelString(); }
//! Get current lights (requested from simulator)
const BlackMisc::Aviation::CAircraftLights &getCurrentLightsInSimulator() const { return m_currentLightsInSim; }
//! Set current lights when received from simulator
void setCurrentLightsInSimulator(const BlackMisc::Aviation::CAircraftLights &lights) { m_currentLightsInSim = lights; }
//! Parts as sent to simulator
const DataDefinitionRemoteAircraftParts &getPartsAsSent() const { return m_partsAsSent; }
//! Parts as sent to simulator
void setPartsAsSent(const DataDefinitionRemoteAircraftParts &parts) { m_partsAsSent = parts; }
//! Lights as sent to simulator
const BlackMisc::Aviation::CAircraftLights &getLightsAsSent() const { return m_lightsAsSent; }
//! Lights as sent to simulator
void setLightsAsSent(const BlackMisc::Aviation::CAircraftLights &lights) { m_lightsAsSent = lights; }
//! How often do we request data from simulator for this remote aircraft
SIMCONNECT_PERIOD getSimDataPeriod() const { return m_requestSimDataPeriod; }
@@ -89,14 +107,18 @@ namespace BlackSimPlugin
bool hasValidRequestAndObjectId() const;
private:
BlackMisc::Simulation::CSimulatedAircraft m_aircraft;
BlackMisc::Simulation::CSimulatedAircraft m_aircraft; //!< corresponding aircraft
DWORD m_requestId = 0;
DWORD m_objectId = 0;
SIMCONNECT_PERIOD m_requestSimDataPeriod = SIMCONNECT_PERIOD_NEVER; //!< how often do we query ground elevation
bool m_validRequestId = false;
bool m_validObjectId = false;
bool m_confirmedAdded = false;
bool m_pendingRemoved = false;
int m_lightsRequestedAt = -1;
DataDefinitionRemoteAircraftParts m_partsAsSent {}; //!< parts as sent
BlackMisc::Aviation::CAircraftLights m_currentLightsInSim { nullptr }; //!< current lights to know state for toggling
BlackMisc::Aviation::CAircraftLights m_lightsAsSent { nullptr }; //!< lights as sent to simulator
SIMCONNECT_PERIOD m_requestSimDataPeriod = SIMCONNECT_PERIOD_NEVER; //!< how often do we query ground elevation
};
//! Simulator objects (aka AI aircraft)

View File

@@ -156,7 +156,7 @@ namespace BlackSimPlugin
// initial position if interpolator has data, otherwise do nothing
setInitialAircraftSituation(addedAircraft); // set interpolated data/parts if available
const DWORD requestId = obtainRequestId();
const DWORD requestId = obtainRequestIdSimData();
SIMCONNECT_DATA_INITPOSITION initialPosition = aircraftSituationToFsxPosition(addedAircraft.getSituation());
const QString modelString(addedAircraft.getModelString());
@@ -373,15 +373,10 @@ namespace BlackSimPlugin
disconnectFrom();
}
DWORD CSimulatorFsx::obtainRequestId()
DWORD CSimulatorFsx::obtainRequestIdSimData()
{
DWORD id = m_requestId++;
if (id < FirstRequestId)
{
// overflow, restart
id = FirstRequestId;
m_requestId = FirstRequestId + 1;
}
const DWORD id = m_requestIdSimData++;
if (id > RequestSimDataEnd) { m_requestIdSimData = RequestSimDataStart; }
return id;
}
@@ -562,7 +557,7 @@ namespace BlackSimPlugin
}
// P3D also has SimConnect_AIReleaseControlEx;
const DWORD requestId = obtainRequestId();
const DWORD requestId = obtainRequestIdSimData();
HRESULT hr = SimConnect_AIReleaseControl(m_hSimConnect, objectId, static_cast<SIMCONNECT_DATA_REQUEST_ID>(requestId));
if (hr == S_OK)
{
@@ -670,6 +665,20 @@ namespace BlackSimPlugin
return this->m_simConnectObjects.setSimConnectObjectIdForRequestId(requestID, objectID);
}
bool CSimulatorFsx::setCurrentLights(const CCallsign &callsign, const CAircraftLights &lights)
{
if (!m_simConnectObjects.contains(callsign)) { return false; }
m_simConnectObjects[callsign].setCurrentLightsInSimulator(lights);
return true;
}
bool CSimulatorFsx::setLightsAsSent(const CCallsign &callsign, const CAircraftLights &lights)
{
if (!m_simConnectObjects.contains(callsign)) { return false; }
m_simConnectObjects[callsign].setLightsAsSent(lights);
return true;
}
void CSimulatorFsx::timerEvent(QTimerEvent *event)
{
Q_UNUSED(event);
@@ -733,9 +742,8 @@ namespace BlackSimPlugin
}
// call in SIM
SimConnect_AIRemoveObject(m_hSimConnect, static_cast<SIMCONNECT_OBJECT_ID>(simObject.getObjectId()), static_cast<SIMCONNECT_DATA_REQUEST_ID>(m_requestId++));
SimConnect_AIRemoveObject(m_hSimConnect, static_cast<SIMCONNECT_OBJECT_ID>(simObject.getObjectId()), static_cast<SIMCONNECT_DATA_REQUEST_ID>(m_requestIdSimData++));
m_hints.remove(simObject.getCallsign());
m_lastPartsSendToSim.remove(simObject.getObjectId());
// mark in provider
bool updated = updateAircraftRendered(callsign, false);
@@ -825,7 +833,7 @@ namespace BlackSimPlugin
}
// facility
hr += SimConnect_SubscribeToFacilities(m_hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, static_cast<SIMCONNECT_DATA_REQUEST_ID>(m_requestId++));
hr += SimConnect_SubscribeToFacilities(m_hSimConnect, SIMCONNECT_FACILITY_LIST_TYPE_AIRPORT, static_cast<SIMCONNECT_DATA_REQUEST_ID>(m_requestIdSimData++));
if (hr != S_OK)
{
CLogMessage(this).error("FSX plugin error: %1") << "SimConnect_SubscribeToFacilities failed";
@@ -863,7 +871,7 @@ namespace BlackSimPlugin
void CSimulatorFsx::updateRemoteAircraft()
{
static_assert(sizeof(DataDefinitionRemoteAircraftParts) == 120, "DataDefinitionRemoteAircraftParts has an incorrect size.");
static_assert(sizeof(DataDefinitionRemoteAircraftParts) == sizeof(double) * 10, "DataDefinitionRemoteAircraftParts has an incorrect size.");
Q_ASSERT_X(this->m_interpolator, Q_FUNC_INFO, "missing interpolator");
Q_ASSERT_X(CThreadUtils::isCurrentThreadObjectThread(this), Q_FUNC_INFO, "thread");
@@ -905,7 +913,6 @@ namespace BlackSimPlugin
CInterpolationHints hints(m_hints[simObj.getCallsign()]);
hints.setAircraftParts(useAircraftParts ? parts : CAircraftParts(), useAircraftParts);
hints.setLoggingInterpolation(logInterpolationAndParts);
const CAircraftSituation interpolatedSituation = this->m_interpolator->getInterpolatedSituation(callsign, currentTimestamp, hints, interpolatorStatus);
if (interpolatorStatus.allTrue())
@@ -930,7 +937,7 @@ namespace BlackSimPlugin
else
{
// guess on position, but not every frame
if (m_interpolationRequest % 20 == 0)
if (m_interpolationRequest % GuessRemoteAircraftPartsCycle == 0)
{
this->guessAndUpdateRemoteAircraftParts(simObj, interpolatedSituation, interpolatorStatus);
}
@@ -950,44 +957,45 @@ namespace BlackSimPlugin
DataDefinitionRemoteAircraftParts ddRemoteAircraftParts = {}; // init members
const bool isOnGround = interpolatedSituation.isOnGround() == CAircraftSituation::OnGround;
ddRemoteAircraftParts.gearHandlePosition = isOnGround ? 1 : 0;
CAircraftLights lights;
// when first detected moving, lights on
if (isOnGround)
{
// ddRemoteAircraftParts.lightTaxi = 1;
ddRemoteAircraftParts.lightBeacon = 1;
ddRemoteAircraftParts.lightNav = 1;
lights.setTaxiOn(true);
lights.setBeaconOn(true);
lights.setNavOn(true);
double gskmh = interpolatedSituation.getGroundSpeed().value(CSpeedUnit::km_h());
if (gskmh > 7.5)
{
// mode taxi
// ddRemoteAircraftParts.lightTaxi = 1;
ddRemoteAircraftParts.lightLanding = 0;
lights.setTaxiOn(true);
lights.setLandingOn(false);
}
else if (gskmh > 25)
else if (gskmh > 40)
{
// mode accelaration for takeoff
// ddRemoteAircraftParts.lightTaxi = 0;
ddRemoteAircraftParts.lightLanding = 1;
lights.setTaxiOn(false);
lights.setLandingOn(true);
}
else
{
// slow movements or parking
// ddRemoteAircraftParts.lightTaxi = 0;
ddRemoteAircraftParts.lightLanding = 0;
lights.setTaxiOn(false);
lights.setLandingOn(false);
}
}
else
{
// ddRemoteAircraftParts.lightTaxi = 0;
ddRemoteAircraftParts.lightBeacon = 1;
ddRemoteAircraftParts.lightNav = 1;
lights.setTaxiOn(false);
lights.setBeaconOn(true);
lights.setNavOn(true);
// landing lights for < 10000ft (normally MSL, here ignored)
ddRemoteAircraftParts.lightLanding = (interpolatedSituation.getAltitude().value(CLengthUnit::ft()) < 10000) ? 1 : 0;
lights.setLandingOn(interpolatedSituation.getAltitude().value(CLengthUnit::ft()) < 10000);
}
return this->sendRemoteAircraftPartsToSim(simObj, ddRemoteAircraftParts);
return this->sendRemoteAircraftPartsToSimulator(simObj, ddRemoteAircraftParts, lights);
}
bool CSimulatorFsx::updateRemoteAircraftParts(const CSimConnectObject &simObj, const CAircraftParts &parts, const IInterpolator::PartsStatus &partsStatus)
@@ -996,48 +1004,72 @@ namespace BlackSimPlugin
if (!partsStatus.isSupportingParts()) { return false; }
DataDefinitionRemoteAircraftParts ddRemoteAircraftParts; // no init, all values will be set
ddRemoteAircraftParts.lightStrobe = parts.getLights().isStrobeOn() ? 1 : 0;
ddRemoteAircraftParts.lightLanding = parts.getLights().isLandingOn() ? 1 : 0;
// ddRemoteAircraftParts.lightTaxi = parts.getLights().isTaxiOn() ? 1 : 0;
ddRemoteAircraftParts.lightBeacon = parts.getLights().isBeaconOn() ? 1 : 0;
ddRemoteAircraftParts.lightNav = parts.getLights().isNavOn() ? 1 : 0;
ddRemoteAircraftParts.lightLogo = parts.getLights().isLogoOn() ? 1 : 0;
ddRemoteAircraftParts.flapsLeadingEdgeLeftPercent = parts.getFlapsPercent() / 100.0;
ddRemoteAircraftParts.flapsLeadingEdgeRightPercent = parts.getFlapsPercent() / 100.0;
ddRemoteAircraftParts.flapsTrailingEdgeLeftPercent = parts.getFlapsPercent() / 100.0;
ddRemoteAircraftParts.flapsTrailingEdgeRightPercent = parts.getFlapsPercent() / 100.0;
ddRemoteAircraftParts.spoilersHandlePosition = parts.isSpoilersOut() ? 1 : 0;
ddRemoteAircraftParts.gearHandlePosition = parts.isGearDown() ? 1 : 0; // on ground we always show gear
ddRemoteAircraftParts.gearHandlePosition = parts.isGearDown() ? 1 : 0;
ddRemoteAircraftParts.engine1Combustion = parts.isEngineOn(1) ? 1 : 0;
ddRemoteAircraftParts.engine2Combustion = parts.isEngineOn(2) ? 1 : 0;
ddRemoteAircraftParts.engine3Combustion = parts.isEngineOn(3) ? 1 : 0;
ddRemoteAircraftParts.engine4Combustion = parts.isEngineOn(4) ? 1 : 0;
return this->sendRemoteAircraftPartsToSim(simObj, ddRemoteAircraftParts);
return this->sendRemoteAircraftPartsToSimulator(simObj, ddRemoteAircraftParts, parts.getLights());
}
bool CSimulatorFsx::sendRemoteAircraftPartsToSim(const CSimConnectObject &simObj, DataDefinitionRemoteAircraftParts &ddRemoteAircraftParts)
bool CSimulatorFsx::sendRemoteAircraftPartsToSimulator(const CSimConnectObject &simObj, DataDefinitionRemoteAircraftParts &ddRemoteAircraftParts, const CAircraftLights &lights)
{
Q_ASSERT(m_hSimConnect);
const DWORD objectId = simObj.getObjectId();
if (m_lastPartsSendToSim.contains(objectId))
{
// no need to send same parts
if (m_lastPartsSendToSim[objectId] == ddRemoteAircraftParts) { return true; }
}
// same as in simulator or same as already send to simulator
const CAircraftLights sentLights(simObj.getLightsAsSent());
if (simObj.getPartsAsSent() == ddRemoteAircraftParts &&
(simObj.getCurrentLightsInSimulator() == lights || sentLights == lights)) { return true; }
m_lastPartsSendToSim[objectId] = ddRemoteAircraftParts;
HRESULT hr = SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts,
objectId, 0, 0,
sizeof(DataDefinitionRemoteAircraftParts), &ddRemoteAircraftParts);
// in case we sent we sent everything
const HRESULT hr = SimConnect_SetDataOnSimObject(m_hSimConnect, CSimConnectDefinitions::DataRemoteAircraftParts,
objectId, SIMCONNECT_DATA_SET_FLAG_DEFAULT, 0,
sizeof(DataDefinitionRemoteAircraftParts), &ddRemoteAircraftParts);
if (hr != S_OK) { CLogMessage(this).warning("Failed so set parts on SimObject '%1' callsign: '%2'") << simObj.getObjectId() << simObj.getCallsign(); }
// lights we can set directly
SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventLandingLightsSet, lights.isLandingOn() ? 1.0 : 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventStrobesSet, lights.isStrobeOn() ? 1.0 : 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
// lights we need to toggle (risk with quickly changing values that we accidentally toggle back)
// I sent 0/1 here, but the value is supposed to be irrelevant since "toggling"
if (!sentLights.isNull())
{
if (sentLights.isTaxiOn() == lights.isTaxiOn())
{
SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventToggleTaxiLights, 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
}
if (sentLights.isNavOn() == lights.isNavOn())
{
SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventToggleNavLights, 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
}
if (sentLights.isBeaconOn() == lights.isBeaconOn())
{
SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventToggleBeaconLights, 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
}
if (sentLights.isLogoOn() == lights.isLogoOn())
{
SimConnect_TransmitClientEvent(m_hSimConnect, objectId, EventToggleLogoLights, 0.0, SIMCONNECT_GROUP_PRIORITY_HIGHEST, SIMCONNECT_EVENT_FLAG_GROUPID_IS_PRIORITY);
}
}
// Update data
CSimConnectObject &objUdpate = m_simConnectObjects[simObj.getCallsign()];
objUdpate.setPartsAsSent(ddRemoteAircraftParts);
objUdpate.setLightsAsSent(lights); // pretend lights are set
// done
return hr == S_OK;
}
SIMCONNECT_DATA_INITPOSITION CSimulatorFsx::aircraftSituationToFsxPosition(const CAircraftSituation &situation)
{
SIMCONNECT_DATA_INITPOSITION position;
@@ -1114,7 +1146,7 @@ namespace BlackSimPlugin
if (!simObject.hasValidRequestAndObjectId()) { return false; }
if (simObject.getSimDataPeriod() == period) { return true; } // already queried like this
const HRESULT result = SimConnect_RequestDataOnSimObject(m_hSimConnect, simObject.getRequestId(), CSimConnectDefinitions::DataRemoteAircraftSimData, simObject.getObjectId(), period, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED);
const HRESULT result = SimConnect_RequestDataOnSimObject(m_hSimConnect, simObject.getRequestId() + RequestSimDataOffset, CSimConnectDefinitions::DataRemoteAircraftSimData, simObject.getObjectId(), period, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED);
if (result == S_OK)
{
m_simConnectObjects[simObject.getCallsign()].setSimDataPeriod(period);
@@ -1124,6 +1156,15 @@ namespace BlackSimPlugin
return false;
}
bool CSimulatorFsx::requestLightsForSimObject(const CSimConnectObject &simObject)
{
if (!simObject.hasValidRequestAndObjectId()) { return false; }
const HRESULT result = SimConnect_RequestDataOnSimObject(m_hSimConnect, simObject.getRequestId() + RequestLightsOffset, CSimConnectDefinitions::DataRemoteAircraftLights, simObject.getObjectId(), SIMCONNECT_PERIOD_SECOND, SIMCONNECT_CLIENT_DATA_REQUEST_FLAG_CHANGED);
if (result == S_OK) { return true; }
CLogMessage(this).error("Cannot request data on object '%1'") << simObject.getObjectId();
return false;
}
void CSimulatorFsx::initSimulatorInternals()
{
CSimulatorFsCommon::initSimulatorInternals();
@@ -1145,7 +1186,7 @@ namespace BlackSimPlugin
m_syncDeferredCounter = 0;
m_skipCockpitUpdateCycles = 0;
m_interpolationRequest = 0;
m_requestId = FirstRequestId;
m_requestIdSimData = RequestSimDataStart;
m_dispatchErrors = 0;
m_receiveExceptionCount = 0;
CSimulatorFsCommon::reset();
@@ -1155,7 +1196,6 @@ namespace BlackSimPlugin
{
m_simConnectObjects.clear();
m_outOfRealityBubble.clear();
m_lastPartsSendToSim.clear();
CSimulatorFsCommon::clearAllAircraft();
}
@@ -1191,7 +1231,7 @@ namespace BlackSimPlugin
{
constexpr int QueryInterval = 5 * 1000; // 5 seconds
m_timer->setInterval(QueryInterval);
this->m_timer->setObjectName(this->objectName().append(":m_timer"));
m_timer->setObjectName(this->objectName().append(":m_timer"));
connect(m_timer, &QTimer::timeout, this, &CSimulatorFsxListener::ps_checkConnection);
}

View File

@@ -171,7 +171,7 @@ namespace BlackSimPlugin
void onSimExit();
//! Get new request id, overflow safe
DWORD obtainRequestId();
DWORD obtainRequestIdSimData();
//! Init when connected
HRESULT initWhenConnected();
@@ -194,7 +194,7 @@ namespace BlackSimPlugin
const BlackMisc::Aviation::CAircraftSituation &interpolatedSituation, const BlackMisc::Simulation::IInterpolator::InterpolationStatus &interpolationStatus);
//! Send parts to sim
bool sendRemoteAircraftPartsToSim(const CSimConnectObject &simObj, DataDefinitionRemoteAircraftParts &ddRemoteAircraftParts);
bool sendRemoteAircraftPartsToSimulator(const CSimConnectObject &simObj, DataDefinitionRemoteAircraftParts &ddRemoteAircraftParts, const BlackMisc::Aviation::CAircraftLights &lights);
//! Called when data about our own aircraft are received
void updateOwnAircraftFromSimulator(const DataDefinitionOwnAircraft &simulatorOwnAircraft);
@@ -214,6 +214,12 @@ namespace BlackSimPlugin
//! Set ID of a SimConnect object, so far we only have an request id in the object
bool setSimConnectObjectId(DWORD requestID, DWORD objectID);
//! Remember current lights
bool setCurrentLights(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftLights &lights);
//! Remember lights sent
bool setLightsAsSent(const BlackMisc::Aviation::CCallsign &callsign, const BlackMisc::Aviation::CAircraftLights &lights);
//! Display receive exceptions?
bool stillDisplayReceiveExceptions();
@@ -229,32 +235,45 @@ namespace BlackSimPlugin
//! Request data for a simObject (aka remote aircraft)
bool requestDataForSimObject(const CSimConnectObject &simObject, SIMCONNECT_PERIOD period = SIMCONNECT_PERIOD_SECOND);
//! Request lights for a simObject
bool requestLightsForSimObject(const CSimConnectObject &simObject);
//! FSX position as string
static QString fsxPositionToString(const SIMCONNECT_DATA_INITPOSITION &position);
//! Get the callsigns which are no longer in the provider, but still in m_simConnectObjects
BlackMisc::Aviation::CCallsignSet getCallsignsMissingInProvider() const;
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 FirstRequestId = static_cast<int>(CSimConnectDefinitions::RequestEndMarker);
//! Request for sim data?
static bool isRequestForSimData(DWORD requestId) { return requestId >= (RequestSimDataStart + RequestSimDataOffset) && requestId < (RequestSimDataStart + RequestSimDataOffset + SimObjectNumber); }
//! Request for sim data?
static bool isRequestForLights(DWORD requestId) { return requestId >= (RequestSimDataStart + RequestLightsOffset) && requestId < (RequestSimDataStart + RequestLightsOffset + SimObjectNumber); }
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 SimObjectNumber = 10000; //!< max. SimObjects at the same time
static constexpr int RequestSimDataStart = static_cast<int>(CSimConnectDefinitions::RequestEndMarker);
static constexpr int RequestSimDataEnd = RequestSimDataStart + SimObjectNumber - 1;
static constexpr int RequestSimDataOffset = 0 * SimObjectNumber;
static constexpr int RequestLightsOffset = 1 * SimObjectNumber;
QString m_simConnectVersion; //!< SimConnect version
bool m_simConnected = false; //!< Is simulator connected?
bool m_simSimulating = false; //!< Simulator running?
bool m_useSbOffsets = true; //!< with SB offsets
int m_syncDeferredCounter = 0; //!< Set when synchronized, used to wait some time
int m_simConnectTimerId = -1; //!< Timer identifier
int m_simConnectTimerId = -1; //!< Timer identifier
int m_skipCockpitUpdateCycles = 0; //!< skip some update cycles to allow changes in simulator cockpit to be set
int m_interpolationRequest = 0; //!< current interpolation request
int m_interpolationRequest = 0; //!< current interpolation request
int m_dispatchErrors = 0; //!< number of dispatched failed, \sa ps_dispatch
int m_receiveExceptionCount = 0; //!< exceptions
DWORD m_requestId = FirstRequestId; //!< request id, use obtainRequestId() to get id
HANDLE m_hSimConnect = nullptr; //!< handle to SimConnect object
CSimConnectObjects m_simConnectObjects; //!< AI objects and their object / request ids
QTimer m_realityBubbleTimer { this }; //!< updating of aircraft out of reality bubble
BlackMisc::Simulation::CSimulatedAircraftList m_outOfRealityBubble; //!< aircraft removed by FSX because they are out of reality bubble
QHash<DWORD, DataDefinitionRemoteAircraftParts> m_lastPartsSendToSim; //!< Last parts send to simulator, avoid always sending same parts
DWORD m_requestIdSimData = RequestSimDataStart; //!< request id, use obtainRequestId() to get id
BlackMisc::Simulation::CSimulatedAircraftList m_outOfRealityBubble; //!< aircraft removed by FSX because they are out of reality bubble
};
//! Listener for FSX

View File

@@ -160,7 +160,9 @@ namespace BlackSimPlugin
if (success)
{
const CSimConnectObject simObject = simulatorFsx->getSimConnectObjects().getSimObjectForObjectId(objectId);
HRESULT result = simulatorFsx->requestDataForSimObject(simObject);
HRESULT result = S_OK;
result += simulatorFsx->requestDataForSimObject(simObject);
result += simulatorFsx->requestLightsForSimObject(simObject);
Q_UNUSED(result);
}
else
@@ -216,11 +218,12 @@ namespace BlackSimPlugin
}
default:
{
static_assert(sizeof(DataDefinitionRemoteAircraftSimData) == 5 * sizeof(double), "DataDefinitionRemoteAircraftSimData has an incorrect size.");
const CSimConnectObject simObj = simulatorFsx->getSimConnectObjects().getSimObjectForRequestId(requestId);
if (simObj.hasValidRequestAndObjectId())
const DWORD objectId = pObjData->dwObjectID;
if (isRequestForSimData(requestId))
{
const DWORD objectId = pObjData->dwObjectID;
static_assert(sizeof(DataDefinitionRemoteAircraftSimData) == 5 * sizeof(double), "DataDefinitionRemoteAircraftSimData has an incorrect size.");
const CSimConnectObject simObj = simulatorFsx->getSimConnectObjects().getSimObjectForObjectId(objectId);
if (!simObj.hasValidRequestAndObjectId()) break;
const DataDefinitionRemoteAircraftSimData *remoteAircraftSimData = (DataDefinitionRemoteAircraftSimData *)&pObjData->dwData;
// extra check, but ids should be the same
if (objectId == simObj.getObjectId())
@@ -228,6 +231,25 @@ namespace BlackSimPlugin
simulatorFsx->updateRemoteAircraftFromSimulator(simObj, *remoteAircraftSimData);
}
}
else if (isRequestForLights(requestId))
{
static_assert(sizeof(DataDefinitionRemoteAircraftLights) == 6 * sizeof(double), "DataDefinitionRemoteAircraftLights has an incorrect size.");
const CSimConnectObject simObj = simulatorFsx->getSimConnectObjects().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
simulatorFsx->setCurrentLights(callsign, lights);
if (simObj.getLightsAsSent().isNull())
{
// allows to compare for toggle
simulatorFsx->setLightsAsSent(callsign, lights);
}
}
}
break;
}
break;
@@ -287,7 +309,6 @@ namespace BlackSimPlugin
}
default:
break;
} // main switch
} // method
} // namespace