diff --git a/src/EditUserMetricDialog.cpp b/src/EditUserMetricDialog.cpp index e46597426..c99cb2bf7 100644 --- a/src/EditUserMetricDialog.cpp +++ b/src/EditUserMetricDialog.cpp @@ -255,6 +255,7 @@ EditUserMetricDialog::EditUserMetricDialog(Context *context, UserMetricSettings mainLayout->addLayout(head); connect(test, SIGNAL(clicked()), this, SLOT(refreshStats())); + connect(context, SIGNAL(rideSelected(RideItem*)), this, SLOT(refreshStats())); connect (cancelButton, SIGNAL(clicked()), this, SLOT(reject())); connect (okButton, SIGNAL(clicked()), this, SLOT(okClicked())); } diff --git a/src/RideMetric.h b/src/RideMetric.h index 93317b6af..f649c8d04 100644 --- a/src/RideMetric.h +++ b/src/RideMetric.h @@ -206,11 +206,15 @@ class UserMetric: public RideMetric { public: UserMetric(Context *context, UserMetricSettings settings); + UserMetric(const UserMetric *from); ~UserMetric(); // is this a user defined one? bool isUser() const { return true; } + // did we clone (i.e. datafilter doesn't belong to us) + bool isClone() const { return clone_; } + void initialize(); QString symbol() const; @@ -257,6 +261,8 @@ public: // is a time value, ie. render as hh:mm:ss bool isTime() const; + RideMetric *clone() const; + // WE DO NOT REIMPLEMENT THE STANDARD toString() METHOD // virtual QString toString(bool useMetricUnits) const; @@ -273,6 +279,9 @@ public: // and we compile into this for runtime DataFilter *program; + // true if we are a clone + bool clone_; + }; class RideMetricFactory { diff --git a/src/UserMetric.cpp b/src/UserMetric.cpp index 4fb66d8db..e4ae343c8 100644 --- a/src/UserMetric.cpp +++ b/src/UserMetric.cpp @@ -1,4 +1,5 @@ /* + return new UserMetric(this); * Copyright (c) 2015 Mark Liversedge (liversedge@gmail.com) * * This program is free software; you can redistribute it and/or modify it @@ -26,11 +27,29 @@ UserMetric::UserMetric(Context *context, UserMetricSettings settings) { // compile the program - built in a context that can close. program = new DataFilter(NULL, context, settings.program); + + // we're not a clone, we're the original + clone_ = false; +} + +UserMetric::UserMetric(const UserMetric *here) +{ + this->settings = here->settings; + this->program = here->program; + + // we are being cloned + clone_ = true; } UserMetric::~UserMetric() { - if (program) delete program; + if (!clone_ && program) delete program; +} + +RideMetric * +UserMetric::clone() const +{ + return new UserMetric(this); } void @@ -131,7 +150,6 @@ UserMetric::isRelevantForRide(const RideItem *item) const if (item->context && program->root()) { if (program->functions.contains("relevant")) { Result res = program->root()->eval(program, program->functions.value("relevant"), 0, const_cast(item), NULL); -qDebug()<<"CALLING USER METHOD FOR RELEVANT!"; return res.number; } else return true; @@ -141,14 +159,50 @@ qDebug()<<"CALLING USER METHOD FOR RELEVANT!"; // Compute the ride metric from a file. void -UserMetric::compute(RideItem *item, Specification spec, const QHash &deps) +UserMetric::compute(RideItem *item, Specification spec, const QHash &) { - // XXX todo - // relevant ? - // init ? - // samples ? + QTime timer; + timer.start(); + +qDebug()<<"INIT"; + // always init first + if (program->functions.contains("init")) + program->root()->eval(program, program->functions.value("init"), 0, const_cast(item), NULL); + +qDebug()<<"CHECK"; + // can it provide a value and is it relevant ? + if (!program->functions.contains("value") || !isRelevantForRide(item)) { + setValue(RideFile::NIL); + setCount(0); + return; + } + +qDebug()<<"SAMPLE"; + // process samples, if there are any and a function exists + if (!spec.isEmpty(item->ride()) && program->functions.contains("sample")) { + RideFileIterator it(item->ride(), spec); + + while(it.hasNext()) { + struct RideFilePoint *point = it.next(); + program->root()->eval(program, program->functions.value("sample"), 0, const_cast(item), point); + } + } + +qDebug()<<"VALUE"; // value ? + if (program->functions.contains("value")) { + Result v = program->root()->eval(program, program->functions.value("value"), 0, const_cast(item), NULL); + setValue(v.number); + } + +qDebug()<<"COUNT"; // count? + if (program->functions.contains("count")) { + Result c = program->root()->eval(program, program->functions.value("count"), 0, const_cast(item), NULL); + setCount(c.number); + } + +qDebug()<<"ELAPSED="<