Fixup RideCache Load in Thread

.. move thread based load of ridecache into ridecache, this fixes a
   serious regression.

.. previously because the ridecache was created in a thread it could
   not attach to the events from the main gui event loop.

.. we now load the RideDB.json file in a worker thread, but the
   ridecache, and its items are created in the main thread.
This commit is contained in:
Mark Liversedge
2020-08-14 10:25:21 +01:00
parent 64e83121ca
commit 9bb1f3434d
4 changed files with 32 additions and 30 deletions

View File

@@ -177,23 +177,14 @@ Athlete::Athlete(Context *context, const QDir &homeDir)
cloudAutoDownload = new CloudServiceAutoDownload(context);
connect(context, SIGNAL(refreshEnd()), cloudAutoDownload, SLOT(autoDownload()));
// blocking as at startup
if (context->mainWindow->progress) {
// now most dependencies are in get cache
rideCache = new RideCache(context);
loadComplete();
} else {
// load in background once GC is up and running
AthleteLoader *loader = new AthleteLoader(context);
connect(loader, SIGNAL(finished()), this, SLOT(loadComplete()));
loader->start();
}
}
// now most dependencies are in get cache
QEventLoop loop;
rideCache = new RideCache(context);
connect(rideCache, SIGNAL(loadComplete()), &loop, SLOT(quit()));
connect(rideCache, SIGNAL(loadComplete()), this, SLOT(loadComplete()));
void
AthleteLoader::run()
{
context->athlete->rideCache = new RideCache(context);
// we need to block on load complete if first (before mainwindow ready)
if (context->mainWindow->progress) loop.exec();
}
void

View File

@@ -225,17 +225,4 @@ class AthleteDirectoryStructure : public QObject {
};
class MainWindow;
class AthleteLoader : public QThread
{
public:
// load an athlete in background
AthleteLoader(Context *context) : context(context) {}
void run() override;
private:
Context *context;
};
#endif

View File

@@ -49,6 +49,18 @@
bool rideCacheGreaterThan(const RideItem *a, const RideItem *b) { return a->dateTime > b->dateTime; }
bool rideCacheLessThan(const RideItem *a, const RideItem *b) { return a->dateTime < b->dateTime; }
class RideCacheLoader : public QThread
{
public:
RideCacheLoader(RideCache *cache) : cache(cache) {}
void run() { cache->load(); }
private:
RideCache *cache;
};
RideCache::RideCache(Context *context) : context(context)
{
directory = context->athlete->home->activities();
@@ -128,8 +140,15 @@ RideCache::RideCache(Context *context) : context(context)
qSort(rides_.begin(), rides_.end(), rideCacheLessThan);
// load the store - will unstale once cache restored
load();
RideCacheLoader *rideCacheLoader = new RideCacheLoader(this);
connect(rideCacheLoader, SIGNAL(finished()), this, SLOT(postLoad()));
connect(rideCacheLoader, SIGNAL(finished()), this, SIGNAL(loadComplete()));
rideCacheLoader->start();
}
void
RideCache::postLoad()
{
// set model once we have the basics
model_ = new RideCacheModel(context, this);
@@ -461,6 +480,9 @@ RideCache::writeAsCSV(QString filename)
void
itemRefresh(RideItem *&item)
{
// debugging below to watch refreshing take place
//fprintf(stderr, "%s %s refresh\n", item->context->athlete->cyclist.toStdString().c_str(), item->dateTime.toString().toStdString().c_str()); fflush(stderr);
// need parser to be reentrant !item->refresh();
if (item->isstale) {
item->refresh();

View File

@@ -100,6 +100,7 @@ class RideCache : public QObject
// restore / dump cache to disk (json)
void load();
void postLoad();
void save(bool opendata=false, QString filename="");
// find entry quickly
@@ -126,6 +127,7 @@ class RideCache : public QObject
signals:
void modelProgress(int, int); // let others know when we're refreshing the model estimates
void loadComplete(); // when loading the cache completes...
// us telling the world the item changed
void itemChanged(RideItem*);