diff --git a/src/plugins/simulator/xplane/simulatorxplane.cpp b/src/plugins/simulator/xplane/simulatorxplane.cpp index 0ddb4fd56..8445da9d4 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.cpp +++ b/src/plugins/simulator/xplane/simulatorxplane.cpp @@ -254,6 +254,7 @@ namespace BlackSimPlugin m_traffic->updateInstalledModels(); m_watcher->setConnection(m_conn); reloadWeatherSettings(); + loadCslPackages(); emitSimulatorCombinedStatus(); return true; } @@ -434,6 +435,49 @@ 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()); + for (const auto &model : m_modelSet.getThreadLocal()) + { + 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_traffic->loadPlanesPackage(package.s); + } + } + + QString CSimulatorXPlane::findCslPackage(const QString &modelFile) + { + QDir dir = QFileInfo(modelFile).dir(); + do + { + if (dir.exists(QStringLiteral("xsb_aircraft.txt"))) + { + if (dir.cdUp()) { return dir.path(); } + } + } while(dir.cdUp()); + CLogMessage(this).warning("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 06907358f..c46578755 100644 --- a/src/plugins/simulator/xplane/simulatorxplane.h +++ b/src/plugins/simulator/xplane/simulatorxplane.h @@ -21,6 +21,7 @@ #include "blackmisc/pq/time.h" #include "blackmisc/pq/units.h" #include "blackmisc/simulation/aircraftmodellist.h" +#include "blackmisc/simulation/data/modelcaches.h" #include "blackmisc/simulation/simulatorsettings.h" #include "blackmisc/weather/weathergrid.h" #include "blackmisc/settingscache.h" @@ -134,6 +135,9 @@ namespace BlackSimPlugin void ps_installedModelsUpdated(const QStringList &modelStrings, const QStringList &icaos, const QStringList &airlines, const QStringList &liveries); private: + void loadCslPackages(); + QString findCslPackage(const QString &modelFileName); + //! Inject weather grid to simulator void injectWeatherGrid(const BlackMisc::Weather::CWeatherGrid &weatherGrid); void reloadWeatherSettings(); @@ -147,6 +151,7 @@ namespace BlackSimPlugin QTimer *m_slowTimer { nullptr }; BlackMisc::Aviation::CAirportList m_airportsInRange; //!< aiports in range of own aircraft BlackMisc::Simulation::CAircraftModelList m_installedModels; //!< \todo Do we still need this, as we now focus on model set + BlackMisc::CData m_modelSet { this }; BlackMisc::Geo::CCoordinateGeodetic m_lastWeatherPosition; //!< Own aircraft position at which weather was fetched and injected last BlackMisc::CSetting m_weatherScenarioSettings { this, &CSimulatorXPlane::reloadWeatherSettings };