From e2deb1fc993646cd3f8c6df7fe08af8a10902b15 Mon Sep 17 00:00:00 2001 From: Sean Rhea Date: Mon, 18 Jan 2010 11:54:42 -0800 Subject: [PATCH] extract core functionality into static function ...so that we can use BestIntervalDialog::findBests elsewhere in the code. --- src/BestIntervalDialog.cpp | 102 +++++++++++++++++++------------------ src/BestIntervalDialog.h | 11 ++++ 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/src/BestIntervalDialog.cpp b/src/BestIntervalDialog.cpp index 57a268d8a..eef6d325b 100644 --- a/src/BestIntervalDialog.cpp +++ b/src/BestIntervalDialog.cpp @@ -117,15 +117,9 @@ intervalDuration(const RideFilePoint *start, const RideFilePoint *stop, const Ri return stop->secs - start->secs + ride->recIntSecs(); } -struct BestInterval -{ - double start, stop, avg; - BestInterval(double start, double stop, double avg) : - start(start), stop(stop), avg(avg) {} -}; - static bool -intervalsOverlap(const BestInterval &a, const BestInterval &b) +intervalsOverlap(const BestIntervalDialog::BestInterval &a, + const BestIntervalDialog::BestInterval &b) { if ((a.start <= b.start) && (a.stop > b.start)) return true; @@ -136,7 +130,8 @@ intervalsOverlap(const BestInterval &a, const BestInterval &b) struct CompareBests { // Sort by decreasing power and increasing start time. - bool operator()(const BestInterval &a, const BestInterval &b) const { + bool operator()(const BestIntervalDialog::BestInterval &a, + const BestIntervalDialog::BestInterval &b) const { if (a.avg > b.avg) return true; if (b.avg < a.avg) @@ -165,48 +160,8 @@ BestIntervalDialog::findClicked() return; } - QList window; - QList bests; - - double secsDelta = ride->recIntSecs(); - double totalWatts = 0.0; - - // We're looking for intervals with durations in [windowSizeSecs, windowSizeSecs + secsDelta). - - foreach (const RideFilePoint *point, ride->dataPoints()) { - // Discard points until interval duration is < windowSizeSecs + secsDelta. - while (!window.empty() && (intervalDuration(window.first(), point, ride) >= windowSizeSecs + secsDelta)) { - totalWatts -= window.first()->watts; - window.takeFirst(); - } - // Add points until interval duration is >= windowSizeSecs. - totalWatts += point->watts; - window.append(point); - double duration = intervalDuration(window.first(), window.last(), ride); - assert(duration < windowSizeSecs + secsDelta); - if (duration >= windowSizeSecs) { - double start = window.first()->secs; - double stop = start + duration; - double avg = totalWatts * secsDelta / duration; - bests.append(BestInterval(start, stop, avg)); - } - } - - std::sort(bests.begin(), bests.end(), CompareBests()); - QList results; - while (!bests.empty() && (results.size() < maxIntervals)) { - BestInterval candidate = bests.takeFirst(); - bool overlaps = false; - foreach (const BestInterval &existing, results) { - if (intervalsOverlap(candidate, existing)) { - overlaps = true; - break; - } - } - if (!overlaps) - results.append(candidate); - } + findBests(ride, windowSizeSecs, maxIntervals, results); // clear the table clearResultsTable(resultsTable); @@ -291,6 +246,53 @@ BestIntervalDialog::findClicked() resultsTable->setColumnWidth(2,200); } +void +BestIntervalDialog::findBests(const RideFile *ride, double windowSizeSecs, + int maxIntervals, QList &results) +{ + QList bests; + + double secsDelta = ride->recIntSecs(); + double totalWatts = 0.0; + QList window; + + // We're looking for intervals with durations in [windowSizeSecs, windowSizeSecs + secsDelta). + foreach (const RideFilePoint *point, ride->dataPoints()) { + // Discard points until interval duration is < windowSizeSecs + secsDelta. + while (!window.empty() && (intervalDuration(window.first(), point, ride) >= windowSizeSecs + secsDelta)) { + totalWatts -= window.first()->watts; + window.takeFirst(); + } + // Add points until interval duration is >= windowSizeSecs. + totalWatts += point->watts; + window.append(point); + double duration = intervalDuration(window.first(), window.last(), ride); + assert(duration < windowSizeSecs + secsDelta); + if (duration >= windowSizeSecs) { + double start = window.first()->secs; + double stop = start + duration; + double avg = totalWatts * secsDelta / duration; + bests.append(BestInterval(start, stop, avg)); + } + } + + std::sort(bests.begin(), bests.end(), CompareBests()); + + while (!bests.empty() && (results.size() < maxIntervals)) { + BestInterval candidate = bests.takeFirst(); + bool overlaps = false; + foreach (const BestInterval &existing, results) { + if (intervalsOverlap(candidate, existing)) { + overlaps = true; + break; + } + } + if (!overlaps) + results.append(candidate); + } + +} + void BestIntervalDialog::doneClicked() { diff --git a/src/BestIntervalDialog.h b/src/BestIntervalDialog.h index 9b46ebd8a..aee052341 100644 --- a/src/BestIntervalDialog.h +++ b/src/BestIntervalDialog.h @@ -22,14 +22,25 @@ #include class MainWindow; +class RideFile; class BestIntervalDialog : public QDialog { Q_OBJECT public: + + struct BestInterval { + double start, stop, avg; + BestInterval(double start, double stop, double avg) : + start(start), stop(stop), avg(avg) {} + }; + BestIntervalDialog(MainWindow *mainWindow); + static void findBests(const RideFile *ride, double windowSizeSecs, + int maxIntervals, QList &results); + private slots: void findClicked(); void doneClicked();