diff --git a/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp b/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp index b97ec2057..23d6b0f6b 100644 --- a/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp +++ b/src/plugins/simulator/xplane/xswiftbustrafficproxy.cpp @@ -41,6 +41,20 @@ namespace BlackSimPlugin } } + MultiplayerAcquireInfo CXSwiftBusTrafficProxy::acquireMultiplayerPlanes() + { + QDBusPendingReply reply = m_dbusInterface->asyncCall(QLatin1String("acquireMultiplayerPlanes")); + reply.waitForFinished(); + if (reply.isError()) + { + BlackMisc::CLogMessage(this).debug("CXSwiftBusTrafficProxy::acquireMultiplayerPlanes returned: %1") << reply.error().message(); + } + MultiplayerAcquireInfo info; + info.hasAcquired = reply.argumentAt<0>(); + info.owner = reply.argumentAt<1>(); + return info; + } + bool CXSwiftBusTrafficProxy::initialize() { return m_dbusInterface->callDBusRet(QLatin1String("initialize")); diff --git a/src/plugins/simulator/xplane/xswiftbustrafficproxy.h b/src/plugins/simulator/xplane/xswiftbustrafficproxy.h index 827e39ff9..143bc395e 100644 --- a/src/plugins/simulator/xplane/xswiftbustrafficproxy.h +++ b/src/plugins/simulator/xplane/xswiftbustrafficproxy.h @@ -99,6 +99,13 @@ namespace BlackSimPlugin QList idents; //!< List of active idents }; + //! Multiplayer Acquire Info + struct MultiplayerAcquireInfo + { + bool hasAcquired; //!< Has XSwiftBus acquired multiplayer planes? + QString owner; //!< Name of the plugin having multiplayer planes acquired + }; + /*! * Proxy object connected to a real XSwiftBus::CTraffic object via DBus */ @@ -145,6 +152,9 @@ namespace BlackSimPlugin void remoteAircraftAddingFailed(const QString &callsign); public slots: + //! \copydoc XSwiftBus::CTraffic::acquireMultiplayerPlanes + MultiplayerAcquireInfo acquireMultiplayerPlanes(); + //! \copydoc XSwiftBus::CTraffic::initialize bool initialize(); diff --git a/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml b/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml index af4fdaec2..989801b00 100644 --- a/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml +++ b/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml @@ -1,5 +1,9 @@ R"( + + + + diff --git a/src/xswiftbus/traffic.cpp b/src/xswiftbus/traffic.cpp index a61fd6b64..03a4cf573 100644 --- a/src/xswiftbus/traffic.cpp +++ b/src/xswiftbus/traffic.cpp @@ -19,6 +19,8 @@ #include "XPLMGraphics.h" #include #include +#include +#include #include #include #include @@ -83,25 +85,50 @@ namespace XSwiftBus { if (! s_legacyDataOK) { return false; } - auto err = XPMPMultiplayerInit(preferences, preferences); - if (*err) { cleanup(); return false; } - m_initialized = true; + if (! m_initialized) + { + auto err = XPMPMultiplayerInit(preferences, preferences); + if (*err) { cleanup(); } + else { m_initialized = true; } + } - err = XPMPMultiplayerEnable(); - if (*err) { cleanup(); return false; } - m_enabled = true; + return m_initialized; + } - XPMPLoadPlanesIfNecessary(); - return true; + bool CTraffic::acquireMultiplayerPlanes(std::string *owner) + { + if (! m_enabledMultiplayer) + { + auto err = XPMPMultiplayerEnable(); + if (*err) + { + cleanup(); + } + else + { + m_enabledMultiplayer = true; + XPMPLoadPlanesIfNecessary(); + } + } + + int totalAircraft; + int activeAircraft; + XPLMPluginID controller; + XPLMCountAircraft(&totalAircraft, &activeAircraft, &controller); + + char pluginName[256]; + XPLMGetPluginInfo(controller, pluginName, nullptr, nullptr, nullptr); + *owner = std::string(pluginName); + return m_enabledMultiplayer; } void CTraffic::cleanup() { removeAllPlanes(); - if (m_enabled) + if (m_enabledMultiplayer) { - m_enabled = false; + m_enabledMultiplayer = false; XPMPMultiplayerDisable(); } @@ -474,7 +501,20 @@ namespace XSwiftBus } else if (message.getInterfaceName() == XSWIFTBUS_TRAFFIC_INTERFACENAME) { - if (message.getMethodName() == "initialize") + if (message.getMethodName() == "acquireMultiplayerPlanes") + { + queueDBusCall([ = ]() + { + std::string owner; + bool acquired = acquireMultiplayerPlanes(&owner); + CDBusMessage reply = CDBusMessage::createReply(sender, serial); + reply.beginArgumentWrite(); + reply.appendArgument(acquired); + reply.appendArgument(owner); + sendDBusMessage(reply); + }); + } + else if (message.getMethodName() == "initialize") { sendDBusReply(sender, serial, initialize()); } diff --git a/src/xswiftbus/traffic.h b/src/xswiftbus/traffic.h index bfb646a9d..c85a179e3 100644 --- a/src/xswiftbus/traffic.h +++ b/src/xswiftbus/traffic.h @@ -65,6 +65,9 @@ namespace XSwiftBus //! Initialize the multiplayer planes rendering and return true if successful bool initialize(); + //! Returns whether multiplayer planes have been acquired. If not, owner will be set to the plugin that acquired it. + bool acquireMultiplayerPlanes(std::string *owner = nullptr); + //! Reverse the actions of initialize(). void cleanup(); @@ -132,7 +135,7 @@ namespace XSwiftBus private: bool m_initialized = false; - bool m_enabled = false; + bool m_enabledMultiplayer = false; CTerrainProbe m_terrainProbe; void emitSimFrame();