From 7948a135b645646486a2f75732df2eee2e38e141 Mon Sep 17 00:00:00 2001 From: James Turner Date: Wed, 17 Jun 2020 11:51:16 +0100 Subject: [PATCH] Launcher: load aircraft with odd -set.xml includes Lars T identified some cases where the launcher would fail to include local aircraft due to them using weird ways to include additional XML into their -set.xml. Add a temporary resource provider while the launcher is scanning, to make this work. Will pick to LTS branch once verified. --- src/GUI/LocalAircraftCache.cxx | 48 +++++++++++++++++++++++++++++++--- 1 file changed, 45 insertions(+), 3 deletions(-) diff --git a/src/GUI/LocalAircraftCache.cxx b/src/GUI/LocalAircraftCache.cxx index 5c7ea4658..e538690cf 100644 --- a/src/GUI/LocalAircraftCache.cxx +++ b/src/GUI/LocalAircraftCache.cxx @@ -34,6 +34,7 @@ #include
#include +#include #include #include @@ -204,6 +205,39 @@ QVariant AircraftItem::status(int variant) } +// ensure references to Aircraft/ foo are resolved. This happens when +// aircraft reference a path (probably to themselves) in their -set.xml +class CurrentScanDirProvider : public simgear::ResourceProvider +{ +public: + CurrentScanDirProvider() : simgear::ResourceProvider(simgear::ResourceManager::PRIORITY_NORMAL) {} + + ~CurrentScanDirProvider() = default; + + SGPath resolve(const std::string& aResource, SGPath& aContext) const override + { + string_list pieces(sgPathBranchSplit(aResource)); + if ((pieces.size() < 3) || (pieces.front() != "Aircraft")) { + return SGPath{}; // not an Aircraft path + } + + const std::string res(aResource, 9); // resource path with 'Aircraft/' removed + SGPath p = _currentScanPath / res; + if (p.exists()) + return p; + + return SGPath{}; + } + + void setCurrentPath(const SGPath& p) + { + _currentScanPath = p; + } + +private: + SGPath _currentScanPath; +}; + class AircraftScanThread : public QThread { Q_OBJECT @@ -212,10 +246,14 @@ public: m_dirs(dirsToScan), m_done(false) { + auto rm = simgear::ResourceManager::instance(); + m_currentScanDir.reset(new CurrentScanDirProvider); + rm->addProvider(m_currentScanDir.get()); } ~AircraftScanThread() { + simgear::ResourceManager::instance()->removeProvider(m_currentScanDir.get()); } /** thread-safe access to items already scanned */ @@ -238,11 +276,13 @@ Q_SIGNALS: void addedItems(); protected: - virtual void run() + void run() override { readCache(); Q_FOREACH(QString d, m_dirs) { + const auto p = SGPath::fromUtf8(d.toUtf8().toStdString()); + m_currentScanDir->setCurrentPath(p); scanAircraftDir(QDir(d)); if (m_done) { return; @@ -334,8 +374,9 @@ private: } else { variants.append(item); } - } catch (sg_exception&) { - qWarning() << "Problems occurred while parsing" << xmlChild.absoluteFilePath() << "(skipping)"; + } catch (sg_exception& e) { + qWarning() << "Problems occurred while parsing" << xmlChild.absoluteFilePath() << "(skipping)" + << "\n\t" << QString::fromStdString(e.what()); continue; } @@ -378,6 +419,7 @@ private: QMap m_nextCache; bool m_done; + std::unique_ptr m_currentScanDir; }; static std::unique_ptr static_cacheInstance;