diff --git a/src/plugins/simulator/xplane/simulatorxplane.cpp b/src/plugins/simulator/xplane/simulatorxplane.cpp index 999cb4e85..e2c5729b4 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.cpp +++ b/src/plugins/simulator/xplane/simulatorxplane.cpp @@ -380,6 +380,7 @@ namespace BlackSimPlugin connect(m_trafficProxy, &CXSwiftBusTrafficProxy::remoteAircraftAddingFailed, this, &CSimulatorXPlane::onRemoteAircraftAddingFailed); if (m_watcher) { m_watcher->setConnection(m_dBusConnection); } m_trafficProxy->removeAllPlanes(); + this->loadCslPackages(); this->emitSimulatorCombinedStatus(); this->initSimulatorInternals(); @@ -544,6 +545,53 @@ namespace BlackSimPlugin return false; } + void CSimulatorXPlane::loadCslPackages() + { + struct Prefix { QString s; }; + struct PrefixComparator + { + bool operator()(const Prefix &a, const QString &b) const { return QStringRef(&a.s) < b.leftRef(a.s.size()); } + bool operator()(const QString &a, const Prefix &b) const { return a.leftRef(b.s.size()) < QStringRef(&b.s); } + }; + QList packages; + + Q_ASSERT(isConnected()); + const CAircraftModelList models = this->getModelSet(); + for (const auto &model : models) + { + const QString &modelFile = model.getFileName(); + if (modelFile.isEmpty() || ! QFile::exists(modelFile)) { continue; } + auto it = std::lower_bound(packages.begin(), packages.end(), modelFile, PrefixComparator()); + if (it != packages.end() && modelFile.startsWith(it->s)) { continue; } + QString package = findCslPackage(modelFile); + if (package.isEmpty()) { continue; } + packages.insert(it, { package.append('/') }); + } + for (auto &package : packages) + { + Q_ASSERT(package.s.endsWith('/')); + package.s.chop(1); + m_trafficProxy->loadPlanesPackage(package.s); + } + } + + QString CSimulatorXPlane::findCslPackage(const QString &modelFile) + { + //! \todo KB 2018-02 KB when I have removed the CSL dir (acciedently) there was no warning here + const QFileInfo info(modelFile); + QDir dir = info.isDir() ? QDir(modelFile) : info.dir(); + do + { + if (dir.exists(QStringLiteral("xsb_aircraft.txt"))) + { + if (dir.cdUp()) { return dir.path(); } + } + } + while (dir.cdUp()); + CLogMessage(this).warning(u"Failed to find CSL package for %1") << modelFile; + return {}; + } + bool CSimulatorXPlane::physicallyAddRemoteAircraft(const CSimulatedAircraft &newRemoteAircraft) { Q_ASSERT(isConnected()); diff --git a/src/plugins/simulator/xplane/simulatorxplane.h b/src/plugins/simulator/xplane/simulatorxplane.h index c99049b96..7287d1cb1 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.h +++ b/src/plugins/simulator/xplane/simulatorxplane.h @@ -179,6 +179,9 @@ namespace BlackSimPlugin void fastTimerTimeout(); void slowTimerTimeout(); + void loadCslPackages(); + QString findCslPackage(const QString &modelFileName); + //! Update remote aircraft //! \remark this is where the interpolated data are set void updateRemoteAircraft(); diff --git a/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml b/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml index 75ae6d1b2..989801b00 100644 --- a/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml +++ b/src/xswiftbus/org.swift_project.xswiftbus.traffic.xml @@ -9,6 +9,10 @@ R"( + + + + diff --git a/src/xswiftbus/traffic.cpp b/src/xswiftbus/traffic.cpp index 5031ed2ac..d39bf7cf3 100644 --- a/src/xswiftbus/traffic.cpp +++ b/src/xswiftbus/traffic.cpp @@ -85,12 +85,6 @@ namespace XSwiftBus { if (! s_legacyDataOK) { return false; } - findAllCslPackages(g_xplanePath); - for (const auto &package : m_cslPackages) - { - loadPlanesPackage(package); - } - if (! m_initialized) { auto err = XPMPMultiplayerInit(preferences, preferences); @@ -145,36 +139,6 @@ namespace XSwiftBus } } - void CTraffic::findAllCslPackages(const std::string &path) - { - std::vector nameBuffer(65536, '\0'); - std::vector indices(4096, nullptr); - int returnedFiles; - - // Remove trailing / - std::string dir = path.substr(0, path.size() - 1); - XPLMGetDirectoryContents(dir.c_str(), 0, - nameBuffer.data(), static_cast(nameBuffer.size()), - indices.data(), static_cast(indices.size()), - nullptr, &returnedFiles); - for (std::size_t i = 0; i < static_cast(returnedFiles); i++) - { - std::string fileName(indices[i]); - if (fileName == "xsb_aircraft.txt") - { - const std::string seperator = "/\\"; - const std::size_t sepPos = dir.find_last_of(seperator); - std::string parentPath = dir.substr(0, sepPos); - m_cslPackages.insert(parentPath); - } - else - { - std::string filePath(path + fileName + g_sep); - findAllCslPackages(filePath); - } - } - } - void CTraffic::emitSimFrame() { if (m_emitSimFrame) { sendDBusSignal("simFrame"); } @@ -562,6 +526,16 @@ namespace XSwiftBus cleanup(); }); } + else if (message.getMethodName() == "loadPlanesPackage") + { + std::string path; + message.beginArgumentRead(); + message.getArgument(path); + queueDBusCall([ = ]() + { + sendDBusReply(sender, serial, loadPlanesPackage(path)); + }); + } else if (message.getMethodName() == "setDefaultIcao") { std::string defaultIcao; diff --git a/src/xswiftbus/traffic.h b/src/xswiftbus/traffic.h index ab61e6f1e..4bdccb6a5 100644 --- a/src/xswiftbus/traffic.h +++ b/src/xswiftbus/traffic.h @@ -21,7 +21,6 @@ #include #include #include -#include //! \cond PRIVATE #define XSWIFTBUS_TRAFFIC_INTERFACENAME "org.swift_project.xswiftbus.traffic" @@ -147,9 +146,7 @@ namespace XSwiftBus bool m_initialized = false; bool m_enabledMultiplayer = false; CTerrainProbe m_terrainProbe; - std::set m_cslPackages; - void findAllCslPackages(const std::string &path); void emitSimFrame(); void emitPlaneAdded(const std::string &callsign); void emitPlaneAddingFailed(const std::string &callsign);