From 8a3e35b880b6ef5adf04ff4e122f42319e4d1d5a Mon Sep 17 00:00:00 2001 From: Mark Liversedge Date: Mon, 4 May 2015 18:17:33 +0100 Subject: [PATCH] IntervalItem::refresh() Computes the metrics for an interval and creates a temporary ridefile locally so you don't have to. .. previous design should have pushed this into the class instead of performing it in RideItem .. now there should be no reason to create a ridefile during interval discovery. --- src/IntervalItem.cpp | 56 ++++++++++++++++++++++++++++++++++++++++++++ src/IntervalItem.h | 1 + src/RideFile.cpp | 8 ++++++- src/RideFile.h | 1 + src/RideItem.cpp | 54 +++--------------------------------------- src/RideItem.h | 1 + 6 files changed, 69 insertions(+), 52 deletions(-) diff --git a/src/IntervalItem.cpp b/src/IntervalItem.cpp index 0f8ebe846..f64f23c44 100644 --- a/src/IntervalItem.cpp +++ b/src/IntervalItem.cpp @@ -18,6 +18,8 @@ #include "IntervalItem.h" #include "RideFile.h" +#include "Context.h" +#include "Athlete.h" IntervalItem::IntervalItem(const RideFile *ride, QString name, double start, double stop, double startKM, double stopKM, int displaySequence, @@ -48,6 +50,60 @@ IntervalItem::setFrom(IntervalItem &other) *this = other; } +void +IntervalItem::refresh() +{ + // don't open on our account - we should be called with a ride available + RideFile *f = rideItem_->ride_; + if (!f) return; + + // create a temporary ride + RideFile intervalRide(f); + for (int i = f->intervalBeginSecs(start); i>= 0 &&i < f->dataPoints().size(); ++i) { + + // iterate + const RideFilePoint *p = f->dataPoints()[i]; + if (p->secs > stop) break; + + // append all values + intervalRide.appendPoint(p->secs, p->cad, p->hr, p->km, p->kph, p->nm, + p->watts, p->alt, p->lon, p->lat, p->headwind, + p->slope, p->temp, p->lrbalance, + p->lte, p->rte, p->lps, p->rps, + p->lpco, p->rpco, p->lppb, p->rppb, p->lppe, p->rppe, p->lpppb, p->rpppb, p->lpppe, p->rpppe, + p->smo2, p->thb, p->rvert, p->rcad, p->rcontact, 0); + + // copy derived data + RideFilePoint *l = intervalRide.dataPoints().last(); + l->np = p->np; + l->xp = p->xp; + l->apower = p->apower; + } + + // we created a blank ride (?) + if (intervalRide.dataPoints().size() == 0) return; + + // ok, lets collect the metrics + const RideMetricFactory &factory = RideMetricFactory::instance(); + QHash computed= RideMetric::computeMetrics(rideItem_->context, &intervalRide, rideItem_->context->athlete->zones(), + rideItem_->context->athlete->hrZones(), factory.allMetrics()); + + // pack the metrics away and clean up if needed + metrics_.fill(0, factory.metricCount()); + + // snaffle away all the computed values into the array + QHashIterator i(computed); + while (i.hasNext()) { + i.next(); + metrics_[i.value()->index()] = i.value()->value(); + } + + // clean any bad values + for(int j=0; j metrics_; QVector &metrics() { return metrics_; } diff --git a/src/RideFile.cpp b/src/RideFile.cpp index 5bdb9b231..08da36200 100644 --- a/src/RideFile.cpp +++ b/src/RideFile.cpp @@ -369,9 +369,15 @@ struct ComparePointSecs { int RideFile::intervalBegin(const RideFileInterval &interval) const +{ + return intervalBeginSecs(interval.start); +} + +int +RideFile::intervalBeginSecs(const double secs) const { RideFilePoint p; - p.secs = interval.start; + p.secs = secs; QVector::const_iterator i = std::lower_bound( dataPoints_.begin(), dataPoints_.end(), &p, ComparePointSecs()); if (i == dataPoints_.end()) diff --git a/src/RideFile.h b/src/RideFile.h index 8dca7472c..acc71037d 100644 --- a/src/RideFile.h +++ b/src/RideFile.h @@ -260,6 +260,7 @@ class RideFile : public QObject // QObject to emit signals void clearIntervals(); void fillInIntervals(); int intervalBegin(const RideFileInterval &interval) const; + int intervalBeginSecs(const double secs) const; // Working with CAIBRATIONS const QList &calibrations() const { return calibrations_; } diff --git a/src/RideItem.cpp b/src/RideItem.cpp index 3fa6f55d1..38eb4fe40 100644 --- a/src/RideItem.cpp +++ b/src/RideItem.cpp @@ -555,9 +555,6 @@ RideItem::updateIntervals() // add those automatically for HR and Power where those // data series are present - // get metric factory - const RideMetricFactory &factory = RideMetricFactory::instance(); - // ride start and end RideFilePoint *begin = f->dataPoints().first(); RideFilePoint *end = f->dataPoints().last(); @@ -575,6 +572,7 @@ RideItem::updateIntervals() entire->rideItem_ = this; intervals_ << entire; + int count = 1; foreach(RideFileInterval interval, f->intervals()) { // skip peaks, they're autodiscovered now @@ -589,37 +587,6 @@ RideItem::updateIntervals() // skip empty backward intervals if (interval.start >= interval.stop) continue; - // create a temporary ride - RideFile intervalRide(f); - int count = 1; - for (int i = f->intervalBegin(interval); i>= 0 &&i < f->dataPoints().size(); ++i) { - - // iterate - const RideFilePoint *p = f->dataPoints()[i]; - if (p->secs > interval.stop) break; - - // append all values - intervalRide.appendPoint(p->secs, p->cad, p->hr, p->km, p->kph, p->nm, - p->watts, p->alt, p->lon, p->lat, p->headwind, - p->slope, p->temp, p->lrbalance, - p->lte, p->rte, p->lps, p->rps, - p->lpco, p->rpco, p->lppb, p->rppb, p->lppe, p->rppe, p->lpppb, p->rpppb, p->lpppe, p->rpppe, - p->smo2, p->thb, p->rvert, p->rcad, p->rcontact, 0); - - // copy derived data - RideFilePoint *l = intervalRide.dataPoints().last(); - l->np = p->np; - l->xp = p->xp; - l->apower = p->apower; - } - - // we created a blank ride (?) - if (intervalRide.dataPoints().size() == 0) continue; - - // ok, lets collect the metrics - QHash computed= RideMetric::computeMetrics(context, &intervalRide, context->athlete->zones(), - context->athlete->hrZones(), factory.allMetrics()); - // create a new interval item IntervalItem *intervalItem = new IntervalItem(f, interval.name, interval.start, interval.stop, @@ -627,25 +594,10 @@ RideItem::updateIntervals() f->timeToDistance(interval.stop), count++, // sequence defaults to count RideFileInterval::USER); - intervalItem->rideItem_ = this; + intervalItem->rideItem_ = this; // XXX will go when we refactor and be passed instead of ridefile + intervalItem->refresh(); // XXX will get called in constructore when refactor intervals_ << intervalItem; - // pack the metrics away and clean up if needed - intervalItem->metrics_.fill(0, factory.metricCount()); - - // snaffle away all the computed values into the array - QHashIterator i(computed); - while (i.hasNext()) { - i.next(); - intervalItem->metrics_[i.value()->index()] = i.value()->value(); - } - - // clean any bad values - for(int j=0; jmetrics_[j] = 0.00f; - - // debug //qDebug()<<"interval:"<secs<secs; } diff --git a/src/RideItem.h b/src/RideItem.h index b89815d2a..536a6ecb0 100644 --- a/src/RideItem.h +++ b/src/RideItem.h @@ -47,6 +47,7 @@ class RideItem : public QObject friend class ::RideCache; friend class ::RideCacheModel; + friend class ::IntervalItem; // ridefile RideFile *ride_;