diff --git a/src/Core/Athlete.cpp b/src/Core/Athlete.cpp index b4ba64006..c60052042 100644 --- a/src/Core/Athlete.cpp +++ b/src/Core/Athlete.cpp @@ -58,7 +58,6 @@ Athlete::Athlete(Context *context, const QDir &homeDir) { -fprintf(stderr, "new athlete preamble...\n"); fflush(stderr); // athlete name / structured directory this->home = new AthleteDirectoryStructure(homeDir); this->context = context; diff --git a/src/Core/RideCache.cpp b/src/Core/RideCache.cpp index 57065919b..678957570 100644 --- a/src/Core/RideCache.cpp +++ b/src/Core/RideCache.cpp @@ -124,12 +124,12 @@ RideCache::RideCache(Context *context) : context(context) } } + // now sort it - we need to use find on it + qSort(rides_.begin(), rides_.end(), rideCacheLessThan); + // load the store - will unstale once cache restored load(); - // now sort it - qSort(rides_.begin(), rides_.end(), rideCacheLessThan); - // set model once we have the basics model_ = new RideCacheModel(context, this); @@ -152,6 +152,20 @@ RideCache::RideCache(Context *context) : context(context) connect(&watcher, SIGNAL(progressValueChanged(int)), this, SLOT(progressing(int))); } +struct comparerideitem { bool operator()(const RideItem *p1, const RideItem *p2) { return p1->dateTime < p2->dateTime; } }; + +int +RideCache::find(RideItem *dt) +{ + // use lower_bound to binary search + QVector::const_iterator i = std::lower_bound(rides_.begin(), rides_.end(), dt, comparerideitem()); + int index = i - rides_.begin(); + + // did it find the right value? + if (index < 0 || index >= rides_.count() || rides_.at(index)->dateTime != dt->dateTime) return -1; + return index; +} + RideCache::~RideCache() { exiting = true; diff --git a/src/Core/RideCache.h b/src/Core/RideCache.h index 305490cd1..e167726f3 100644 --- a/src/Core/RideCache.h +++ b/src/Core/RideCache.h @@ -102,6 +102,9 @@ class RideCache : public QObject void load(); void save(bool opendata=false, QString filename=""); + // find entry quickly + int find(RideItem *); + // user updated options/preferences void configChanged(qint32); diff --git a/src/Core/RideDB.l b/src/Core/RideDB.l index 4b10c3cc2..a0e4e3592 100644 --- a/src/Core/RideDB.l +++ b/src/Core/RideDB.l @@ -39,19 +39,44 @@ // Un-Escape special characters (JSON compliance) static QString unprotect(char *string) { - // sending UTF-8 to FLEX demands symetric conversion back to QString - QString string2 = QString::fromUtf8(string); - // this is a lexer string so it will be enclosed - // in quotes. Lets strip those first - QStringRef r = string2.midRef(1,string2.length()-2); + char *s = string; + char *target = static_cast(malloc(strlen(string)+1)); + char *p = target; - // does it end with a space (to avoid token conflict) ? - if (r.endsWith(" ")) r = r.mid(0, r.length()-1); + // first " + s++; - QString s = Utils::RidefileUnEscape(r); + while (*s != '\0') { + if (*s == '\\') { + switch(*++s) { + case '\\' : *p++ = '\\'; break; + case 't' : *p++ = '\t'; break; + case 'n' : *p++ = '\n'; break; + case 'r' : *p++ = '\r'; break; + case 'b' : *p++ = '\b'; break; + case 'f' : *p++ = '\f'; break; + case '/' : *p++ = '/'; break; + case '"' : *p++ = '"'; break; + default: + *p++ = '\\'; *p++ = *s; + } + } else *p++ = *s; + s++; + } - return s; + // trailing " + p--; + + // trailing SINGLE space used to protect tokens + *p-- = '\0'; + if(p>=target && *p == ' ') *p = '\0'; + + // as a qstring + QString r = QString::fromUtf8(target); + free(target); + + return r; } // we reimplement these to remove compiler warnings diff --git a/src/Core/RideDB.y b/src/Core/RideDB.y index 0ac558d16..e2b63cc0d 100644 --- a/src/Core/RideDB.y +++ b/src/Core/RideDB.y @@ -83,33 +83,21 @@ ride: '{' rideelement_list '}' { #endif } else { - // we're loading the cache - bool found = false; - foreach(RideItem *i, jc->cache->rides()) { - if (i->fileName == jc->item.fileName) { + double progress= double(jc->loading++) / double(jc->cache->rides().count()) * 100.0f; + if (jc->context->mainWindow->progress) { - found = true; - - // progress update - double progress= double(jc->loading++) / double(jc->cache->rides().count()) * 100.0f; - if (jc->context->mainWindow->progress) { - - // percentage progress - QString m = QString("%1%").arg(progress , 0, 'f', 0); - jc->context->mainWindow->progress->setText(m); - QApplication::processEvents(); - } else { - jc->context->notifyLoadProgress(jc->folder,progress); - } - - // update from our loaded value - i->setFrom(jc->item); - break; - } + // percentage progress + QString m = QString("%1%").arg(progress , 0, 'f', 0); + jc->context->mainWindow->progress->setText(m); + QApplication::processEvents(); + } else { + jc->context->notifyLoadProgress(jc->folder,progress); } - // not found ! - if (found == false) - qDebug()<<"unable to load:"<item.fileName<item.dateTime<item.weight; + + // find entry and update it + int index=jc->cache->find(&jc->item); + if (index==-1) qDebug()<<"unable to load:"<item.fileName<item.dateTime<item.weight; + else jc->cache->rides().at(index)->setFrom(jc->item); } // now set our ride item clean again, so we don't diff --git a/src/Core/RideItem.h b/src/Core/RideItem.h index b5f76818b..305d32fe0 100644 --- a/src/Core/RideItem.h +++ b/src/Core/RideItem.h @@ -95,6 +95,8 @@ class RideItem : public QObject public: + bool operator==(RideItem &other) { return other.dateTime == dateTime; } + Context *context; // to notify widgets when date/time changes bool isdirty; // ride data has changed and needs saving bool isstale; // metric data is out of date and needs recomputing diff --git a/src/Gui/AthleteView.cpp b/src/Gui/AthleteView.cpp index 7827a58b4..38b3e7c67 100644 --- a/src/Gui/AthleteView.cpp +++ b/src/Gui/AthleteView.cpp @@ -84,6 +84,22 @@ AthleteCard::AthleteCard(ChartSpace *parent, QString path) : ChartSpaceItem(pare painter.drawEllipse(0, 0, img.width(), img.height()); avatar = canvas.toImage(); +#if 0 + // ridecache raw + if (loadprogress == 0) { + QTime timer; + timer.start(); + QFile rideDB(gcroot + "/" + path + "/cache/rideDB.json"); + if (rideDB.exists() && rideDB.open(QFile::ReadOnly)) { + + QByteArray contents = rideDB.readAll(); + rideDB.close(); + QJsonDocument json = QJsonDocument::fromJson(contents); + } + fprintf(stderr, "'%s' read rideDB took %d usecs\n", path.toStdString().c_str(), timer.elapsed()); fflush(stderr); + } +#endif + } void