1
0
Fork 0

Launcher: fixes for scanning local aircraft dirs

When multiple ‘added items’ signals occur, don’t loose some entries,
always pull the full list from the aircraft cache.
This commit is contained in:
James Turner 2018-01-07 14:19:28 +00:00
parent 178c6440f6
commit d2cb99ba1d
3 changed files with 40 additions and 42 deletions

View file

@ -39,7 +39,6 @@
#include "QmlAircraftInfo.hxx" #include "QmlAircraftInfo.hxx"
const int STANDARD_THUMBNAIL_HEIGHT = 128; const int STANDARD_THUMBNAIL_HEIGHT = 128;
const int STANDARD_THUMBNAIL_WIDTH = 172;
using namespace simgear::pkg; using namespace simgear::pkg;
@ -630,22 +629,17 @@ QString AircraftItemModel::nameForAircraftURI(QUrl uri) const
return {}; return {};
} }
void AircraftItemModel::onScanAddedItems(int count) void AircraftItemModel::onScanAddedItems(int addedCount)
{ {
QVector<AircraftItemPtr> newItems = LocalAircraftCache::instance()->newestItems(count); Q_UNUSED(addedCount);
if (newItems.isEmpty()) const auto items = LocalAircraftCache::instance()->allItems();
return; const int newItemCount = items.size() - m_cachedLocalAircraftCount;
const int firstRow = m_cachedLocalAircraftCount;
const int lastRow = firstRow + newItemCount - 1;
int firstRow = m_cachedLocalAircraftCount;
int lastRow = firstRow + count - 1;
beginInsertRows(QModelIndex(), firstRow, lastRow); beginInsertRows(QModelIndex(), firstRow, lastRow);
m_cachedLocalAircraftCount += count; m_delegateStates.insert(m_cachedLocalAircraftCount, newItemCount, {});
m_cachedLocalAircraftCount += newItemCount;
// default variants in all cases
for (int i=0; i< count; ++i) {
m_delegateStates.insert(firstRow + i, {});
}
endInsertRows(); endInsertRows();
} }

View file

