9 #include <QDBusServiceWatcher>
10 #include <QElapsedTimer>
16 #include "dbus/dbus.h"
17 #include "qcompilerdetection.h"
49 #include "misc/simulation/settings/xswiftbussettingsqtfree.inc"
60 using namespace swift::config;
62 using namespace swift::misc::aviation;
63 using namespace swift::misc::network;
64 using namespace swift::misc::physical_quantities;
65 using namespace swift::misc::geo;
66 using namespace swift::misc::simulation;
67 using namespace swift::misc::simulation::settings;
68 using namespace swift::misc::weather;
73 const QString &xswiftbusServiceName()
75 static const QString name(
"org.swift-project.xswiftbus");
78 const QString &commitHash()
80 static const QString hash(XSWIFTBUS_COMMIT);
85 namespace swift::simplugin::xplane
90 : CSimulatorPluginCommon(info, ownAircraftProvider, remoteAircraftProvider, clientProvider, parent)
92 m_watcher =
new QDBusServiceWatcher(
this);
93 m_watcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration);
94 m_watcher->addWatchedService(xswiftbusServiceName());
95 m_watcher->setObjectName(
"QDBusServiceWatcher");
96 connect(m_watcher, &QDBusServiceWatcher::serviceUnregistered,
this,
97 &CSimulatorXPlane::onDBusServiceUnregistered, Qt::QueuedConnection);
99 m_fastTimer.setObjectName(this->objectName().append(
":m_fastTimer"));
100 m_slowTimer.setObjectName(this->objectName().append(
":m_slowTimer"));
101 m_pendingAddedTimer.setObjectName(this->objectName().append(
":m_pendingAddedTimer"));
102 connect(&m_fastTimer, &QTimer::timeout,
this, &CSimulatorXPlane::fastTimerTimeout);
103 connect(&m_slowTimer, &QTimer::timeout,
this, &CSimulatorXPlane::slowTimerTimeout);
104 connect(&m_airportUpdater, &QTimer::timeout,
this, &CSimulatorXPlane::updateAirportsInRange);
105 connect(&m_pendingAddedTimer, &QTimer::timeout,
this, &CSimulatorXPlane::addNextPendingAircraft);
106 m_fastTimer.start(100);
107 m_slowTimer.start(1000);
108 m_airportUpdater.start(60 * 1000);
109 m_pendingAddedTimer.start(5000);
111 this->
setDefaultModel({
"Jets A320_a A320_a_Austrian_Airlines A320_a_Austrian_Airlines",
112 CAircraftModel::TypeModelMatchingDefaultModel,
"A320 AUA",
114 this->resetXPlaneData();
124 CSimulatorPluginCommon::unload();
131 return QStringLiteral(
"Add-time: %1ms/%2ms").arg(m_statsAddCurrentTimeMs).arg(m_statsAddMaxTimeMs);
136 m_statsAddMaxTimeMs = -1;
137 m_statsAddCurrentTimeMs = -1;
145 return m_xplaneAircraftObjects[callsign].getInterpolationMessages(setup.
getInterpolatorMode());
152 if (!m_trafficProxy) {
return false; }
153 if (!m_xplaneAircraftObjects.contains(callsign)) {
return false; }
175 const QString &hint,
bool ignoreOutsideRange)
180 if (isSuspiciousTerrainValue(plane))
184 if (ignoreOutsideRange && distance > maxTerrainRequestDistance()) {
return false; }
186 static const CLength threshold = maxTerrainRequestDistance() * 0.50;
187 if (distance > threshold)
193 this->setMinTerrainProbeDistance(distance);
195 u
"Suspicous XPlane probe [%1] value %2 for '%3' ignored, distance: %4 min.disance: %5 water: %6")
198 << m_minSuspicousTerrainProbe.
valueRoundedAsString(CLengthUnit::NM(), 2) << boolToYesNo(waterFlag);
208 static const QString hint(
"probe callback");
209 if (!this->handleProbeValue(plane, callsign, isWater, hint,
false))
214 CSimulatorPluginCommon::callbackReceivedRequestedElevation(plane, callsign, isWater);
220 CSimulatorPluginCommon::setFlightNetworkConnected(connected);
223 bool CSimulatorXPlane::isSuspiciousTerrainValue(
const CElevationPlane &elevation)
227 return valueFt < 1.0;
230 const CLength &CSimulatorXPlane::maxTerrainRequestDistance()
232 static const CLength d(70.0, CLengthUnit::NM());
238 m_aircraftAddedFailed.
clear();
239 CSimulatorPluginCommon::clearAllRemoteAircraftData();
240 m_minSuspicousTerrainProbe.
setNull();
246 if (reference.
isNull()) {
return false; }
249 if (callsign.
isEmpty()) {
return false; }
253 if (!d.
isNull() && d > maxTerrainRequestDistance())
267 static const CAltitude alt(0, CAltitude::MeanSeaLevel, CLengthUnit::ft());
271 using namespace std::placeholders;
275 m_trafficProxy->getElevationAtPosition(callsign, pos.
latitude().
value(CAngleUnit::deg()),
285 if (ident) {
return CTransponder::StateIdent; }
286 if (xplaneMode == 0 || xplaneMode == 1) {
return CTransponder::StateStandby; }
287 return CTransponder::ModeC;
293 void CSimulatorXPlane::fastTimerTimeout()
310 const CAltitude altitude { m_xplaneData.
altitudeM, CAltitude::MeanSeaLevel, CLengthUnit::m() };
312 const CAltitude pressureAltitude(altitude.toPressureAltitude(seaLevelPressure));
315 m_altitudeDelta = {};
322 CAltitude::PressureAltitude, CLengthUnit::ft());
323 m_altitudeDelta = pressureAltitude - pressureAltitudeXP12;
325 situation.
setAltitude({ altitude - m_altitudeDelta, CAltitude::MeanSeaLevel });
354 const int v1 = qRound(m_xplaneData.
com1Volume * 100);
355 com1.setVolumeReceive(v1);
358 const bool changedCom1 = myAircraft.getCom1System() != com1;
362 const int v2 = qRound(m_xplaneData.
com2Volume * 100);
363 com2.setVolumeReceive(v2);
366 const bool changedCom2 = myAircraft.getCom2System() != com2;
368 transponder = CTransponder::getStandardTransponder(m_xplaneData.
xpdrCode,
370 const bool changedXpr = (myAircraft.getTransponder() != transponder);
372 if (changedCom1 || changedCom2 || changedXpr)
379 void CSimulatorXPlane::slowTimerTimeout()
391 for (
int engineNumber = 0; engineNumber < m_xplaneData.
enginesN1Percentage.size(); ++engineNumber)
414 for (CXPlaneMPAircraft &xplaneAircraft : m_xplaneAircraftObjects)
417 const CCallsign cs = xplaneAircraft.getCallsign();
425 xplaneAircraft.setSimulatedAircraft(simulatedAircraft);
431 for (
const CCallsign &cs : invalid) { this->triggerRemoveAircraft(cs, ++i * 100); }
435 if ((m_slowTimerCalls % 3u) == 0u) { this->requestRemoteAircraftDataFromXPlane(); }
439 if ((m_slowTimerCalls % 5u) == 0u)
441 constexpr
double warningMiles = 1;
442 constexpr
double disconnectMiles = 2;
447 if (previousMiles < disconnectMiles && m_trackMilesShort >= disconnectMiles)
451 else if (previousMiles < warningMiles && m_trackMilesShort >= warningMiles)
464 const QString dBusServerAddress = m_xSwiftBusServerSettings.
getThreadLocal().getDBusServerAddressQt();
466 if (CDBusServer::isSessionOrSystemAddress(dBusServerAddress))
468 m_dBusConnection = QDBusConnection::sessionBus();
469 m_dbusMode = Session;
471 else if (CDBusServer::isQtDBusAddress(dBusServerAddress))
473 m_dBusConnection = QDBusConnection::connectToPeer(dBusServerAddress,
"xswiftbus");
474 if (!m_dBusConnection.isConnected()) {
return false; }
482 bool s = m_dBusConnection.connect(QString(), DBUS_PATH_LOCAL, DBUS_INTERFACE_LOCAL,
"Disconnected",
this,
483 SLOT(onDBusServiceUnregistered()));
495 QString xplaneVersion = QStringLiteral(
"%1.%2")
500 &CSimulatorXPlane::emitOwnAircraftModelChanged);
504 &CSimulatorXPlane::onRemoteAircraftAdded);
506 &CSimulatorXPlane::onRemoteAircraftAddingFailed);
507 if (m_watcher) { m_watcher->setConnection(m_dBusConnection); }
511 this->sendXSwiftBusSettings();
514 this->loadCslPackages();
526 this->disconnectFromDBus();
527 if (m_watcher) { m_watcher->setConnection(m_dBusConnection); }
528 delete m_serviceProxy;
529 delete m_trafficProxy;
530 m_serviceProxy =
nullptr;
531 m_trafficProxy =
nullptr;
532 m_fastTimerCalls = 0;
533 m_slowTimerCalls = 0;
539 void CSimulatorXPlane::onDBusServiceUnregistered()
541 if (!m_serviceProxy) {
return; }
544 if (m_dbusMode == P2P) { m_dBusConnection.disconnectFromPeer(m_dBusConnection.name()); }
545 m_dBusConnection = QDBusConnection {
"default" };
546 if (m_watcher) { m_watcher->setConnection(m_dBusConnection); }
547 delete m_serviceProxy;
548 delete m_trafficProxy;
549 m_serviceProxy =
nullptr;
550 m_trafficProxy =
nullptr;
554 void CSimulatorXPlane::emitOwnAircraftModelChanged(
const QString &path,
const QString &filename,
555 const QString &livery,
const QString &icao,
556 const QString &modelString,
const QString &name,
557 const QString &description)
559 CAircraftModel model(modelString, CAircraftModel::TypeOwnSimulatorModel, CSimulatorInfo::XPLANE, name,
561 if (!livery.isEmpty()) { model.setModelString(model.getModelString() +
" " + livery); }
562 model.setFileName(path +
"/" + filename);
573 static bool isInFunction =
false;
574 if (isInFunction) {
return; }
577 std::vector<int> msgBoxValues = m_xSwiftBusServerSettings.
getThreadLocal().getMessageBoxValuesVector();
578 QColor color = msgBoxValues[9];
588 isInFunction =
false;
596 std::vector<int> msgBoxValues = m_xSwiftBusServerSettings.
getThreadLocal().getMessageBoxValuesVector();
601 else { color = msgBoxValues[6]; }
604 color.redF(), color.greenF(), color.blueF());
609 return m_xplaneAircraftObjects.contains(callsign);
615 if (originator == this->
identifier()) {
return false; }
618 auto com1 = CComSystem::getCom1System({ m_xplaneData.
com1ActiveKhz, CFrequencyUnit::kHz() },
620 auto com2 = CComSystem::getCom2System({ m_xplaneData.
com2ActiveKhz, CFrequencyUnit::kHz() },
622 auto xpdr = CTransponder::getStandardTransponder(m_xplaneData.
xpdrCode,
652 if (originator == this->
identifier()) {
return false; }
660 void CSimulatorXPlane::loadCslPackages()
667 Prefix(
const QString &p) : s(p +
'/') {}
668 QString parent()
const
670 return s.section(
'/', 0, -2, QString::SectionSkipEmpty | QString::SectionIncludeLeadingSep);
672 bool isPrefixOf(
const QString &o)
const {
return o.startsWith(s); }
678 struct PrefixComparator
680 bool operator()(
const Prefix &a,
const QString &b)
const
682 return QStringView(a.s) < QStringView(b).left(a.s.size());
684 bool operator()(
const QString &a,
const Prefix &b)
const
686 return QStringView(a).left(b.s.size()) < QStringView(b.s);
691 QList<Prefix> packages;
697 for (
const auto &model : models)
699 const QString &modelFile = model.getFileName();
700 if (modelFile.isEmpty() || !QFile::exists(modelFile)) {
continue; }
703 auto it = std::lower_bound(packages.begin(), packages.end(), modelFile, PrefixComparator());
704 if (it != packages.end() && it->isPrefixOf(modelFile)) {
continue; }
707 QString
package = findCslPackage(modelFile);
708 if (package.isEmpty()) {
continue; }
709 packages.insert(it, package);
715 for (
const Prefix &package : std::as_const(packages)) { superpackages.
insert(package.parent()); }
716 QStringList superpackagesList = superpackages;
719 for (
const QString &package : superpackagesList)
721 if (CDirectoryUtils::isSameOrSubDirectoryOf(package, simDir))
724 if (!message.isEmpty())
732 u
"CSL package '%1' can not be loaded as it is outside the X-Plane installation directory")
738 QString CSimulatorXPlane::findCslPackage(
const QString &modelFile)
741 const QFileInfo info(modelFile);
742 QDir dir = info.isDir() ? QDir(modelFile) : info.dir();
744 if (dir.exists(QStringLiteral(
"xsb_aircraft.txt"))) {
return dir.path(); }
757 Q_ASSERT_X(CThreadUtils::isInThisThread(
this), Q_FUNC_INFO,
"thread");
758 Q_ASSERT_X(!newRemoteAircraft.
getCallsign().
isEmpty(), Q_FUNC_INFO,
"empty callsign");
759 Q_ASSERT_X(newRemoteAircraft.
hasModelString(), Q_FUNC_INFO,
"missing model string");
771 if (this->canAddAircraft())
775 const qint64 now = QDateTime::currentMSecsSinceEpoch();
776 m_addingInProgressAircraft.insert(newRemoteAircraft.
getCallsign(), now);
783 CLogMessage(
this).
warning(u
"Model for '%1' has no callsign, maybe using a default model") << callsign;
804 m_pendingToBeAddedAircraft.
replaceOrAdd(newRemoteAircraft);
815 Q_ASSERT_X(CThreadUtils::isInThisThread(
this), Q_FUNC_INFO,
"wrong thread");
816 if (callsign.
isEmpty()) {
return false; }
819 if (!this->
isTestMode() && !m_xplaneAircraftObjects.contains(callsign) &&
820 !m_pendingToBeAddedAircraft.
containsCallsign(callsign) && !m_addingInProgressAircraft.contains(callsign))
830 if (m_xplaneAircraftObjects.contains(callsign))
846 if (m_addingInProgressAircraft.contains(callsign))
849 QPointer<CSimulatorXPlane> myself(
this);
851 if (!myself) {
return; }
852 m_addingInProgressAircraft.remove(callsign);
859 m_xplaneAircraftObjects.remove(callsign);
863 return CSimulatorPluginCommon::physicallyRemoveRemoteAircraft(callsign);
869 m_pendingToBeAddedAircraft.
clear();
870 m_addingInProgressAircraft.clear();
871 return CSimulatorPluginCommon::physicallyRemoveAllRemoteAircraft();
882 if (!m_trafficProxy || !m_trafficProxy->
isValid()) {
return false; }
887 void CSimulatorXPlane::updateRemoteAircraft()
889 Q_ASSERT_X(CThreadUtils::isInThisThread(
this), Q_FUNC_INFO,
"thread");
892 if (remoteAircraftNo < 1) {
return; }
896 const qint64 currentTimestamp = QDateTime::currentMSecsSinceEpoch();
899 PlanesPositions planesPositions;
900 PlanesSurfaces planesSurfaces;
901 PlanesTransponders planesTransponders;
903 uint32_t aircraftNumber = 0;
906 for (
const CXPlaneMPAircraft &xplaneAircraft : std::as_const(m_xplaneAircraftObjects))
908 const CCallsign callsign(xplaneAircraft.getCallsign());
909 const bool hasCallsign = !callsign.
isEmpty();
918 if (!callsignsInRange.
contains(callsign)) {
continue; }
920 planesTransponders.callsigns.push_back(callsign.
asString());
921 planesTransponders.codes.push_back(xplaneAircraft.getAircraft().getTransponderCode());
923 planesTransponders.idents.push_back(transponderMode == CTransponder::StateIdent);
924 planesTransponders.modeCs.push_back(transponderMode == CTransponder::ModeC);
932 xplaneAircraft.getInterpolation(currentTimestamp, setup, aircraftNumber++);
938 const CLength relativeAltitude =
940 const double altitudeDeltaWeight =
941 2 - qBound(3000.0, relativeAltitude.
abs().
value(CLengthUnit::ft()), 6000.0) / 3000;
942 const CLength alt = interpolatedSituation.getAltitude() +
943 m_altitudeDelta * altitudeDeltaWeight *
944 (1 - interpolatedSituation.getOnGroundInfo().getGroundFactor());
945 interpolatedSituation.setAltitude({ alt, interpolatedSituation.getAltitude().getReferenceDatum() });
948 if (updateAllAircraft || !this->
isEqualLastSent(interpolatedSituation))
951 planesPositions.push_back(interpolatedSituation);
966 planesSurfaces.push_back(xplaneAircraft.getCallsign(), parts);
974 if (!planesPositions.isEmpty())
976 if (CBuildConfig::isLocalDeveloperDebugBuild())
978 SWIFT_VERIFY_X(planesPositions.hasSameSizes(), Q_FUNC_INFO,
"Mismatching sizes");
983 if (!planesSurfaces.isEmpty()) { m_trafficProxy->
setPlanesSurfaces(planesSurfaces); }
989 void CSimulatorXPlane::requestRemoteAircraftDataFromXPlane()
997 CCallsignSet callsigns = m_xplaneAircraftObjects.getAllCallsigns();
1000 if (!callsigns.
isEmpty()) { this->requestRemoteAircraftDataFromXPlane(callsigns); }
1003 void CSimulatorXPlane::requestRemoteAircraftDataFromXPlane(
const CCallsignSet &callsigns)
1005 if (callsigns.
isEmpty()) {
return; }
1008 QPointer<CSimulatorXPlane> myself(
this);
1010 csStrings, [=](
const QStringList &callsigns,
const QDoubleList &latitudesDeg,
1011 const QDoubleList &longitudesDeg,
const QDoubleList &elevationsMeters,
1012 const QBoolList &waterFlags,
const QDoubleList &verticalOffsetsMeters) {
1013 if (!myself) {
return; }
1014 this->updateRemoteAircraftFromSimulator(callsigns, latitudesDeg, longitudesDeg, elevationsMeters,
1015 waterFlags, verticalOffsetsMeters);
1019 void CSimulatorXPlane::triggerRequestRemoteAircraftDataFromXPlane(
const CCallsignSet &callsigns)
1021 if (callsigns.
isEmpty()) {
return; }
1022 QPointer<CSimulatorXPlane> myself(
this);
1024 if (!myself) {
return; }
1025 this->requestRemoteAircraftDataFromXPlane(callsigns);
1029 void CSimulatorXPlane::updateRemoteAircraftFromSimulator(
1030 const QStringList &callsigns,
const QDoubleList &latitudesDeg,
const QDoubleList &longitudesDeg,
1031 const QDoubleList &elevationsMeters,
const QBoolList &waterFlags,
const QDoubleList &verticalOffsetsMeters)
1033 const int size = callsigns.size();
1036 if (CBuildConfig::isLocalDeveloperDebugBuild())
1038 Q_ASSERT_X(elevationsMeters.size() == size, Q_FUNC_INFO,
"Wrong elevations");
1039 Q_ASSERT_X(waterFlags.size() == size, Q_FUNC_INFO,
"Wrong waterFlags");
1040 Q_ASSERT_X(latitudesDeg.size() == size, Q_FUNC_INFO,
"Wrong latitudesDeg");
1041 Q_ASSERT_X(longitudesDeg.size() == size, Q_FUNC_INFO,
"Wrong longitudesDeg");
1042 Q_ASSERT_X(verticalOffsetsMeters.size() == size, Q_FUNC_INFO,
"Wrong CG");
1046 static const QString hint(
"remote acft.");
1047 for (
int i = 0; i < size; i++)
1049 const bool emptyCs = callsigns[i].isEmpty();
1051 if (emptyCs) {
continue; }
1054 if (!m_xplaneAircraftObjects.contains(cs)) {
continue; }
1055 const CXPlaneMPAircraft xpAircraft = m_xplaneAircraftObjects[cs];
1056 SWIFT_VERIFY_X(xpAircraft.hasCallsign(), Q_FUNC_INFO,
"Need callsign");
1057 if (!xpAircraft.hasCallsign()) {
continue; }
1060 if (!std::isnan(elevationsMeters[i]))
1062 const CAltitude elevationAlt =
CAltitude(elevationsMeters[i], CLengthUnit::m(), CLengthUnit::ft());
1064 CLongitude(longitudesDeg[i], CAngleUnit::deg()), elevationAlt,
1065 CElevationPlane::singlePointRadius());
1068 const double cgValue = verticalOffsetsMeters[i];
1070 cg = fixSimulatorCg(cg, xpAircraft.getAircraftModel());
1074 const bool waterFlag = waterFlags[i];
1075 const bool useElevation = this->handleProbeValue(elevation, cs, waterFlag, hint,
true);
1077 useElevation ? elevation : CElevationPlane::null(), cg);
1091 return CLength(0.0, CLengthUnit::ft());
1096 void CSimulatorXPlane::disconnectFromDBus()
1098 if (m_dBusConnection.isConnected())
1100 if (m_trafficProxy) { m_trafficProxy->
cleanup(); }
1102 if (m_dbusMode == P2P) { QDBusConnection::disconnectFromPeer(m_dBusConnection.name()); }
1103 else { QDBusConnection::disconnectFromBus(m_dBusConnection.name()); }
1105 m_dBusConnection = QDBusConnection {
"default" };
1108 bool CSimulatorXPlane::sendXSwiftBusSettings()
1111 if (!m_serviceProxy) {
return false; }
1125 if (!m_serviceProxy) {
return s; }
1133 void CSimulatorXPlane::onXSwiftBusSettingsChanged()
1144 this->sendXSwiftBusSettings();
1149 void CSimulatorXPlane::setMinTerrainProbeDistance(
const CLength &distance)
1151 if (distance.
isNull()) {
return; }
1152 if (m_minSuspicousTerrainProbe.
isNull() || distance < m_minSuspicousTerrainProbe)
1154 m_minSuspicousTerrainProbe = distance;
1158 void CSimulatorXPlane::updateAirportsInRange()
1164 void CSimulatorXPlane::onRemoteAircraftAdded(
const QString &callsign)
1166 SWIFT_VERIFY_X(!callsign.isEmpty(), Q_FUNC_INFO,
"Need callsign");
1167 if (callsign.isEmpty()) {
return; }
1172 bool wasPending =
false;
1173 if (m_addingInProgressAircraft.contains(cs))
1176 const qint64 wasStartedMs = m_addingInProgressAircraft.value(cs);
1177 const qint64 deltaTimeMs = QDateTime::currentMSecsSinceEpoch() - wasStartedMs;
1178 m_statsAddCurrentTimeMs = deltaTimeMs;
1179 if (deltaTimeMs > m_statsAddMaxTimeMs) { m_statsAddMaxTimeMs = deltaTimeMs; }
1180 m_addingInProgressAircraft.remove(cs);
1185 CLogMessage(
this).
warning(u
"Aircraft '%1' no longer in range, will be removed") << callsign;
1186 this->triggerRemoveAircraft(cs, TimeoutAdding);
1195 CLogMessage(
this).
warning(u
"Added callsign '%1' was not in progress anymore. Timeout?") << callsign;
1198 const bool rendered =
true;
1201 this->triggerRequestRemoteAircraftDataFromXPlane(cs);
1202 this->triggerAddNextPendingAircraft();
1204 Q_ASSERT_X(addedRemoteAircraft.
hasCallsign(), Q_FUNC_INFO,
1206 Q_ASSERT_X(addedRemoteAircraft.
getCallsign() == cs, Q_FUNC_INFO,
1208 m_xplaneAircraftObjects.insert(cs, CXPlaneMPAircraft(addedRemoteAircraft,
this, &
m_interpolationLogger));
1212 void CSimulatorXPlane::onRemoteAircraftAddingFailed(
const QString &callsign)
1214 SWIFT_VERIFY_X(!callsign.isEmpty(), Q_FUNC_INFO,
"Need callsign");
1215 if (callsign.isEmpty()) {
return; }
1226 CLogMessage(
this).
warning(u
"Adding '%1' failed, but aircraft no longer in range, will be removed")
1230 const bool wasPending = (
static_cast<int>(m_addingInProgressAircraft.remove(cs)) > 0);
1231 Q_UNUSED(wasPending)
1235 m_aircraftAddedFailed.
push_back(failedRemoteAircraft);
1236 m_pendingToBeAddedAircraft.
replaceOrAdd(failedRemoteAircraft);
1238 this->triggerAddNextPendingAircraft();
1241 void CSimulatorXPlane::addNextPendingAircraft()
1243 if (m_pendingToBeAddedAircraft.
isEmpty()) {
return; }
1246 this->detectTimeoutAdding();
1249 if (!this->canAddAircraft()) {
return; }
1254 CLogMessage(
this).
info(u
"Adding next pending aircraft '%1', pending %2, in progress %3")
1256 << m_addingInProgressAircraft.size();
1260 void CSimulatorXPlane::triggerAddNextPendingAircraft()
1262 QPointer<CSimulatorXPlane> myself(
this);
1265 this->addNextPendingAircraft();
1269 int CSimulatorXPlane::detectTimeoutAdding()
1271 if (m_addingInProgressAircraft.isEmpty()) {
return 0; }
1272 const qint64 timeout = QDateTime::currentMSecsSinceEpoch() + TimeoutAdding;
1274 const QList<CCallsign> addingCallsigns = m_addingInProgressAircraft.keys();
1275 for (
const CCallsign &cs : addingCallsigns)
1277 if (m_addingInProgressAircraft.value(cs) < timeout) {
continue; }
1281 for (
const CCallsign &cs : std::as_const(timeoutCallsigns))
1283 m_addingInProgressAircraft.remove(cs);
1287 return timeoutCallsigns.
size();
1290 void CSimulatorXPlane::triggerRemoveAircraft(
const CCallsign &callsign, qint64 deferMs)
1292 QPointer<CSimulatorXPlane> myself(
this);
1294 if (!myself) {
return; }
1299 QPair<qint64, qint64> CSimulatorXPlane::minMaxTimestampsAddInProgress()
const
1301 static const QPair<qint64, qint64> empty(-1, -1);
1302 if (m_addingInProgressAircraft.isEmpty()) {
return empty; }
1303 const QList<qint64> ts = m_addingInProgressAircraft.values();
1304 const auto mm = std::minmax_element(ts.constBegin(), ts.constEnd());
1305 return QPair<qint64, qint64>(*mm.first, *mm.second);
1308 bool CSimulatorXPlane::canAddAircraft()
const
1310 if (m_addingInProgressAircraft.isEmpty()) {
return true; }
1313 const qint64 now = QDateTime::currentMSecsSinceEpoch();
1314 const QPair<qint64, qint64> tsMM = this->minMaxTimestampsAddInProgress();
1315 const qint64 deltaLatest = now - tsMM.second;
1316 const bool canAdd = (deltaLatest > TimeoutAdding);
1325 return new CSimulatorXPlane(info, ownAircraftProvider, remoteAircraftProvider, clientProvider,
this);
1330 constexpr
int QueryInterval = 5 * 1000;
1331 m_timer.setInterval(QueryInterval);
1332 m_timer.setObjectName(this->objectName().append(
":m_timer"));
1333 connect(&m_timer, &QTimer::timeout,
this, &CSimulatorXPlaneListener::checkConnection);
1342 if (!m_timer.isActive()) {
return; }
1346 QPointer<CSimulatorXPlaneListener> myself(
this);
1348 if (!myself) {
return; }
1353 void CSimulatorXPlaneListener::checkConnection()
1356 Q_ASSERT_X(!CThreadUtils::thisIsMainThread(), Q_FUNC_INFO,
"Expect to run in background");
1361 m_dBusServerAddress = m_xSwiftBusServerSettings.
getThreadLocal().getDBusServerAddressQt();
1362 if (CDBusServer::isSessionOrSystemAddress(m_dBusServerAddress))
1364 checkConnectionViaSessionBus();
1367 else if (CDBusServer::isQtDBusAddress(m_dBusServerAddress))
1369 checkConnectionViaPeer(m_dBusServerAddress);
1373 CLogMessage(
this).
debug(u
"Checked sim. 'XPLANE' via '%1' connection in %2ms") << via << t.elapsed();
1376 void CSimulatorXPlaneListener::checkConnectionViaSessionBus()
1378 m_DBusConnection = QDBusConnection::sessionBus();
1379 if (!m_DBusConnection.isConnected())
1381 m_DBusConnection.disconnectFromBus(m_DBusConnection.name());
1384 checkConnectionCommon();
1385 m_DBusConnection.disconnectFromBus(m_DBusConnection.name());
1388 void CSimulatorXPlaneListener::checkConnectionViaPeer(
const QString &address)
1390 m_DBusConnection = QDBusConnection::connectToPeer(address,
"xswiftbus");
1391 if (!m_DBusConnection.isConnected())
1394 m_DBusConnection.disconnectFromPeer(m_DBusConnection.name());
1397 checkConnectionCommon();
1398 m_DBusConnection.disconnectFromPeer(m_DBusConnection.name());
1401 void CSimulatorXPlaneListener::checkConnectionCommon()
1403 CXSwiftBusServiceProxy service(m_DBusConnection);
1404 CXSwiftBusTrafficProxy traffic(m_DBusConnection);
1406 const bool result = service.isValid() && traffic.isValid();
1407 if (!result) {
return; }
1409 const QString swiftVersion = CBuildConfig::getVersionString();
1410 const QString xswiftbusVersion = service.getVersionNumber();
1411 const QString xswiftbusCommitHash = service.getCommitHash();
1412 if (xswiftbusVersion.isEmpty())
1414 CLogMessage(
this).
warning(u
"Could not determine which version of xswiftbus is running. Mismatched versions "
1415 u
"might cause instability.");
1417 else if (commitHash() != xswiftbusCommitHash)
1419 CLogMessage(
this).
error(u
"You are using an incorrect version of xswiftbus. The version of xswiftbus (%1) "
1420 u
"should match the version of swift (%2). Consider upgrading!")
1421 << xswiftbusVersion << swiftVersion;
1424 if (!traffic.initialize())
1427 u
"Connection to xswiftbus successful, but could not initialize xswiftbus. Check X-Plane Log.txt.");
1431 const MultiplayerAcquireInfo info = traffic.acquireMultiplayerPlanes();
1432 if (!info.hasAcquired)
1434 const QString owner =
1435 info.owner.trimmed().
isEmpty() ? QStringLiteral(
"unknown plugin") : info.owner.trimmed();
1437 u
"Connection to xswiftbus successful, but could not acquire multiplayer planes. '%1' has acquired them "
1438 u
"already. Disable '%2' or remove it if not required and reload xswiftbus.")
1439 << owner << owner.toLower();
1446 void CSimulatorXPlaneListener::serviceRegistered(
const QString &serviceName)
1449 m_DBusConnection.disconnectFromBus(m_DBusConnection.name());
1452 void CSimulatorXPlaneListener::onXSwiftBusServerSettingChanged()
SWIFT_CORE_EXPORT swift::core::CApplication * sApp
Single instance of application object.
bool isShuttingDown() const
Is application shutting down?
Interface to a simulator.
double m_simTimeRatio
ratio of simulation time to real time, due to low FPS (X-Plane)
bool addLoopbackSituation(const swift::misc::aviation::CAircraftSituation &situation)
Add a loopback situation if logging is enabled.
bool isEqualLastSent(const swift::misc::aviation::CAircraftSituation &compare) const
Equal to last sent situation.
bool updateOwnSituationAndGroundElevation(const swift::misc::aviation::CAircraftSituation &situation)
Update own aircraft position and if suitable use it to update ground elevation.
bool isUpdateAllRemoteAircraft(qint64 currentTimestamp=-1) const
Do update all remote aircraft?
virtual bool isShuttingDown() const
Is overall (swift) application shutting down.
void requestedElevation(const swift::misc::aviation::CCallsign &callsign)
Requested elevation, call pending.
bool m_updateRemoteAircraftInProgress
currently updating remote aircraft
void rememberElevationAndSimulatorCG(const swift::misc::aviation::CCallsign &callsign, const swift::misc::simulation::CAircraftModel &model, bool likelyOnGroundElevation, const swift::misc::geo::CElevationPlane &elevation, const swift::misc::physical_quantities::CLength &simulatorCG)
Set elevation and CG in the providers and for auto publishing.
double m_trackMilesShort
difference between real and reported groundspeed, multiplied by time
double m_minutesLate
difference between real and reported groundspeed, integrated over time
bool isAircraftInRangeOrTestMode(const swift::misc::aviation::CCallsign &callsign) const
Test version aware version of isAircraftInRange.
void finishUpdateRemoteAircraftAndSetStatistics(qint64 startTime, bool limited=false)
Update stats and flags.
void insufficientFrameRateDetected(bool fatal)
Frame rate has fallen too far below the threshold to maintain consistent sim rate.
void reverseLookupAndUpdateOwnAircraftModel(const swift::misc::simulation::CAircraftModel &model)
Set own model.
swift::misc::aviation::CAircraftSituationList getLastSentCanLikelySkipNearGroundInterpolation() const
Last sent situations.
bool isTestMode() const
Test mode? (driver can skip code parts etc., driver dependent)
swift::misc::simulation::CAircraftModelList getModelSet() const
Get the model set.
void emitSimulatorCombinedStatus(SimulatorStatus oldStatus=Unspecified)
Emit the combined status.
void logAddingAircraftModel(const swift::misc::simulation::CSimulatedAircraft &aircraft) const
Unified qeeing aircraft message.
swift::misc::simulation::CInterpolationAndRenderingSetupPerCallsign getInterpolationSetupConsolidated(const swift::misc::aviation::CCallsign &callsign, bool forceFullUpdate) const
Consolidate setup with other data like from swift::misc::simulation::IRemoteAircraftProvider.
swift::misc::simulation::settings::CSpecializedSimulatorSettings getSimulatorSettings() const
Settings for current simulator.
swift::misc::simulation::CInterpolationLogger m_interpolationLogger
log.interpolation
void aircraftRenderingChanged(const swift::misc::simulation::CSimulatedAircraft &aircraft)
Aircraft rendering changed.
virtual bool isShuttingDownOrDisconnected() const
Shutting down or disconnected?
virtual void initSimulatorInternals()
Init the internals info from the simulator.
QString getInvalidSituationLogMessage(const swift::misc::aviation::CCallsign &callsign, const swift::misc::simulation::CInterpolationStatus &status, const QString &details={}) const
Info about invalid situation.
void rememberLastSent(const swift::misc::aviation::CAircraftSituation &sent)
Remember as last sent.
Interface to a simulator listener.
const swift::misc::simulation::CSimulatorPluginInfo & getPluginInfo() const
Corresponding info.
void simulatorStarted(const swift::misc::simulation::CSimulatorPluginInfo &info)
Emitted when the listener discovers the simulator running.
virtual bool isShuttingDown() const
Overall (swift) application shutting down.
void start()
Start listening for the simulator to start.
void stop()
Stops listening.
const T & getThreadLocal() const
Read the current value.
T get() const
Get a copy of the current value.
size_type size() const
Returns number of elements in the collection.
void remove(const T &object)
Efficient remove using the find and erase of the implementation container. Typically O(log n).
iterator insert(const_iterator hint, const T &value)
For compatibility with std::inserter.
bool isEmpty() const
Synonym for empty.
iterator push_back(const T &value)
Synonym for insert.
void clear()
Removes all elements in the collection.
const CIdentifier & identifier() const
Get identifier.
Value object encapsulating information identifying a component of a modular distributed swift process...
Class for emitting a log message.
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
bool isEmpty() const
Message empty.
Derived & validationError(const char16_t(&format)[N])
Set the severity to error, providing a format string, and adding the validation category.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & debug()
Set the severity to debug.
Derived & info(const char16_t(&format)[N])
Set the severity to info, providing a format string.
bool contains(const T &object) const
Return true if there is an element equal to given object. Uses the most efficient implementation avai...
size_type size() const
Returns number of elements in the sequence.
void replaceOrAdd(const T &original, const T &replacement)
Replace elements matching the given element. If there is no match, push the new element on the end.
void push_back(const T &value)
Appends an element at the end of the sequence.
reference front()
Access the first element.
void clear()
Removes all elements in the sequence.
bool isEmpty() const
Synonym for empty.
void pop_front()
Removes an element at the front of the sequence.
Build a QSet more efficiently when calling insert() in a for loop.
void insert(const T &value)
Add an element to the set. Runs in amortized constant time.
Streamable status message, e.g.
QString getMessage() const
Message.
Status messages, e.g. from Core -> GUI.
Value object encapsulating information about aircraft's engines.
Value object encapsulating a list of aircraft engines.
Value object for ICAO classification.
const QString & getDesignator() const
Get ICAO designator, e.g. "B737".
Value object encapsulating information about aircraft's lights.
Value object encapsulating information of aircraft's parts.
bool isNull() const
NULL parts object?
Value object encapsulating information of an aircraft's situation.
void setPressureAltitude(const CAltitude &altitude)
Set pressure altitude.
void setGroundSpeed(const physical_quantities::CSpeed &groundspeed)
Set ground speed.
bool setGroundElevation(const aviation::CAltitude &altitude, GndElevationInfo info, bool transferred=false)
Elevation of the ground directly beneath at the given situation.
void setBank(const physical_quantities::CAngle &bank)
Set bank (angle)
void setHeading(const CHeading &heading)
Set heading.
void setAltitude(const CAltitude &altitude)
Set altitude.
void setPitch(const physical_quantities::CAngle &pitch)
Set pitch.
virtual bool isNull() const
Null situation.
void setVelocity(const CAircraftVelocity &velocity)
Set 6DOF velocity.
void setPosition(const geo::CCoordinateGeodetic &position)
Set position.
const QString & getDesignator() const
Get airline, e.g. "DLH".
Altitude as used in aviation, can be AGL or MSL altitude.
Value object encapsulating information of a callsign.
const QString & asString() const
Get callsign (normalized)
bool isEmpty() const
Is empty?
Value object for a set of callsigns.
QStringList getCallsignStrings(bool sorted=false) const
The callsign strings.
const QString & getCombinedCode() const
Combined code.
swift::misc::physical_quantities::CFrequency getFrequencyStandby() const
Standby frequency.
swift::misc::physical_quantities::CFrequency getFrequencyActive() const
Active frequency.
TransponderMode
Transponder codes.
OBJ findFirstByCallsign(const CCallsign &callsign, const OBJ &ifNotFound={}) const
Find the first aircraft by callsign, if none return given one.
int removeByCallsign(const CCallsign &callsign)
Remove all objects with callsign.
swift::misc::aviation::CCallsignSet getCallsigns() const
All callsigns.
bool containsCallsign(const CCallsign &callsign) const
Contains callsign?
virtual CLatitude latitude() const
Latitude.
virtual const aviation::CAltitude & geodeticHeight() const
Height, ellipsoidal or geodetic height (used in GPS)
void setGeodeticHeight(const aviation::CAltitude &height)
Set height (ellipsoidal or geodetic height)
virtual CLongitude longitude() const
Longitude.
Plane of same elevation, can be a single point or larger area (e.g. airport)
const aviation::CAltitude & getAltitude() const
Altitude (synonym for geodetic height)
double getAltitudeValue(const physical_quantities::CLengthUnit &unit) const
Altitude (synonym for geodetic height)
Geodetic coordinate, a position in 3D space relative to the reference geoid.
bool hasMSLGeodeticHeight() const
Geodetic height not null and aviation::CAltitude::MeanSeaLevel.
virtual bool isNull() const
Is null, means vector x, y, z == 0.
QString toQString(bool i18n=false) const
Cast as QString.
Value object encapsulating information of a text message.
bool isPrivateMessage() const
Is private message?
const QString & getMessage() const
Get message.
bool isServerMessage() const
Initial message of server?
const aviation::CCallsign & getSenderCallsign() const
Get callsign (from)
bool isSupervisorMessage() const
Supervisor message?
Direct in memory access to client (network client) data.
Physical unit length (length)
Specialized class for distance units (meter, foot, nautical miles).
int valueInteger(MU unit) const
As integer value.
bool isNull() const
Is quantity null?
double value(MU unit) const
Value in given unit.
QString valueRoundedAsString(MU unit, int digits=-1) const
Rounded value in given unit.
PQ abs() const
Absolute value (always >=0)
Aircraft model (used by another pilot, my models on disk)
const aviation::CCallsign & getCallsign() const
Corresponding callsign if applicable.
const aviation::CLivery & getLivery() const
Get livery.
const QString & getModelString() const
Model key, either queried or loaded from simulator model.
void setCallsign(const aviation::CCallsign &callsign)
Corresponding callsign if applicable.
const CDistributor & getDistributor() const
Get distributor.
Value object encapsulating a list of aircraft models.
bool matchesKeyOrAlias(const QString &keyOrAlias) const
Matches key or alias.
InterpolatorMode getInterpolatorMode() const
Interpolator mode.
Value object for interpolator and rendering per callsign.
const CInterpolationStatus & getInterpolationStatus() const
Get status.
const CPartsStatus & getPartsStatus() const
Get status.
bool hasValidSituation() const
Is the corresponding position valid?
bool updateOwnParts(const aviation::CAircraftParts &parts)
Update own parts.
swift::misc::physical_quantities::CLength getDistanceToOwnAircraft(const swift::misc::geo::ICoordinateGeodetic &position) const
Distance to own aircraft.
bool updateCockpit(const swift::misc::simulation::CSimulatedAircraft &aircraft, const swift::misc::CIdentifier &originator)
swift::misc::geo::CCoordinateGeodetic getOwnAircraftPosition() const
Own aircraft's position.
CSimulatedAircraft getOwnAircraft() const
Own aircraft.
bool isSupportingParts() const
Supporting parts.
aviation::CCallsignSet getAircraftInRangeCallsigns() const
Unique callsigns for aircraft in range.
bool isAircraftInRange(const aviation::CCallsign &callsign) const
Is aircraft in range?
CSimulatedAircraftList getAircraftInRange() const
All remote aircraft.
int getAircraftInRangeCount() const
Count remote aircraft.
CSimulatedAircraft getAircraftInRangeForCallsign(const aviation::CCallsign &callsign) const
Aircraft for callsign.
bool updateAircraftRendered(const aviation::CCallsign &callsign, bool rendered)
Set aircraft rendered.
Comprehensive information of an aircraft.
bool hasModelString() const
Has model string?
aviation::CTransponder::TransponderMode getTransponderMode() const
Get transponder mode.
const aviation::CAircraftSituation & getSituation() const
Get situation.
const aviation::CComSystem & getCom2System() const
Get COM2 system.
bool setRendered(bool rendered)
Rendered?
qint32 getTransponderCode() const
Get transponder code.
bool hasCallsign() const
Callsign not empty, no further checks.
const aviation::CCallsign & getCallsign() const
Get callsign.
const aviation::CAircraftIcaoCode & getAircraftIcaoCode() const
Get aircraft ICAO info.
bool hasChangedCockpitData(const aviation::CComSystem &com1, const aviation::CComSystem &com2, const aviation::CTransponder &transponder) const
Changed cockpit data?
const simulation::CAircraftModel & getModel() const
Get model (model used for mapping)
QString getCallsignAsString() const
Get callsign.
const aviation::CComSystem & getCom1System() const
Get COM1 system.
const aviation::CAirlineIcaoCode & getAirlineIcaoCode() const
Airline ICAO code if any.
const aviation::CAircraftParts & getParts() const
Get aircraft parts.
Q_REQUIRED_RESULT CSimulatedAircraftList findByRendered(bool rendered) const
Rendered / not rendered aircraft.
Describing a simulator plugin.
aviation::CCallsignSet getLogCallsigns() const
All callsigns marked to be logged.
Direct threadsafe in memory access to own aircraft.
Direct thread safe in memory access to remote aircraft.
void setSimulatorDetails(const QString &name, const QString &details, const QString &version)
Set version and simulator details from running simulator.
void removePendingElevationRequest(const aviation::CCallsign &cs)
Remove pending timestamp.
void setDefaultModel(const CAircraftModel &defaultModel)
Default model.
const QString & getSimulatorDirectoryOrDefault() const
Simulator directory or default path.
void parseXSwiftBusStringQt(const QString &json)
Load and parse config file.
QString toXSwiftBusJsonStringQt() const
As JSON string.
virtual void setCurrentUtcTime()
Sets both timestamps.
QString getDBusServerAddressQt() const
DBus server.
virtual swift::core::ISimulator * create(const swift::misc::simulation::CSimulatorPluginInfo &info, swift::misc::simulation::IOwnAircraftProvider *ownAircraftProvider, swift::misc::simulation::IRemoteAircraftProvider *remoteAircraftProvider, swift::misc::network::IClientProvider *clientProvider)
Create a new instance of a driver.
virtual int physicallyRemoveAllRemoteAircraft()
Remove all remote aircraft and their data via ISimulator::clearAllRemoteAircraftData.
virtual ~CSimulatorXPlane()
Dtor.
virtual bool connectTo()
Connect to simulator.
virtual bool followAircraft(const swift::misc::aviation::CCallsign &callsign)
Follow aircraft.
virtual bool isConnected() const
Are we connected to the simulator?
virtual bool requestElevation(const swift::misc::geo::ICoordinateGeodetic &reference, const swift::misc::aviation::CCallsign &callsign)
Request elevation, there is no guarantee the requested elevation will be available in the provider.
CSimulatorXPlane(const swift::misc::simulation::CSimulatorPluginInfo &info, swift::misc::simulation::IOwnAircraftProvider *ownAircraftProvider, swift::misc::simulation::IRemoteAircraftProvider *remoteAircraftProvider, swift::misc::network::IClientProvider *clientProvider, QObject *parent=nullptr)
Constructor.
virtual bool testSendSituationAndParts(const swift::misc::aviation::CCallsign &callsign, const swift::misc::aviation::CAircraftSituation &situation, const swift::misc::aviation::CAircraftParts &parts)
Send situation/parts for testing.
virtual void resetAircraftStatistics()
Reset the statistics.
virtual bool updateOwnSimulatorSelcal(const swift::misc::aviation::CSelcal &selcal, const swift::misc::CIdentifier &originator)
Update own aircraft cockpit (usually from context)
virtual void clearAllRemoteAircraftData()
Clear all aircraft related data, but do not physically remove the aircraft.
virtual bool isPhysicallyRenderedAircraft(const swift::misc::aviation::CCallsign &callsign) const
Is the aircraft rendered (displayed in simulator)? This shall only return true if the aircraft is rea...
virtual void unload()
Driver will be unloaded.
virtual bool updateOwnSimulatorCockpit(const swift::misc::simulation::CSimulatedAircraft &aircraft, const swift::misc::CIdentifier &originator)
Update own aircraft cockpit (usually from context)
virtual swift::misc::aviation::CCallsignSet physicallyRenderedAircraft() const
Physically rendered (displayed in simulator) This shall only return aircraft handled in the simulator...
virtual swift::misc::CStatusMessageList getInterpolationMessages(const swift::misc::aviation::CCallsign &callsign) const
Interpolation messages for callsign.
virtual void setFlightNetworkConnected(bool connected)
Flight network has been connected.
virtual bool physicallyAddRemoteAircraft(const swift::misc::simulation::CSimulatedAircraft &newRemoteAircraft)
Add new remote aircraft physically to the simulator.
virtual bool physicallyRemoveRemoteAircraft(const swift::misc::aviation::CCallsign &callsign)
Remove remote aircraft from simulator.
virtual QString getStatisticsSimulatorSpecific() const
Allows to print out simulator specific statistics.
virtual void callbackReceivedRequestedElevation(const swift::misc::geo::CElevationPlane &plane, const swift::misc::aviation::CCallsign &callsign, bool isWater)
A requested elevation has been received.
virtual void displayStatusMessage(const swift::misc::CStatusMessage &message) const
Display a status message in the simulator.
virtual bool disconnectFrom()
Disconnect from simulator.
virtual void displayTextMessage(const swift::misc::network::CTextMessage &message) const
Display a text message.
CSimulatorXPlaneListener(const swift::misc::simulation::CSimulatorPluginInfo &info)
Constructor.
virtual void checkImpl()
Plugin specific implementation to check.
virtual void startImpl()
Plugin specific implementation to start listener.
virtual void stopImpl()
Plugin specific implementation to stop listener.
Class representing a X-Plane multiplayer aircraft.
const swift::misc::simulation::CSimulatedAircraft & getAircraft() const
Simulated aircraft (as added)
Proxy object connected to a real XSwiftBus::CService object via DBus.
void getOwnAircraftModelDataAsync(swift::simplugin::xplane::XPlaneData *o_xplaneData)
Get own model data.
void getOwnAircraftCom2DataAsync(swift::simplugin::xplane::XPlaneData *o_xplaneData)
Get own aircraft COM2 data.
void setTransponderMode(int mode)
Set the current transponder mode (depends on the aircraft, 0 and 1 usually mean standby,...
QString getAircraftModelFilename() const
Get base filename of current aircraft model.
void updateAirportsInRange()
int getXPlaneVersionMajor() const
Get major version number.
void setCom2ActiveKhz(int freq)
Set the current COM2 active frequency in kHz.
void getAllWheelsOnGroundAsync(bool *o_allWheels)
Get whether all wheels are on the ground.
QString getAircraftLivery() const
Get current aircraft livery.
void setTransponderCode(int code)
Set the current transponder code in decimal.
void addTextMessage(const QString &text, double red, double green, double blue)
Add a text message to the on-screen display, with RGB components in the range [0,1].
void setCom1StandbyKhz(int freq)
Set the current COM1 standby frequency in kHz.
void getOwnAircraftLightsAsync(swift::simplugin::xplane::XPlaneData *o_xplaneData)
Get own lights data.
void getOwnAircraftVelocityDataAsync(swift::simplugin::xplane::XPlaneData *o_xplaneData)
Get own aircraft velocity data.
void setCom1ActiveKhz(int freq)
Set the current COM1 active frequency in kHz.
void getOwnAircraftXpdrAsync(swift::simplugin::xplane::XPlaneData *o_xplaneData)
Get own XPDR data.
QString getAircraftDescription() const
Get the description of the current aircraft model.
QString getAircraftName() const
Get name of current aircraft model.
QString getSettingsJson() const
Get settings.
bool isValid() const
Does the remote object exist?
void setSettingsJson(const QString &json)
Set settings.
QString getAircraftModelString() const
Get canonical swift model string of current aircraft model.
QString getAircraftIcaoCode() const
Get the ICAO code of the current aircraft model.
QString getAircraftModelPath() const
Get full path to current aircraft model.
void getPressureAltitudeFtAsync(double *o_altitude)
Get aircraft pressure altitude in feet in standard atmosphere in X-Plane 12. NaN in earlier versions ...
void getFrameStats(double *o_averageFps, double *o_simTimeRatio, double *o_trackMilesShort, double *o_minutesLate) const
Frames-per-second, averaged over the last 500 frames, or since this function was last called,...
void getOwnAircraftPartsAsync(swift::simplugin::xplane::XPlaneData *o_xplaneData)
Get own parts such as gear, flaps.
void getHeightAglMAsync(double *o_height)
Get aircraft height in meters.
void aircraftModelChanged(const QString &path, const QString &filename, const QString &livery, const QString &icao, const QString &modelString, const QString &name, const QString &description)
Own aircraft model changed.
void getOwnAircraftSituationDataAsync(swift::simplugin::xplane::XPlaneData *o_xplaneData)
Get own aircraft situation data.
void setCom2StandbyKhz(int freq)
Set the current COM2 standby frequency in kHz.
void resetFrameTotals()
Reset the monitoring of total miles and minutes lost due to low frame rate.
void cancelAllPendingAsyncCalls()
Cancel all current async slot calls.
int getXPlaneVersionMinor() const
Get minor version number.
void getOwnAircraftCom1DataAsync(swift::simplugin::xplane::XPlaneData *o_xplaneData)
Get own aircraft COM1 data.
Proxy object connected to a real XSwiftBus::CTraffic object via DBus.
void cleanup()
Reverse the actions of initialize().
void addPlane(const QString &callsign, const QString &modelName, const QString &aircraftIcao, const QString &airlineIcao, const QString &livery)
Introduce a new traffic aircraft.
void remoteAircraftAddingFailed(const QString &callsign)
Remote aircraft adding failed.
void setPlanesPositions(const swift::simplugin::xplane::PlanesPositions &planesPositions)
Set the position of multiple traffic aircrafts.
void removeAllPlanes()
Remove all traffic aircraft.
void setFollowedAircraft(const QString &callsign)
Sets the aircraft with callsign to be followed in plane view.
void simFrame()
Simulator frame.
void setPlanesSurfaces(const swift::simplugin::xplane::PlanesSurfaces &planesSurfaces)
Set the flight control surfaces and lights of multiple traffic aircrafts.
QString loadPlanesPackage(const QString &path)
Load a collection of planes from the given directory and return error message if unsuccessful.
void setPlanesTransponders(const swift::simplugin::xplane::PlanesTransponders &planesTransponders)
Set the transponder of multiple traffic aircraft.
void removePlane(const QString &callsign)
Remove a traffic aircraft.
bool isValid() const
Does the remote object exist?
void remoteAircraftAdded(const QString &callsign)
Remote aircraft successfully added.
void getRemoteAircraftData(const QStringList &callsigns, const RemoteAircraftDataCallback &setter) const
Get remote aircrafts data (lat, lon, elevation and CG)
Backend services of the swift project, like dealing with the network or the simulators.
Free functions in swift::misc.
auto singleShot(int msec, QObject *target, F &&task)
Starts a single-shot timer which will call a task in the thread of the given object when it times out...
void push_back(const swift::misc::aviation::CAircraftSituation &situation)
Push back the latest situation.
void push_back(const swift::misc::aviation::CCallsign &callsign, const swift::misc::aviation::CAircraftParts &parts)
Push back the latest parts.
double rollDeg
Roll [deg].
int com2StandbyKhz
COM2 standby [kHz].
double headingRadPerSec
Heading angular velocity [rad/s].
double groundspeedMs
Ground speed [m/s].
bool isCom1Receiving
COM1 receiving.
double com2Volume
COM2 volume 0..1.
double com1Volume
COM1 volume 0..1.
double longitudeDeg
Latitude [deg].
double localXVelocityMs
Local x velocity [m/s].
int xpdrMode
Transponder mode (off=0,stdby=1,on=2,test=3)
int com1ActiveKhz
COM1 active [kHz].
bool beaconLightsOn
Beacon lights on?
bool isCom1Transmitting
COM1 transmittings.
double flapsDeployRatio
Flaps deployment ratio [%].
double localZVelocityMs
Local z velocity [m/s].
bool taxiLightsOn
Taxi lights on?
bool isCom2Transmitting
COM2 transmittings.
bool strobeLightsOn
Strobe lights on?
double rollRadPerSec
Roll angular velocity [rad/s].
int xpdrCode
Transpondder code.
double gearDeployRatio
Gear deployment ratio [%].
double trueHeadingDeg
True heading [deg].
bool xpdrIdent
Is transponder in ident?
int com2ActiveKhz
COM2 active [kHz].
double altitudeM
Altitude [m].
bool onGroundAll
All wheels on ground?
double latitudeDeg
Longitude [deg].
bool isCom2Receiving
COM2 receiving.
double heightAglM
Height AGL [m].
bool navLightsOn
NAV lights on?
double pitchRadPerSec
Pitch angular velocity [rad/s].
QList< double > enginesN1Percentage
N1 per engine [%].
double pitchDeg
Pitch [deg].
double speedBrakeRatio
Speed break ratio [%].
double seaLevelPressureInHg
Sea level pressure [inhg].
int com1StandbyKhz
COM1 standby [kHz].
double pressureAltitudeFt
Pressure altitude [ft, XP12].
bool landingLightsOn
Landing lights on?
double localYVelocityMs
Local y velocity [m/s].
#define SWIFT_VERIFY_X(COND, WHERE, WHAT)
A weaker kind of assert.