swift
xswiftbustrafficproxy.cpp
1 // SPDX-FileCopyrightText: Copyright (C) 2013 swift Project Community / Contributors
2 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-swift-pilot-client-1
3 
5 
6 #include <cmath>
7 
8 #include <QDBusConnection>
9 #include <QLatin1String>
10 
11 #include "misc/logmessage.h"
12 
13 #define XSWIFTBUS_SERVICENAME "org.swift-project.xswiftbus"
14 
15 using namespace swift::misc;
16 using namespace swift::misc::aviation;
17 using namespace swift::misc::geo;
18 using namespace swift::misc::physical_quantities;
19 
20 namespace swift::simplugin::xplane
21 {
22  const QStringList &CXSwiftBusTrafficProxy::getLogCategories()
23  {
24  static const QStringList cats { CLogCategories::driver(), CLogCategories::dbus() };
25  return cats;
26  }
27 
28  CXSwiftBusTrafficProxy::CXSwiftBusTrafficProxy(QDBusConnection &connection, QObject *parent, bool dummy)
29  : QObject(parent)
30  {
31  m_dbusInterface = new swift::misc::CGenericDBusInterface(XSWIFTBUS_SERVICENAME, ObjectPath(), InterfaceName(),
32  connection, this);
33  if (!dummy)
34  {
35  bool s;
36  s = connection.connect(QString(), "/xswiftbus/traffic", "org.swift_project.xswiftbus.traffic", "simFrame",
37  this, SIGNAL(simFrame()));
38  Q_ASSERT(s);
39 
40  s = connection.connect(QString(), "/xswiftbus/traffic", "org.swift_project.xswiftbus.traffic",
41  "remoteAircraftAdded", this, SIGNAL(remoteAircraftAdded(QString)));
42  Q_ASSERT(s);
43 
44  s = connection.connect(QString(), "/xswiftbus/traffic", "org.swift_project.xswiftbus.traffic",
45  "remoteAircraftAddingFailed", this, SIGNAL(remoteAircraftAddingFailed(QString)));
46  Q_ASSERT(s);
47  }
48  }
49 
51  {
52  QDBusPendingReply<bool, QString> reply = m_dbusInterface->asyncCall(QLatin1String("acquireMultiplayerPlanes"));
53  reply.waitForFinished();
54  if (reply.isError())
55  {
56  CLogMessage(this).debug(u"CXSwiftBusTrafficProxy::acquireMultiplayerPlanes returned: %1")
57  << reply.error().message();
58  }
60  info.hasAcquired = reply.argumentAt<0>();
61  info.owner = reply.argumentAt<1>();
62  return info;
63  }
64 
66  {
67  return m_dbusInterface->callDBusRet<bool>(QLatin1String("initialize"));
68  }
69 
70  void CXSwiftBusTrafficProxy::cleanup() { m_dbusInterface->callDBus(QLatin1String("cleanup")); }
71 
72  QString CXSwiftBusTrafficProxy::loadPlanesPackage(const QString &path)
73  {
74  return m_dbusInterface->callDBusRet<QString>(QLatin1String("loadPlanesPackage"), path);
75  }
76 
77  void CXSwiftBusTrafficProxy::setDefaultIcao(const QString &defaultIcao)
78  {
79  m_dbusInterface->callDBus(QLatin1String("setDefaultIcao"), defaultIcao);
80  }
81 
83  {
84  m_dbusInterface->callDBus(QLatin1String("setMaxPlanes"), planes);
85  }
86 
87  void CXSwiftBusTrafficProxy::setMaxDrawDistance(double nauticalMiles)
88  {
89  m_dbusInterface->callDBus(QLatin1String("setMaxDrawDistance"), nauticalMiles);
90  }
91 
92  void CXSwiftBusTrafficProxy::addPlane(const QString &callsign, const QString &modelName,
93  const QString &aircraftIcao, const QString &airlineIcao,
94  const QString &livery)
95  {
96  m_dbusInterface->callDBus(QLatin1String("addPlane"), callsign, modelName, aircraftIcao, airlineIcao, livery);
97  }
98 
99  void CXSwiftBusTrafficProxy::removePlane(const QString &callsign)
100  {
101  m_dbusInterface->callDBus(QLatin1String("removePlane"), callsign);
102  }
103 
104  void CXSwiftBusTrafficProxy::removeAllPlanes() { m_dbusInterface->callDBus(QLatin1String("removeAllPlanes")); }
105 
107  {
108  m_dbusInterface->callDBus(QLatin1String("setPlanesPositions"), planesPositions.callsigns,
109  planesPositions.latitudesDeg, planesPositions.longitudesDeg,
110  planesPositions.altitudesFt, planesPositions.pitchesDeg, planesPositions.rollsDeg,
111  planesPositions.headingsDeg, planesPositions.onGrounds);
112  }
113 
115  {
116  m_dbusInterface->callDBus(QLatin1String("setPlanesSurfaces"), planesSurfaces.callsigns, planesSurfaces.gears,
117  planesSurfaces.flaps, planesSurfaces.spoilers, planesSurfaces.speedBrakes,
118  planesSurfaces.slats, planesSurfaces.wingSweeps, planesSurfaces.thrusts,
119  planesSurfaces.elevators, planesSurfaces.rudders, planesSurfaces.ailerons,
120  planesSurfaces.landLights, planesSurfaces.taxiLights, planesSurfaces.beaconLights,
121  planesSurfaces.strobeLights, planesSurfaces.navLights, planesSurfaces.lightPatterns);
122  }
123 
125  {
126  m_dbusInterface->callDBus(QLatin1String("setPlanesTransponders"), planesTransponders.callsigns,
127  planesTransponders.codes, planesTransponders.modeCs, planesTransponders.idents);
128  }
129 
130  void CXSwiftBusTrafficProxy::setInterpolatorMode(const QString &callsign, bool spline)
131  {
132  m_dbusInterface->callDBus(QLatin1String("setInterpolatorMode"), callsign, spline);
133  }
134 
135  void CXSwiftBusTrafficProxy::getRemoteAircraftData(const QStringList &callsigns,
136  const RemoteAircraftDataCallback &setter) const
137  {
138  std::function<void(QDBusPendingCallWatcher *)> callback = [=](QDBusPendingCallWatcher *watcher) {
139  QDBusPendingReply<QStringList, QList<double>, QList<double>, QList<double>, QList<bool>, QList<double>>
140  reply = *watcher;
141  if (!reply.isError())
142  {
143  const QStringList callsigns = reply.argumentAt<0>();
144  const QList<double> latitudesDeg = reply.argumentAt<1>();
145  const QList<double> longitudesDeg = reply.argumentAt<2>();
146  const QList<double> elevationsM = reply.argumentAt<3>();
147  const QList<bool> waterFlags = reply.argumentAt<4>();
148  const QList<double> verticalOffsets = reply.argumentAt<5>();
149 
150  setter(callsigns, latitudesDeg, longitudesDeg, elevationsM, waterFlags, verticalOffsets);
151  }
152  else
153  {
154  const QString errorMsg = reply.error().message();
155  CLogMessage(this).warning(u"xswiftbus DBus error getRemoteAircraftData: %1") << errorMsg;
156  }
157  watcher->deleteLater();
158  };
159  m_dbusInterface->callDBusAsync(QLatin1String("getRemoteAircraftData"), callback, callsigns);
160  }
161 
162  void CXSwiftBusTrafficProxy::getElevationAtPosition(const CCallsign &callsign, double latitudeDeg,
163  double longitudeDeg, double altitudeMeters,
164  const ElevationCallback &setter) const
165  {
166  std::function<void(QDBusPendingCallWatcher *)> callback = [=](QDBusPendingCallWatcher *watcher) {
167  QDBusPendingReply<QString, double, double, double, bool> reply = *watcher;
168  if (!reply.isError())
169  {
170  const CCallsign cs(reply.argumentAt<0>());
171  const double elevationMeters = reply.argumentAt<1>();
172  const double latitudeDegrees = reply.argumentAt<2>();
173  const double longitudeDegrees = reply.argumentAt<3>();
174  const CAltitude elevationAlt = std::isnan(elevationMeters) ?
175  CAltitude::null() :
176  CAltitude(elevationMeters, CLengthUnit::m(), CLengthUnit::ft());
177  const CElevationPlane elevation(CLatitude(latitudeDegrees, CAngleUnit::deg()),
178  CLongitude(longitudeDegrees, CAngleUnit::deg()), elevationAlt,
179  CElevationPlane::singlePointRadius());
180  const bool isWater = reply.argumentAt<4>();
181  setter(elevation, cs, isWater);
182  // CLogMessage(this).debug(u"XPlane elv. response: '%1' %2 %3 %4 %5") << cs.asString() << latitudeDeg <<
183  // longitudeDeg << elevationMeters << isWater;
184  }
185  watcher->deleteLater();
186  };
187 
188  m_dbusInterface->callDBusAsync(QLatin1String("getElevationAtPosition"), callback, callsign.asString(),
189  latitudeDeg, longitudeDeg, altitudeMeters);
190  // CLogMessage(this).debug(u"XPlane elv. request: '%1' %2 %3 %4") << callsign.asString() << latitudeDeg <<
191  // longitudeDeg << altitudeMeters;
192  }
193 
194  void CXSwiftBusTrafficProxy::setFollowedAircraft(const QString &callsign)
195  {
196  m_dbusInterface->callDBus(QLatin1String("setFollowedAircraft"), callsign);
197  }
198 } // namespace swift::simplugin::xplane
Used for hand written interface based on virtual methods.
void callDBus(QLatin1String method, Args &&...args)
Call DBus, no return value.
Ret callDBusRet(QLatin1String method, Args &&...args)
Call DBus with synchronous return value.
QDBusPendingCallWatcher * callDBusAsync(QLatin1String method, Func callback, Args &&...args)
Call DBus with asynchronous return value Callback can be any callable object taking a single argument...
static const QString & dbus()
DBus related.
Definition: logcategories.h:59
static const QString & driver()
Driver.
Class for emitting a log message.
Definition: logmessage.h:27
Derived & warning(const char16_t(&format)[N])
Set the severity to warning, providing a format string.
Derived & error(const char16_t(&format)[N])
Set the severity to error, providing a format string.
Derived & debug()
Set the severity to debug.
QString message() const
Private.
Altitude as used in aviation, can be AGL or MSL altitude.
Definition: altitude.h:52
Value object encapsulating information of a callsign.
Definition: callsign.h:30
const QString & asString() const
Get callsign (normalized)
Definition: callsign.h:96
Plane of same elevation, can be a single point or larger area (e.g. airport)
void cleanup()
Reverse the actions of initialize().
static const QString & ObjectPath()
Service path.
void setMaxPlanes(int planes)
Set the maximum number of aircraft.
void addPlane(const QString &callsign, const QString &modelName, const QString &aircraftIcao, const QString &airlineIcao, const QString &livery)
Introduce a new traffic aircraft.
MultiplayerAcquireInfo acquireMultiplayerPlanes()
Returns whether multiplayer planes have been acquired. If not, owner will be set to the plugin that a...
void remoteAircraftAddingFailed(const QString &callsign)
Remote aircraft adding failed.
bool initialize()
Initialize the multiplayer planes rendering and return true if successful.
void setPlanesPositions(const swift::simplugin::xplane::PlanesPositions &planesPositions)
Set the position of multiple traffic aircrafts.
void setFollowedAircraft(const QString &callsign)
Sets the aircraft with callsign to be followed in plane view.
void setMaxDrawDistance(double nauticalMiles)
Set the maximum distance at which to draw aircraft (nautical miles).
void setPlanesSurfaces(const swift::simplugin::xplane::PlanesSurfaces &planesSurfaces)
Set the flight control surfaces and lights of multiple traffic aircrafts.
void getElevationAtPosition(const swift::misc::aviation::CCallsign &callsign, double latitudeDeg, double longitudeDeg, double altitudeMeters, const ElevationCallback &setter) const
Get the ground elevation at an arbitrary position.
void setInterpolatorMode(const QString &callsign, bool spline)
QString loadPlanesPackage(const QString &path)
Load a collection of planes from the given directory and return error message if unsuccessful.
static const QString & InterfaceName()
Service name.
void setDefaultIcao(const QString &defaultIcao)
Set the ICAO code to use for aircraft without a model match.
void setPlanesTransponders(const swift::simplugin::xplane::PlanesTransponders &planesTransponders)
Set the transponder of multiple traffic aircraft.
std::function< void(const swift::misc::geo::CElevationPlane &, const swift::misc::aviation::CCallsign &, bool)> ElevationCallback
Elevation callback.
void removePlane(const QString &callsign)
Remove a traffic aircraft.
std::function< void(const QStringList &, const QDoubleList &, const QDoubleList &, const QDoubleList &, const QBoolList &, const QDoubleList &)> RemoteAircraftDataCallback
Remote aircrafts data callback.
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)
Free functions in swift::misc.
bool hasAcquired
Has xswiftbus acquired multiplayer planes?
QString owner
Name of the plugin having multiplayer planes acquired.
QList< double > pitchesDeg
List of pitches.
QList< double > altitudesFt
List of altitudes.
QList< double > headingsDeg
List of headings.
QList< bool > onGrounds
List of onGrounds.
QList< double > latitudesDeg
List of latitudes.
QList< double > longitudesDeg
List of longitudes.
QList< bool > beaconLights
List of beacon lights.
QList< bool > landLights
List of landing lights.
QList< double > speedBrakes
List of speed brakes.
QList< bool > strobeLights
List of strobe lights.
QList< double > rudders
List of rudders.
QList< double > ailerons
List of ailerons.
QList< bool > navLights
List of nav lights.
QList< double > thrusts
List of thrusts.
QList< double > elevators
List of elevators.
QList< bool > taxiLights
List of taxi lights.
QList< int > lightPatterns
List of light patterns.
QList< double > spoilers
List of spoilers.
QList< double > wingSweeps
List of wing sweeps.
QList< bool > idents
List of active idents.
QList< bool > modeCs
List of active mode C's.
QList< int > codes
List of transponder codes.