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 
73  {
74  return m_dbusInterface->callDBusRet<QString>(QLatin1String("loadPlanesPackage"), path);
75  }
76 
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 
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 
136  const RemoteAircraftDataCallback &setter) const
137  {
138  std::function<void(QDBusPendingCallWatcher *)> callback = [=](QDBusPendingCallWatcher *watcher) {
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) {
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 
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 & debug()
Set the severity to debug.
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.
QDBusPendingCall asyncCall(const QString &method, Args &&... args)
bool connect(const QString &service, const QString &path, const QString &interface, const QString &name, QObject *receiver, const char *slot)
QString message() const const
QVariant argumentAt(int index) const const
QDBusError error() const const
bool isError() const const
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.