Added RideCache

.. source files missed off last commit
This commit is contained in:
Mark Liversedge
2014-12-05 15:33:19 +00:00
parent a61c1e3217
commit f87adaa89a
2 changed files with 275 additions and 0 deletions

211
src/RideCache.cpp Normal file
View File

@@ -0,0 +1,211 @@
/*
* Copyright (c) 2014 Mark Liversedge (liversedge@gmail.com)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "RideCache.h"
#include "Context.h"
#include "Athlete.h"
#include "Route.h"
#include "RouteWindow.h"
RideCache::RideCache(Context *context) : context(context)
{
// set the list
// populate ride list
RideItem *last = NULL;
QStringListIterator i(RideFileFactory::instance().listRideFiles(context->athlete->home->activities()));
while (i.hasNext()) {
QString name = i.next();
QDateTime dt;
if (RideFile::parseRideFileName(name, &dt)) {
last = new RideItem(context->athlete->home->activities().canonicalPath(), name, dt, context);
rides_ << last;
}
}
// load the store - will unstale once cache restored
load();
// do we have any stale items ?
refresh();
}
RideCache::~RideCache()
{
// save to store
save();
}
// add a new ride
void
RideCache::addRide(QString name, bool dosignal)
{
// ignore malformed names
QDateTime dt;
if (!RideFile::parseRideFileName(name, &dt)) return;
// new ride item
RideItem *last = new RideItem(context->athlete->home->activities().canonicalPath(), name, dt, context);
// now add to the list, or replace if already there
bool added = false;
for (int index=0; index < rides_.count(); index++) {
if (rides_[index]->fileName == last->fileName) {
rides_[index] = last;
break;
}
}
if (!added) rides_ << last;
qSort(rides_); // sort by date
// refresh metrics for *this ride only*
// XXX not implemented yet XXX
if (dosignal) context->notifyRideAdded(last); // here so emitted BEFORE rideSelected is emitted!
//Search routes
context->athlete->routes->searchRoutesInRide(last->ride());
// notify everyone to select it
context->ride = last;
context->notifyRideSelected(last);
}
void
RideCache::removeCurrentRide()
{
if (context->ride == NULL) return;
RideItem *select = NULL; // ride to select once its gone
RideItem *todelete = context->ride;
bool found = false;
int index=0; // index to wipe out
// find ours in the list and select the one
// immediately after it, but if it is the last
// one on the list select the one before
for(index=0; index < rides_.count(); index++) {
if (rides_[index]->fileName == context->ride->fileName) {
// bingo!
found = true;
if (rides_.count()-index > 1) select = rides_[index+1];
else if (index > 0) select = rides_[index-1];
break;
}
}
// WTAF!?
if (!found) {
qDebug()<<"ERROR: delete not found.";
return;
}
// remove from the cache, before deleting it this is so
// any aggregating functions no longer see it, when recalculating
// during aride deleted operation
rides_.remove(index, 1);
// delete the file by renaming it
QString strOldFileName = context->ride->fileName;
QFile file(context->athlete->home->activities().canonicalPath() + "/" + strOldFileName);
// purposefully don't remove the old ext so the user wouldn't have to figure out what the old file type was
QString strNewName = strOldFileName + ".bak";
// in case there was an existing bak file, delete it
// ignore errors since it probably isn't there.
QFile::remove(context->athlete->home->activities().canonicalPath() + "/" + strNewName);
if (!file.rename(context->athlete->home->activities().canonicalPath() + "/" + strNewName)) {
QMessageBox::critical(NULL, "Rename Error", tr("Can't rename %1 to %2")
.arg(strOldFileName).arg(strNewName));
}
// remove any other derived/additional files; notes, cpi etc
QStringList extras;
extras << "notes" << "cpi" << "cpx";
foreach (QString extension, extras) {
QString deleteMe = QFileInfo(strOldFileName).baseName() + "." + extension;
QFile::remove(context->athlete->home->activities().canonicalPath() + "/" + deleteMe);
}
// rename also the source files either in /imports or in /downloads to allow a second round of import
QString sourceFilename = todelete->ride()->getTag("Source Filename", "");
if (sourceFilename != "") {
// try to rename in both directories /imports and /downloads
// but don't report any errors - files may have been backup already
QFile old1 (context->athlete->home->imports().canonicalPath() + "/" + sourceFilename);
old1.rename(context->athlete->home->imports().canonicalPath() + "/" + sourceFilename + ".bak");
QFile old2 (context->athlete->home->downloads().canonicalPath() + "/" + sourceFilename);
old2.rename(context->athlete->home->downloads().canonicalPath() + "/" + sourceFilename + ".bak");
}
// we don't want the whole delete, select next flicker
context->mainWindow->setUpdatesEnabled(false);
// select a different ride
context->ride = select;
// notify AFTER deleted from DISK..
context->notifyRideDeleted(todelete);
// ..but before MEMORY cleared
todelete->freeMemory();
delete todelete;
// now we can update
context->mainWindow->setUpdatesEnabled(true);
QApplication::processEvents();
// now select another ride
context->notifyRideSelected(select);
}
// work with "rideDB.json" XXX not implemented yet
void RideCache::load() {}
void RideCache::save() {}
// refresh the metrics XXX not implemented yet
void
RideCache::refresh()
{
if (isRunning()) return;
else {
bool stale = false;
foreach(RideItem *item, rides_) {
if (item->isstale) {
stale = true;
break;
}
}
if (stale) start();
}
}
void RideCache::run()
{
//XXX not implemented but where metrics and meta get refreshed.
}

64
src/RideCache.h Normal file
View File

@@ -0,0 +1,64 @@
/*
* Copyright (c) 2014 Mark Liversedge (liversedge@gmail.com)
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the Free
* Software Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., 51
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _GC_RideCache_h
#define _GC_RideCache_h 1
#include "GoldenCheetah.h"
#include "MainWindow.h"
#include "RideFile.h"
#include "RideItem.h"
#include <QVector>
#include <QThread>
class Context;
class RideCache : public QThread
{
public:
RideCache(Context *context);
~RideCache();
// the ride list
QVector<RideItem*>&rides() { return rides_; }
// add/remove a ride to the list
void addRide(QString name, bool dosignal);
void removeCurrentRide();
// restore / dump cache to disk (json)
void load();
void save();
// the background refresher !
void refresh(); // calls start() and doesn't wait
// the thread code that gets run to refresh
void run();
protected:
private:
Context *context;
QVector<RideItem*> rides_;
};
#endif // _GC_RideCache_h