From 2fd4d286d6ed8b8258c61c23d0186a80ccf993e1 Mon Sep 17 00:00:00 2001 From: Roland Winklmeier Date: Sat, 5 May 2018 13:45:24 +0200 Subject: [PATCH] Refactor retrieving remote aircraft data Instead of requesting it individually for each callsign and waiting for a signal from xswiftbus, pass in a list of callsigns and use async callback to read the data. --- .../simulator/xplane/simulatorxplane.cpp | 31 ++++++--- .../simulator/xplane/simulatorxplane.h | 5 +- .../simulator/xplane/xplanempaircraft.cpp | 5 ++ .../xplane/xswiftbustrafficproxy.cpp | 22 +++++-- .../simulator/xplane/xswiftbustrafficproxy.h | 15 +++-- .../org.swift_project.xswiftbus.traffic.xml | 2 - src/xswiftbus/traffic.cpp | 65 ++++++++++++------- src/xswiftbus/traffic.h | 6 +- 8 files changed, 102 insertions(+), 49 deletions(-) diff --git a/src/plugins/simulator/xplane/simulatorxplane.cpp b/src/plugins/simulator/xplane/simulatorxplane.cpp index 02afd2385..371ef9b71 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.cpp +++ b/src/plugins/simulator/xplane/simulatorxplane.cpp @@ -261,7 +261,6 @@ namespace BlackSimPlugin connect(m_serviceProxy, &CXSwiftBusServiceProxy::airportsInRangeUpdated, this, &CSimulatorXPlane::setAirportsInRange); 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); } @@ -805,19 +804,31 @@ namespace BlackSimPlugin void CSimulatorXPlane::requestRemoteAircraftDataFromXPlane() { if (!isConnected()) { return; } - m_trafficProxy->requestRemoteAircraftData(); + m_trafficProxy->getRemoteAircraftsData(m_xplaneAircraftObjects.getAllCallsignStrings(), [ = ](const QStringList & callsigns, const QDoubleList & latitudesDeg, const QDoubleList & longitudesDeg, const QDoubleList & elevationsM, const QDoubleList & verticalOffsets) + { + updateRemoteAircraftsFromSimulator(callsigns, latitudesDeg, longitudesDeg, elevationsM, verticalOffsets); + }); } - void CSimulatorXPlane::updateRemoteAircraftFromSimulator(const QString &callsign, double latitudeDeg, double longitudeDeg, double elevationMeters, double modelVerticalOffsetMeters) + void CSimulatorXPlane::updateRemoteAircraftsFromSimulator(const QStringList &callsigns, const QDoubleList &latitudesDeg, const QDoubleList &longitudesDeg, + const QDoubleList &elevationsM, const QDoubleList &verticalOffsets) { - // we skip if we are not near ground - const CCallsign cs(callsign); - if (!m_xplaneAircraftObjects.contains(cs)) { return; } - if (m_xplaneAircraftObjects[cs].getSituationAsSent().canLikelySkipNearGroundInterpolation()) { return; } + for (int i = 0; i < callsigns.size(); i++) + { + const CCallsign cs(callsigns[i]); + if (!m_xplaneAircraftObjects.contains(cs)) { continue; } - CElevationPlane elevation(CLatitude(latitudeDeg, CAngleUnit::deg()), CLongitude(longitudeDeg, CAngleUnit::deg()), CAltitude(elevationMeters, CLengthUnit::m())); - elevation.setSinglePointRadius(); - this->rememberElevationAndCG(callsign, elevation, CLength(modelVerticalOffsetMeters, CLengthUnit::m())); + // we skip if we are not near ground + if (m_xplaneAircraftObjects[cs].getSituationAsSent().canLikelySkipNearGroundInterpolation()) { continue; } + + CAltitude elevationAlt(elevationsM[i], CLengthUnit::m()); + elevationAlt.switchUnit(CLengthUnit::ft()); + CElevationPlane elevation(CLatitude(latitudesDeg[i], CAngleUnit::deg()), CLongitude(longitudesDeg[i], CAngleUnit::deg()), elevationAlt); + elevation.setSinglePointRadius(); + CLength cg(verticalOffsets[i], CLengthUnit::m()); + cg.switchUnit(CLengthUnit::ft()); + this->rememberElevationAndCG(callsigns[i], elevation, cg); + } } void CSimulatorXPlane::updateAirportsInRange() diff --git a/src/plugins/simulator/xplane/simulatorxplane.h b/src/plugins/simulator/xplane/simulatorxplane.h index adb99b79c..1950e9851 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.h +++ b/src/plugins/simulator/xplane/simulatorxplane.h @@ -164,6 +164,8 @@ namespace BlackSimPlugin //! @} private: + using QDoubleList = QList; + void serviceUnregistered(); void setAirportsInRange(const QStringList &icaoCodes, const QStringList &names, const BlackMisc::CSequence &lats, const BlackMisc::CSequence &lons, const BlackMisc::CSequence &alts); void emitOwnAircraftModelChanged(const QString &path, const QString &filename, const QString &livery, const QString &icao, @@ -179,7 +181,8 @@ namespace BlackSimPlugin void updateRemoteAircraft(); void requestRemoteAircraftDataFromXPlane(); - void updateRemoteAircraftFromSimulator(const QString &callsign, double latitudeDeg, double longitudeDeg, double elevationMeters, double modelVerticalOffsetMeters); + void updateRemoteAircraftsFromSimulator(const QStringList &callsigns, const QDoubleList &latitudesDeg, const QDoubleList &longitudesDeg, + const QDoubleList &elevationsM, const QDoubleList &verticalOffsets); void updateAirportsInRange(); void remoteAircraftAdded(const QString &callsign); void remoteAircraftAddingFailed(const QString &callsign); diff --git a/src/plugins/simulator/xplane/xplanempaircraft.cpp b/src/plugins/simulator/xplane/xplanempaircraft.cpp index f29d72ddd..d0c53a3c2 100644 --- a/src/plugins/simulator/xplane/xplanempaircraft.cpp +++ b/src/plugins/simulator/xplane/xplanempaircraft.cpp @@ -58,5 +58,10 @@ namespace BlackSimPlugin { return CCallsignSet(this->keys()); } + + QStringList CXPlaneMPAircraftObjects::getAllCallsignStrings(bool sorted) const + { + return this->getAllCallsigns().getCallsignStrings(sorted); + } } // namespace } // namespace diff --git a/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp b/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp index 5220f5995..18c4ab23a 100644 --- a/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp +++ b/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp @@ -107,15 +107,29 @@ namespace BlackSimPlugin m_dbusInterface->callDBus(QLatin1String("setInterpolatorMode"), callsign, spline); } - void CXSwiftBusTrafficProxy::requestRemoteAircraftData() + void CXSwiftBusTrafficProxy::getRemoteAircraftsData(const QStringList &callsigns, const RemoteAircraftDataCallback &setter) { - m_dbusInterface->callDBus(QLatin1String("requestRemoteAircraftData")); + std::function callback = [ = ](QDBusPendingCallWatcher * watcher) + { + QDBusPendingReply, QList, QList, QList> reply = *watcher; + if (!reply.isError()) + { + QStringList callsigns = reply.argumentAt<0>(); + QList latitudesDeg = reply.argumentAt<1>(); + QList longitudesDeg = reply.argumentAt<2>(); + QList elevationsM = reply.argumentAt<3>(); + QList verticalOffsets = reply.argumentAt<4>(); + setter(callsigns, latitudesDeg, longitudesDeg, elevationsM, verticalOffsets); + } + watcher->deleteLater(); + }; + m_dbusInterface->callDBusAsync(QLatin1String("getRemoteAircraftsData"), callback, callsigns); } void CXSwiftBusTrafficProxy::getEelevationAtPosition(const CCallsign &callsign, double latitude, double longitude, double altitude, - const ElevationCallback &setter) + const ElevationCallback &setter) { - std::function callback = [=](QDBusPendingCallWatcher * watcher) + std::function callback = [ = ](QDBusPendingCallWatcher * watcher) { QDBusPendingReply reply = *watcher; if (!reply.isError()) diff --git a/src/plugins/simulator/xplane/xswiftbustrafficproxy.h b/src/plugins/simulator/xplane/xswiftbustrafficproxy.h index b15c813cb..8a7e8f9b6 100644 --- a/src/plugins/simulator/xplane/xswiftbustrafficproxy.h +++ b/src/plugins/simulator/xplane/xswiftbustrafficproxy.h @@ -39,8 +39,15 @@ namespace BlackSimPlugin Q_OBJECT public: + //! List of doubles + using QDoubleList = QList; + + //! Elevation callback using ElevationCallback = std::function; + //! Remote aircrafts data callback + using RemoteAircraftDataCallback = std::function; + //! Service name static const QString &InterfaceName() { @@ -66,10 +73,6 @@ namespace BlackSimPlugin //! \remark from simulator to driver void simFrame(); - //! Remote aircraft data - //! \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); @@ -126,8 +129,8 @@ namespace BlackSimPlugin //! \deprecated XSwiftBus::CTraffic::setInterpolatorMode void setInterpolatorMode(const QString &callsign, bool spline); - //! \copydoc XSwiftBus::CTraffic::requestRemoteAircraftData - void requestRemoteAircraftData(); + //! \copydoc XSwiftBus::CTraffic::getRemoteAircraftsData + void getRemoteAircraftsData(const QStringList &callsigns, const RemoteAircraftDataCallback &setter); //! \copydoc XSwiftBus::CTraffic::getEelevationAtPosition void getEelevationAtPosition(const BlackMisc::Aviation::CCallsign &callsign, double latitude, double longitude, double altitude, diff --git a/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml b/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml index aea134bf6..e3bb46075 100644 --- a/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml +++ b/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml @@ -70,8 +70,6 @@ R"( - - diff --git a/src/xswiftbus/traffic.cpp b/src/xswiftbus/traffic.cpp index 447e884cf..87378ab66 100644 --- a/src/xswiftbus/traffic.cpp +++ b/src/xswiftbus/traffic.cpp @@ -111,18 +111,6 @@ namespace XSwiftBus m_emitSimFrame = !m_emitSimFrame; } - void CTraffic::emitRemoteAircraftData(const std::string &callsign, double latitude, double longitude, double elevation, double modelVerticalOffset) - { - CDBusMessage signalRemoteAircraftData = CDBusMessage::createSignal(XSWIFTBUS_TRAFFIC_OBJECTPATH, XSWIFTBUS_TRAFFIC_INTERFACENAME, "remoteAircraftData"); - signalRemoteAircraftData.beginArgumentWrite(); - signalRemoteAircraftData.appendArgument(callsign); - signalRemoteAircraftData.appendArgument(latitude); - signalRemoteAircraftData.appendArgument(longitude); - signalRemoteAircraftData.appendArgument(elevation); - signalRemoteAircraftData.appendArgument(modelVerticalOffset); - sendDBusMessage(signalRemoteAircraftData); - } - void CTraffic::emitPlaneAdded(const std::string &callsign) { CDBusMessage signalPlaneAdded = CDBusMessage::createSignal(XSWIFTBUS_TRAFFIC_OBJECTPATH, XSWIFTBUS_TRAFFIC_INTERFACENAME, "remoteAircraftAdded"); @@ -353,22 +341,38 @@ namespace XSwiftBus else { plane->xpdr.mode = xpmpTransponderMode_Standby; } } - void CTraffic::requestRemoteAircraftData() + void CTraffic::getRemoteAircraftsData(std::vector &callsigns, std::vector &latitudesDeg, std::vector &longitudesDeg, + std::vector &elevationsM, std::vector &verticalOffsets) { - if (m_planesByCallsign.empty()) { return; } - for (const auto &kv : m_planesByCallsign) + if (callsigns.empty() || m_planesByCallsign.empty()) { return; } + + const auto requestedCallsigns = callsigns; + callsigns.clear(); + latitudesDeg.clear(); + longitudesDeg.clear(); + elevationsM.clear(); + verticalOffsets.clear(); + + for (const auto &requestedCallsign : requestedCallsigns) { - Plane *plane = kv.second; + auto planeIt = m_planesByCallsign.find(requestedCallsign); + if (planeIt == m_planesByCallsign.end()) { continue; } + + Plane *plane = planeIt->second; assert(plane); + double lat = plane->position.lat; double lon = plane->position.lon; - double elevation = plane->position.elevation; - double groundElevation = plane->terrainProbe.getElevation(lat, lon, elevation); + double groundElevation = plane->terrainProbe.getElevation(lat, lon, plane->position.elevation); if (std::isnan(groundElevation)) { groundElevation = 0.0; } double fudgeFactor = 3.0; XPMPGetVerticalOffset(plane->id, &fudgeFactor); - // actualVertOffsetInfo(plane->modelName.c_str(), nullptr, &fudgeFactor); - emitRemoteAircraftData(plane->callsign, lat, lon, groundElevation, fudgeFactor); + + callsigns.push_back(requestedCallsign); + latitudesDeg.push_back(lat); + longitudesDeg.push_back(lon); + elevationsM.push_back(groundElevation); + verticalOffsets.push_back(fudgeFactor); } } @@ -605,12 +609,27 @@ namespace XSwiftBus setPlaneTransponder(callsign, code, modeC, ident); }); } - else if (message.getMethodName() == "requestRemoteAircraftData") + else if (message.getMethodName() == "getRemoteAircraftsData") { - maybeSendEmptyDBusReply(wantsReply, sender, serial); + std::vector requestedcallsigns; + message.beginArgumentRead(); + message.getArgument(requestedcallsigns); queueDBusCall([ = ]() { - requestRemoteAircraftData(); + std::vector callsigns = requestedcallsigns; + std::vector latitudesDeg; + std::vector longitudesDeg; + std::vector elevationsM; + std::vector verticalOffsets; + getRemoteAircraftsData(callsigns, latitudesDeg, longitudesDeg, elevationsM, verticalOffsets); + CDBusMessage reply = CDBusMessage::createReply(sender, serial); + reply.beginArgumentWrite(); + reply.appendArgument(callsigns); + reply.appendArgument(latitudesDeg); + reply.appendArgument(longitudesDeg); + reply.appendArgument(elevationsM); + reply.appendArgument(verticalOffsets); + sendDBusMessage(reply); }); } else if (message.getMethodName() == "getEelevationAtPosition") diff --git a/src/xswiftbus/traffic.h b/src/xswiftbus/traffic.h index f7537f4a3..749367334 100644 --- a/src/xswiftbus/traffic.h +++ b/src/xswiftbus/traffic.h @@ -107,8 +107,9 @@ namespace XSwiftBus //! Set the transponder of a traffic aircraft void setPlaneTransponder(const std::string &callsign, int code, bool modeC, bool ident); - //! Request traffic plane data. A signal remoteAircraftData will be emitted for each known plane - void requestRemoteAircraftData(); + //! Get remote aircrafts data (lat, lon, elevation and CG) + void getRemoteAircraftsData(std::vector &callsigns, std::vector &latitudesDeg, std::vector &longitudesDeg, + std::vector &elevationsM, std::vector &verticalOffsets); //! Get the ground elevation at an arbitrary position double getEelevationAtPosition(const std::string &callsign, double latitude, double longitude, double altitude); @@ -124,7 +125,6 @@ namespace XSwiftBus CTerrainProbe m_terrainProbe; 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);