@ -38,7 +38,7 @@
static quint32 CACHE_VERSION = 8; static quint32 CACHE_VERSION = 8;
const int STANDARD_THUMBNAIL_HEIGHT = 128; const int STANDARD_THUMBNAIL_HEIGHT = 128;
const int STANDARD_THUMBNAIL_WIDTH = 172; //const int STANDARD_THUMBNAIL_WIDTH = 172;
AircraftItem::AircraftItem() AircraftItem::AircraftItem()
{ {
@ -230,6 +230,7 @@ public:
QVector<AircraftItemPtr> result; QVector<AircraftItemPtr> result;
QMutexLocker g(&m_lock); QMutexLocker g(&m_lock);
result.swap(m_items); result.swap(m_items);
Q_ASSERT(m_items.empty());
g.unlock(); g.unlock();
return result; return result;
} }
@ -303,8 +304,8 @@ private:
void scanAircraftDir(QDir path) void scanAircraftDir(QDir path)
{ {
QTime t; //QTime t;
t.start(); //t.start();
QStringList filters; QStringList filters;
filters << "*-set.xml"; filters << "*-set.xml";
@ -318,9 +319,12 @@ private:
QString absolutePath = xmlChild.absoluteFilePath(); QString absolutePath = xmlChild.absoluteFilePath();
AircraftItemPtr item; AircraftItemPtr item;
// should we re-stat here? But we already did so when loading
// the cache and dropped any non-valid entries
if (m_cachedItems.contains(absolutePath)) { if (m_cachedItems.contains(absolutePath)) {
item = m_cachedItems.value(absolutePath); item = m_cachedItems.value(absolutePath);
} else { } else {
// scan the cached item
item = AircraftItemPtr(new AircraftItem(childDir, absolutePath)); item = AircraftItemPtr(new AircraftItem(childDir, absolutePath));
} }
@ -339,7 +343,7 @@ private:
continue; continue;
} }
if (m_done) { if (m_done) { // thread termination bail-out
return; return;
} }
} // of set.xml iteration } // of set.xml iteration
@ -355,13 +359,19 @@ private:
} }
// lock mutex while we modify the items array // lock mutex while we modify the items array
bool didAddItems = false;
{ {
QMutexLocker g(&m_lock); QMutexLocker g(&m_lock);
m_items+=(baseAircraft.values().toVector()); m_items+=(baseAircraft.values().toVector());
didAddItems = !m_items.isEmpty();
} }
emit addedItems(); if (didAddItems) {
emit addedItems();
}
} // of subdir iteration } // of subdir iteration
//qInfo() << "scanning" << path.absolutePath() << "took" << t.elapsed();
} }
QMutex m_lock; QMutex m_lock;
@ -393,7 +403,6 @@ LocalAircraftCache::LocalAircraftCache()
LocalAircraftCache::~LocalAircraftCache() LocalAircraftCache::~LocalAircraftCache()
{ {
abandonCurrentScan(); abandonCurrentScan();
} }
void LocalAircraftCache::setPaths(QStringList paths) void LocalAircraftCache::setPaths(QStringList paths)
@ -415,13 +424,13 @@ void LocalAircraftCache::scanDirs()
rootAircraft.append("Aircraft"); rootAircraft.append("Aircraft");
dirs << QString::fromStdString(rootAircraft.utf8Str()); dirs << QString::fromStdString(rootAircraft.utf8Str());
m_scanThread = new AircraftScanThread(dirs); m_scanThread.reset(new AircraftScanThread(dirs));
connect(m_scanThread, &AircraftScanThread::finished, this, connect(m_scanThread.get(), &AircraftScanThread::finished, this,
&LocalAircraftCache::onScanFinished); &LocalAircraftCache::onScanFinished);
// force a queued connection here since we the scan thread object still // force a queued connection here since we the scan thread object still
// belongs to the same thread as us, and hence this would otherwise be // belongs to the same thread as us, and hence this would otherwise be
// a direct connection // a direct connection
connect(m_scanThread, &AircraftScanThread::addedItems, connect(m_scanThread.get(), &AircraftScanThread::addedItems,
this, &LocalAircraftCache::onScanResults, this, &LocalAircraftCache::onScanResults,
Qt::QueuedConnection); Qt::QueuedConnection);
m_scanThread->start(); m_scanThread->start();
@ -434,6 +443,11 @@ int LocalAircraftCache::itemCount() const
return m_items.size(); return m_items.size();
} }
QVector<AircraftItemPtr> LocalAircraftCache::allItems() const
{
return m_items;
}
AircraftItemPtr LocalAircraftCache::itemAt(int index) const AircraftItemPtr LocalAircraftCache::itemAt(int index) const
{ {
return m_items.at(index); return m_items.at(index);
@ -474,17 +488,6 @@ AircraftItemPtr LocalAircraftCache::primaryItemFor(AircraftItemPtr item) const
return {}; return {};
} }
QVector<AircraftItemPtr> LocalAircraftCache::newestItems(int count)
{
QVector<AircraftItemPtr> r;
r.reserve(count);
int total = m_items.size();
for (int i = total - count; i < count; ++i) {
r.push_back(m_items.at(i));
}
return r;
}
AircraftItemPtr LocalAircraftCache::findItemWithUri(QUrl aircraftUri) const AircraftItemPtr LocalAircraftCache::findItemWithUri(QUrl aircraftUri) const
{ {
int index = findIndexWithUri(aircraftUri); int index = findIndexWithUri(aircraftUri);
@ -500,8 +503,7 @@ void LocalAircraftCache::abandonCurrentScan()
if (m_scanThread) { if (m_scanThread) {
m_scanThread->setDone(); m_scanThread->setDone();
m_scanThread->wait(1000); m_scanThread->wait(1000);
delete m_scanThread; m_scanThread.reset();
m_scanThread = NULL;
} }
} }
@ -512,15 +514,13 @@ void LocalAircraftCache::onScanResults()
if (newItems.isEmpty()) if (newItems.isEmpty())
return; return;
m_items+=newItems; m_items+=newItems;
emit addedItems(newItems.size()); emit addedItems(newItems.size());
} }
void LocalAircraftCache::onScanFinished() void LocalAircraftCache::onScanFinished()
{ {
delete m_scanThread; m_scanThread.reset();
m_scanThread = nullptr;
emit scanCompleted(); emit scanCompleted();
} }
@ -528,6 +528,9 @@ bool LocalAircraftCache::isCandidateAircraftPath(QString path)
{ {
QStringList filters; QStringList filters;
filters << "*-set.xml"; filters << "*-set.xml";
// count of child dirs, if we visited more than ten children without
// finding a -set.xml file, let's assume we are done. This avoids an
// exhaustive search of huge directory trees
int dirCount = 0, int dirCount = 0,
setXmlCount = 0; setXmlCount = 0;

View file

@ -20,6 +20,7 @@
#ifndef LOCALAIRCRAFTCACHE_HXX #ifndef LOCALAIRCRAFTCACHE_HXX
#define LOCALAIRCRAFTCACHE_HXX #define LOCALAIRCRAFTCACHE_HXX
#include <memory>
#include <QObject> #include <QObject>
#include <QPixmap> #include <QPixmap>
#include <QDateTime> #include <QDateTime>
@ -96,6 +97,8 @@ public:
int itemCount() const; int itemCount() const;
QVector<AircraftItemPtr> allItems() const;
AircraftItemPtr itemAt(int index) const; AircraftItemPtr itemAt(int index) const;
AircraftItemPtr findItemWithUri(QUrl aircraftUri) const; AircraftItemPtr findItemWithUri(QUrl aircraftUri) const;
@ -103,8 +106,6 @@ public:
AircraftItemPtr primaryItemFor(AircraftItemPtr item) const; AircraftItemPtr primaryItemFor(AircraftItemPtr item) const;
QVector<AircraftItemPtr> newestItems(int count);
QVariant aircraftStatus(AircraftItemPtr item) const; QVariant aircraftStatus(AircraftItemPtr item) const;
enum AircraftStatus enum AircraftStatus
@ -145,7 +146,7 @@ private:
void abandonCurrentScan(); void abandonCurrentScan();
QStringList m_paths; QStringList m_paths;
AircraftScanThread* m_scanThread = nullptr; std::unique_ptr<AircraftScanThread> m_scanThread;
QVector<AircraftItemPtr> m_items; QVector<AircraftItemPtr> m_items;
}; };