Load X-Plane remote aircrafts one by one sequentially

This commit is contained in:
Roland Winklmeier
2018-04-30 14:14:51 +02:00
parent 7de5c06c7a
commit bf8ed5c006
5 changed files with 154 additions and 24 deletions

View File

@@ -96,9 +96,11 @@ namespace BlackSimPlugin
m_fastTimer.setObjectName(this->objectName().append(":m_fastTimer"));
m_slowTimer.setObjectName(this->objectName().append(":m_slowTimer"));
m_pendingAddedTimer.setObjectName(this->objectName().append(":m_pendingAddedTimer"));
connect(&m_fastTimer, &QTimer::timeout, this, &CSimulatorXPlane::fastTimerTimeout);
connect(&m_slowTimer, &QTimer::timeout, this, &CSimulatorXPlane::slowTimerTimeout);
connect(&m_airportUpdater, &QTimer::timeout, this, &CSimulatorXPlane::updateAirportsInRange);
connect(&m_pendingAddedTimer, &QTimer::timeout, this, &CSimulatorXPlane::remoteAircraftAddingTimeout);
m_fastTimer.start(100);
m_slowTimer.start(1000);
m_airportUpdater.start(60000);
@@ -260,6 +262,8 @@ namespace BlackSimPlugin
m_serviceProxy->updateAirportsInRange();
connect(m_trafficProxy, &CXSwiftBusTrafficProxy::simFrame, this, &CSimulatorXPlane::updateRemoteAircraft);
connect(m_trafficProxy, &CXSwiftBusTrafficProxy::remoteAircraftData, this, &CSimulatorXPlane::updateRemoteAircraftFromSimulator);
connect(m_trafficProxy, &CXSwiftBusTrafficProxy::remoteAircraftAdded, this, &CSimulatorXPlane::remoteAircraftAdded);
connect(m_trafficProxy, &CXSwiftBusTrafficProxy::remoteAircraftAddingFailed, this, &CSimulatorXPlane::remoteAircraftAddingFailed);
if (m_watcher) { m_watcher->setConnection(m_conn); }
m_trafficProxy->removeAllPlanes();
this->loadCslPackages();
@@ -491,22 +495,19 @@ namespace BlackSimPlugin
Q_ASSERT_X(!newRemoteAircraft.getCallsign().isEmpty(), Q_FUNC_INFO, "empty callsign");
Q_ASSERT_X(newRemoteAircraft.hasModelString(), Q_FUNC_INFO, "missing model string");
m_xplaneAircraftObjects.insert(newRemoteAircraft.getCallsign(), CXPlaneMPAircraft(newRemoteAircraft, this, &m_interpolationLogger));
CAircraftModel aircraftModel = newRemoteAircraft.getModel();
QString livery = aircraftModel.getLivery().getCombinedCode(); //! \todo livery resolution for XP
m_trafficProxy->addPlane(newRemoteAircraft.getCallsign().asString(), aircraftModel.getModelString(),
newRemoteAircraft.getAircraftIcaoCode().getDesignator(),
newRemoteAircraft.getAirlineIcaoCode().getDesignator(),
livery);
QString callsign = newRemoteAircraft.getCallsign().asString();
m_pendingAddedAircrafts.push_back(newRemoteAircraft);
CLogMessage(this).info("XP: Added aircraft %1") << newRemoteAircraft.getCallsign().toQString();
bool rendered = true;
updateAircraftRendered(newRemoteAircraft.getCallsign(), rendered);
CSimulatedAircraft remoteAircraftCopy(newRemoteAircraft);
remoteAircraftCopy.setRendered(rendered);
emit this->aircraftRenderingChanged(remoteAircraftCopy);
if (m_pendingAddedAircrafts.size() == 1)
{
CAircraftModel aircraftModel = newRemoteAircraft.getModel();
QString livery = aircraftModel.getLivery().getCombinedCode(); //! \todo livery resolution for XP
m_trafficProxy->addPlane(callsign, aircraftModel.getModelString(),
newRemoteAircraft.getAircraftIcaoCode().getDesignator(),
newRemoteAircraft.getAirlineIcaoCode().getDesignator(),
livery);
m_pendingAddedTimer.start(5000);
}
return true;
}
@@ -519,21 +520,36 @@ namespace BlackSimPlugin
if (callsign.isEmpty()) { return false; } // can happen if an object is not an aircraft
// really remove from simulator
if (!m_xplaneAircraftObjects.contains(callsign)) { return false; } // already fully removed or not yet added
if (!m_xplaneAircraftObjects.contains(callsign) && !m_pendingAddedAircrafts.containsCallsign(callsign)) { return false; } // already fully removed or not yet added
// mark in provider
const bool updated = this->updateAircraftRendered(callsign, false);
if (updated)
{
Q_ASSERT_X(m_xplaneAircraftObjects.contains(callsign), Q_FUNC_INFO, "Aircraft removed");
const CXPlaneMPAircraft &xplaneAircraft = m_xplaneAircraftObjects[callsign];
CSimulatedAircraft aircraft(xplaneAircraft.getAircraft());
aircraft.setRendered(false);
emit this->aircraftRenderingChanged(aircraft);
if (m_xplaneAircraftObjects.contains(callsign))
{
const CXPlaneMPAircraft &xplaneAircraft = m_xplaneAircraftObjects[callsign];
CSimulatedAircraft aircraft(xplaneAircraft.getAircraft());
aircraft.setRendered(false);
emit this->aircraftRenderingChanged(aircraft);
}
if (m_pendingAddedAircrafts.containsCallsign(callsign))
{
CSimulatedAircraft aircraft = m_pendingAddedAircrafts.findFirstByCallsign(callsign);
aircraft.setRendered(false);
emit this->aircraftRenderingChanged(aircraft);
}
}
m_trafficProxy->removePlane(callsign.asString());
m_xplaneAircraftObjects.remove(callsign);
m_pendingAddedAircrafts.removeByCallsign(callsign);
// Stop the timer if there is nothing left
if (m_pendingAddedAircrafts.empty())
{
m_pendingAddedTimer.stop();
}
// bye
return true;
@@ -809,6 +825,81 @@ namespace BlackSimPlugin
if (this->isConnected()) { m_serviceProxy->updateAirportsInRange(); }
}
void CSimulatorXPlane::remoteAircraftAdded(const QString &callsign)
{
if (m_pendingAddedAircrafts.containsCallsign(callsign))
{
CSimulatedAircraft addedRemoteAircraft = m_pendingAddedAircrafts.findFirstByCallsign(callsign);
m_pendingAddedAircrafts.removeByCallsign(callsign);
m_xplaneAircraftObjects.insert(addedRemoteAircraft.getCallsign(), CXPlaneMPAircraft(addedRemoteAircraft, this, &m_interpolationLogger));
CLogMessage(this).info("XP: Added aircraft %1") << addedRemoteAircraft.getCallsign().toQString();
bool rendered = true;
updateAircraftRendered(addedRemoteAircraft.getCallsign(), rendered);
addedRemoteAircraft.setRendered(rendered);
emit this->aircraftRenderingChanged(addedRemoteAircraft);
}
if (m_pendingAddedAircrafts.size() > 0)
{
CSimulatedAircraft newRemoteAircraft = m_pendingAddedAircrafts.front();
CAircraftModel aircraftModel = newRemoteAircraft.getModel();
QString livery = aircraftModel.getLivery().getCombinedCode(); //! \todo livery resolution for XP
m_trafficProxy->addPlane(newRemoteAircraft.getCallsign().toQString(), aircraftModel.getModelString(),
newRemoteAircraft.getAircraftIcaoCode().getDesignator(),
newRemoteAircraft.getAirlineIcaoCode().getDesignator(),
livery);
m_pendingAddedTimer.start(5000);
}
else
{
m_pendingAddedTimer.stop();
}
}
void CSimulatorXPlane::remoteAircraftAddingFailed(const QString &callsign)
{
CLogMessage(this).info("XP: Adding aircraft failed: %1") << callsign;
m_pendingAddedAircrafts.removeByCallsign(callsign);
if (m_pendingAddedAircrafts.size() > 0)
{
CSimulatedAircraft newRemoteAircraft = m_pendingAddedAircrafts.front();
CAircraftModel aircraftModel = newRemoteAircraft.getModel();
QString livery = aircraftModel.getLivery().getCombinedCode(); //! \todo livery resolution for XP
m_trafficProxy->addPlane(newRemoteAircraft.getCallsign().toQString(), aircraftModel.getModelString(),
newRemoteAircraft.getAircraftIcaoCode().getDesignator(),
newRemoteAircraft.getAirlineIcaoCode().getDesignator(),
livery);
m_pendingAddedTimer.start(5000);
}
else
{
m_pendingAddedTimer.stop();
}
}
void CSimulatorXPlane::remoteAircraftAddingTimeout()
{
Q_ASSERT(m_pendingAddedAircrafts.size() > 0);
CSimulatedAircraft newRemoteAircraft = m_pendingAddedAircrafts.front();
QString callsign = newRemoteAircraft.getCallsign().toQString();
CLogMessage(this).warning("XP: Adding aircraft timed out: %1. Trying again.") << callsign;
m_trafficProxy->removePlane(callsign);
CAircraftModel aircraftModel = newRemoteAircraft.getModel();
QString livery = aircraftModel.getLivery().getCombinedCode(); //! \todo livery resolution for XP
m_trafficProxy->addPlane(callsign, aircraftModel.getModelString(),
newRemoteAircraft.getAircraftIcaoCode().getDesignator(),
newRemoteAircraft.getAirlineIcaoCode().getDesignator(),
livery);
m_pendingAddedTimer.start(5000);
}
BlackCore::ISimulator *CSimulatorXPlaneFactory::create(const CSimulatorPluginInfo &info,
IOwnAircraftProvider *ownAircraftProvider,
IRemoteAircraftProvider *remoteAircraftProvider,

View File

@@ -25,6 +25,7 @@
#include "blackmisc/simulation/data/modelcaches.h"
#include "blackmisc/simulation/settings/simulatorsettings.h"
#include "blackmisc/simulation/settings/xswiftbussettings.h"
#include "blackmisc/simulation/simulatedaircraftlist.h"
#include "blackmisc/weather/weathergrid.h"
#include "blackmisc/settingscache.h"
#include "blackmisc/statusmessage.h"
@@ -180,6 +181,9 @@ namespace BlackSimPlugin
void requestRemoteAircraftDataFromXPlane();
void updateRemoteAircraftFromSimulator(const QString &callsign, double latitudeDeg, double longitudeDeg, double elevationMeters, double modelVerticalOffsetMeters);
void updateAirportsInRange();
void remoteAircraftAdded(const QString &callsign);
void remoteAircraftAddingFailed(const QString &callsign);
void remoteAircraftAddingTimeout();
static constexpr int GuessRemoteAircraftPartsCycle = 20; //!< guess every n-th cycle
@@ -196,8 +200,10 @@ namespace BlackSimPlugin
BlackMisc::CData<BlackMisc::Simulation::Data::TModelSetCacheXP> m_modelSet { this };
// Driver Interpolation
BlackMisc::Simulation::CSimulatedAircraftList m_pendingAddedAircrafts;
CXPlaneMPAircraftObjects m_xplaneAircraftObjects; //!< XPlane multiplayer aircraft
int m_interpolationRequest = 0; //!< current interpolation request
QTimer m_pendingAddedTimer;
XPlaneData m_xplaneData;

View File

@@ -70,6 +70,12 @@ namespace BlackSimPlugin
//! \remark from simulator to driver for elevation and CG
void remoteAircraftData(const QString &callsign, double latitudeDeg, double longitudeDeg, double elevationMeters, double modelVerticalOffsetMeters);
//! Remote aircraft successfully added
void remoteAircraftAdded(const QString &callsign);
//! Remote aircraft adding failed
void remoteAircraftAddingFailed(const QString &callsign);
public slots:
//! \copydoc XSwiftBus::CTraffic::initialize
bool initialize();

View File

@@ -76,8 +76,7 @@ namespace XSwiftBus
{
if (! s_legacyDataOK) { return false; }
auto dir = g_xplanePath + "Resources" + g_sep + "plugins" + g_sep + "xswiftbus" + g_sep;
auto err = XPMPMultiplayerInit(preferences, preferences, dir.c_str());
auto err = XPMPMultiplayerInit(preferences, preferences);
if (*err) { cleanup(); return false; }
m_initialized = true;
@@ -124,6 +123,22 @@ namespace XSwiftBus
sendDBusMessage(signalRemoteAircraftData);
}
void CTraffic::emitPlaneAdded(const std::string &callsign)
{
CDBusMessage signalPlaneAdded = CDBusMessage::createSignal(XSWIFTBUS_TRAFFIC_OBJECTPATH, XSWIFTBUS_TRAFFIC_INTERFACENAME, "remoteAircraftAdded");
signalPlaneAdded.beginArgumentWrite();
signalPlaneAdded.appendArgument(callsign);
sendDBusMessage(signalPlaneAdded);
}
void CTraffic::emitPlaneAddingFailed(const std::string &callsign)
{
CDBusMessage signalPlaneAddingFailed = CDBusMessage::createSignal(XSWIFTBUS_TRAFFIC_OBJECTPATH, XSWIFTBUS_TRAFFIC_INTERFACENAME, "remoteAircraftAddingFailed");
signalPlaneAddingFailed.beginArgumentWrite();
signalPlaneAddingFailed.appendArgument(callsign);
sendDBusMessage(signalPlaneAddingFailed);
}
void CTraffic::orbitRemotePlane(const std::string &callsign)
{
m_planeViewCallsign = callsign;
@@ -216,7 +231,7 @@ namespace XSwiftBus
}
else
{
id = XPMPCreatePlaneWithModelName(modelName.c_str(), aircraftIcao.c_str(), airlineIcao.c_str(), livery.c_str(), getPlaneData, static_cast<void *>(this));
id = XPMPCreatePlaneWithModelName(modelName.c_str(), aircraftIcao.c_str(), airlineIcao.c_str(), livery.c_str(), getPlaneData, planeLoaded, static_cast<void *>(this));
}
if (id)

View File

@@ -125,6 +125,8 @@ namespace XSwiftBus
void emitSimFrame();
void emitRemoteAircraftData(const std::string &callsign, double latitude, double longitude, double elevation, double modelVerticalOffset);
void emitPlaneAdded(const std::string &callsign);
void emitPlaneAddingFailed(const std::string &callsign);
void orbitRemotePlane(const std::string &callsign);
static int preferences(const char *section, const char *name, int def);
@@ -169,6 +171,16 @@ namespace XSwiftBus
{
return static_cast<CTraffic *>(self)->getPlaneData(id, dataType, io_data);
}
static void planeLoaded(void *id, bool succeeded, void *self)
{
auto *traffic = static_cast<CTraffic *>(self);
auto planeIt = traffic->m_planesById.find(id);
if (planeIt == traffic->m_planesById.end()) { return; }
if (succeeded) { traffic->emitPlaneAdded(planeIt->second->callsign); }
else { traffic->emitPlaneAddingFailed(planeIt->second->callsign); }
}
};
}