diff --git a/src/DataFilter.cpp b/src/DataFilter.cpp index b130f2850..90e4c697e 100644 --- a/src/DataFilter.cpp +++ b/src/DataFilter.cpp @@ -1293,12 +1293,12 @@ Result DataFilter::evaluate(RideItem *item, RideFilePoint *p) // ... start at main if (functions.contains("main")) - res = treeRoot->eval(context, this, functions.value("main"), 0, item, p); + res = treeRoot->eval(this, functions.value("main"), 0, item, p); } else { // otherwise just evaluate the entire tree - res = treeRoot->eval(context, this, treeRoot, 0, item, p); + res = treeRoot->eval(this, treeRoot, 0, item, p); } return res; @@ -1336,7 +1336,7 @@ QStringList DataFilter::check(QString query) return errors; } -QStringList DataFilter::parseFilter(QString query, QStringList *list) +QStringList DataFilter::parseFilter(Context *context, QString query, QStringList *list) { // remember where we apply this->list = list; @@ -1390,7 +1390,7 @@ QStringList DataFilter::parseFilter(QString query, QStringList *list) foreach(RideItem *item, context->athlete->rideCache->rides()) { // evaluate each ride... - Result result = treeRoot->eval(context, this, treeRoot, 0, item, NULL); + Result result = treeRoot->eval(this, treeRoot, 0, item, NULL); if (result.isNumber && result.number) { filenames << item->fileName; } @@ -1416,7 +1416,7 @@ DataFilter::dynamicParse() foreach(RideItem *item, context->athlete->rideCache->rides()) { // evaluate each ride... - Result result = treeRoot->eval(context, this, treeRoot, 0, item, NULL); + Result result = treeRoot->eval(this, treeRoot, 0, item, NULL); if (result.isNumber && result.number) filenames << item->fileName; } @@ -1469,7 +1469,7 @@ void DataFilter::configChanged(qint32) dataSeriesSymbols = RideFile::symbols(); } -Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideItem *m, RideFilePoint *p) +Result Leaf::eval(DataFilter *df, Leaf *leaf, float x, RideItem *m, RideFilePoint *p) { // if error state all bets are off if (inerror) return Result(0); @@ -1484,26 +1484,26 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte switch (leaf->op) { case AND : { - Result left = eval(context, df, leaf->lvalue.l, x, m, p); + Result left = eval(df, leaf->lvalue.l, x, m, p); if (left.isNumber && left.number) { - Result right = eval(context, df, leaf->rvalue.l, x, m, p); + Result right = eval(df, leaf->rvalue.l, x, m, p); if (right.isNumber && right.number) return Result(true); } return Result(false); } case OR : { - Result left = eval(context, df, leaf->lvalue.l, x, m, p); + Result left = eval(df, leaf->lvalue.l, x, m, p); if (left.isNumber && left.number) return Result(true); - Result right = eval(context, df, leaf->rvalue.l, x, m, p); + Result right = eval(df, leaf->rvalue.l, x, m, p); if (right.isNumber && right.number) return Result(true); return Result(false); } default : // parenthesis - return (eval(context, df, leaf->lvalue.l, x, m, p)); + return (eval(df, leaf->lvalue.l, x, m, p)); } } break; @@ -1528,7 +1528,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte return Result(0); } - Result res = eval(context, df, df->functions.value(leaf->function), x, m, p); + Result res = eval(df, df->functions.value(leaf->function), x, m, p); // pop stack - if we haven't overflowed and reset if (df->stack > 0) df->stack -= 1; @@ -1546,13 +1546,13 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte double PMAX = 0; int zoneRange; - if (context->athlete->zones()) { + if (m->context->athlete->zones()) { // if range is -1 we need to fall back to a default value - zoneRange = context->athlete->zones()->whichRange(m->dateTime.date()); - CP = zoneRange >= 0 ? context->athlete->zones()->getCP(zoneRange) : 0; - WPRIME = zoneRange >= 0 ? context->athlete->zones()->getWprime(zoneRange) : 0; - PMAX = zoneRange >= 0 ? context->athlete->zones()->getPmax(zoneRange) : 0; + zoneRange = m->context->athlete->zones()->whichRange(m->dateTime.date()); + CP = zoneRange >= 0 ? m->context->athlete->zones()->getCP(zoneRange) : 0; + WPRIME = zoneRange >= 0 ? m->context->athlete->zones()->getWprime(zoneRange) : 0; + PMAX = zoneRange >= 0 ? m->context->athlete->zones()->getPmax(zoneRange) : 0; // did we override CP in metadata ? int oCP = m->getText("CP","0").toInt(); @@ -1566,41 +1566,41 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte // // LTHR, MaxHR, RHR // - int hrZoneRange = context->athlete->hrZones() ? - context->athlete->hrZones()->whichRange(m->dateTime.date()) + int hrZoneRange = m->context->athlete->hrZones() ? + m->context->athlete->hrZones()->whichRange(m->dateTime.date()) : -1; - int LTHR = hrZoneRange != -1 ? context->athlete->hrZones()->getLT(hrZoneRange) : 0; - int RHR = hrZoneRange != -1 ? context->athlete->hrZones()->getRestHr(hrZoneRange) : 0; - int MaxHR = hrZoneRange != -1 ? context->athlete->hrZones()->getMaxHr(hrZoneRange) : 0; + int LTHR = hrZoneRange != -1 ? m->context->athlete->hrZones()->getLT(hrZoneRange) : 0; + int RHR = hrZoneRange != -1 ? m->context->athlete->hrZones()->getRestHr(hrZoneRange) : 0; + int MaxHR = hrZoneRange != -1 ? m->context->athlete->hrZones()->getMaxHr(hrZoneRange) : 0; // // CV' D' // - int paceZoneRange = context->athlete->paceZones(false) ? - context->athlete->paceZones(false)->whichRange(m->dateTime.date()) : + int paceZoneRange = m->context->athlete->paceZones(false) ? + m->context->athlete->paceZones(false)->whichRange(m->dateTime.date()) : -1; - double CV = (paceZoneRange != -1) ? context->athlete->paceZones(false)->getCV(paceZoneRange) : 0.0; - double DPRIME = 0; //XXX(paceZoneRange != -1) ? context->athlete->paceZones(false)->getDPrime(paceZoneRange) : 0.0; + double CV = (paceZoneRange != -1) ? m->context->athlete->paceZones(false)->getCV(paceZoneRange) : 0.0; + double DPRIME = 0; //XXX(paceZoneRange != -1) ? m->context->athlete->paceZones(false)->getDPrime(paceZoneRange) : 0.0; - int spaceZoneRange = context->athlete->paceZones(true) ? - context->athlete->paceZones(true)->whichRange(m->dateTime.date()) : + int spaceZoneRange = m->context->athlete->paceZones(true) ? + m->context->athlete->paceZones(true)->whichRange(m->dateTime.date()) : -1; - double SCV = (spaceZoneRange != -1) ? context->athlete->paceZones(true)->getCV(spaceZoneRange) : 0.0; - double SDPRIME = 0; //XXX (spaceZoneRange != -1) ? context->athlete->paceZones(true)->getDPrime(spaceZoneRange) : 0.0; + double SCV = (spaceZoneRange != -1) ? m->context->athlete->paceZones(true)->getCV(spaceZoneRange) : 0.0; + double SDPRIME = 0; //XXX (spaceZoneRange != -1) ? m->context->athlete->paceZones(true)->getDPrime(spaceZoneRange) : 0.0; // // HEIGHT and WEIGHT // double HEIGHT = m->getText("Height","0").toDouble(); - if (HEIGHT == 0) HEIGHT = context->athlete->getHeight(NULL); + if (HEIGHT == 0) HEIGHT = m->context->athlete->getHeight(NULL); double WEIGHT = m->getWeight(); QString symbol = leaf->series->lvalue.n->toLower(); if (symbol == "cranklength") { - return Result(appsettings->cvalue(context->athlete->cyclist, GC_CRANKLENGTH, 175.00f).toDouble() / 1000.0); + return Result(appsettings->cvalue(m->context->athlete->cyclist, GC_CRANKLENGTH, 175.00f).toDouble() / 1000.0); } if (symbol == "cp") { @@ -1640,7 +1640,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte return Result(HEIGHT); } if (symbol == "units") { - return Result(context->athlete->useMetricUnits ? 1 : 0); + return Result(m->context->athlete->useMetricUnits ? 1 : 0); } } @@ -1652,7 +1652,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte default: case Leaf::Function : { - duration = eval(context, df, leaf->lvalue.l, x, m, p).number; // duration will be zero if string + duration = eval(df, leaf->lvalue.l, x, m, p).number; // duration will be zero if string } break; @@ -1687,10 +1687,10 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte } if (leaf->function == "best") - return Result(RideFileCache::best(df->context, m->fileName, leaf->seriesType, duration)); + return Result(RideFileCache::best(m->context, m->fileName, leaf->seriesType, duration)); if (leaf->function == "tiz") // duration is really zone number - return Result(RideFileCache::tiz(df->context, m->fileName, leaf->seriesType, duration)); + return Result(RideFileCache::tiz(m->context, m->fileName, leaf->seriesType, duration)); } // if we get here its general function handling @@ -1713,36 +1713,36 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte if (fnum < 0) return Result(0); switch (fnum) { - case 0 : { return Result(cos(eval(context, df, leaf->fparms[0], x, m, p).number)); } // COS(x) - case 1 : { return Result(tan(eval(context, df, leaf->fparms[0], x, m, p).number)); } // TAN(x) - case 2 : { return Result(sin(eval(context, df, leaf->fparms[0], x, m, p).number)); } // SIN(x) - case 3 : { return Result(acos(eval(context, df, leaf->fparms[0], x, m, p).number)); } // ACOS(x) - case 4 : { return Result(atan(eval(context, df, leaf->fparms[0], x, m, p).number)); } // ATAN(x) - case 5 : { return Result(asin(eval(context, df, leaf->fparms[0], x, m, p).number)); } // ASIN(x) - case 6 : { return Result(cosh(eval(context, df, leaf->fparms[0], x, m, p).number)); } // COSH(x) - case 7 : { return Result(tanh(eval(context, df, leaf->fparms[0], x, m, p).number)); } // TANH(x) - case 8 : { return Result(sinh(eval(context, df, leaf->fparms[0], x, m, p).number)); } // SINH(x) - case 9 : { return Result(acosh(eval(context, df, leaf->fparms[0], x, m, p).number)); } // ACOSH(x) - case 10 : { return Result(atanh(eval(context, df, leaf->fparms[0], x, m, p).number)); } // ATANH(x) - case 11 : { return Result(asinh(eval(context, df, leaf->fparms[0], x, m, p).number)); } // ASINH(x) + case 0 : { return Result(cos(eval(df, leaf->fparms[0], x, m, p).number)); } // COS(x) + case 1 : { return Result(tan(eval(df, leaf->fparms[0], x, m, p).number)); } // TAN(x) + case 2 : { return Result(sin(eval(df, leaf->fparms[0], x, m, p).number)); } // SIN(x) + case 3 : { return Result(acos(eval(df, leaf->fparms[0], x, m, p).number)); } // ACOS(x) + case 4 : { return Result(atan(eval(df, leaf->fparms[0], x, m, p).number)); } // ATAN(x) + case 5 : { return Result(asin(eval(df, leaf->fparms[0], x, m, p).number)); } // ASIN(x) + case 6 : { return Result(cosh(eval(df, leaf->fparms[0], x, m, p).number)); } // COSH(x) + case 7 : { return Result(tanh(eval(df, leaf->fparms[0], x, m, p).number)); } // TANH(x) + case 8 : { return Result(sinh(eval(df, leaf->fparms[0], x, m, p).number)); } // SINH(x) + case 9 : { return Result(acosh(eval(df, leaf->fparms[0], x, m, p).number)); } // ACOSH(x) + case 10 : { return Result(atanh(eval(df, leaf->fparms[0], x, m, p).number)); } // ATANH(x) + case 11 : { return Result(asinh(eval(df, leaf->fparms[0], x, m, p).number)); } // ASINH(x) - case 12 : { return Result(exp(eval(context, df, leaf->fparms[0], x, m, p).number)); } // EXP(x) - case 13 : { return Result(log(eval(context, df, leaf->fparms[0], x, m, p).number)); } // LOG(x) - case 14 : { return Result(log10(eval(context, df, leaf->fparms[0], x, m, p).number)); } // LOG10(x) + case 12 : { return Result(exp(eval(df, leaf->fparms[0], x, m, p).number)); } // EXP(x) + case 13 : { return Result(log(eval(df, leaf->fparms[0], x, m, p).number)); } // LOG(x) + case 14 : { return Result(log10(eval(df, leaf->fparms[0], x, m, p).number)); } // LOG10(x) - case 15 : { return Result(ceil(eval(context, df, leaf->fparms[0], x, m, p).number)); } // CEIL(x) - case 16 : { return Result(floor(eval(context, df, leaf->fparms[0], x, m, p).number)); } // FLOOR(x) - case 17 : { return Result(round(eval(context, df, leaf->fparms[0], x, m, p).number)); } // ROUND(x) + case 15 : { return Result(ceil(eval(df, leaf->fparms[0], x, m, p).number)); } // CEIL(x) + case 16 : { return Result(floor(eval(df, leaf->fparms[0], x, m, p).number)); } // FLOOR(x) + case 17 : { return Result(round(eval(df, leaf->fparms[0], x, m, p).number)); } // ROUND(x) - case 18 : { return Result(fabs(eval(context, df, leaf->fparms[0], x, m, p).number)); } // FABS(x) - case 19 : { return Result(std::isinf(eval(context, df, leaf->fparms[0], x, m, p).number)); } // ISINF(x) - case 20 : { return Result(std::isnan(eval(context, df, leaf->fparms[0], x, m, p).number)); } // ISNAN(x) + case 18 : { return Result(fabs(eval(df, leaf->fparms[0], x, m, p).number)); } // FABS(x) + case 19 : { return Result(std::isinf(eval(df, leaf->fparms[0], x, m, p).number)); } // ISINF(x) + case 20 : { return Result(std::isnan(eval(df, leaf->fparms[0], x, m, p).number)); } // ISNAN(x) case 21 : { /* SUM( ... ) */ double sum=0; foreach(Leaf *l, leaf->fparms) { - sum += eval(context, df, l, x, m, p).number; // for vectors number is sum + sum += eval(df, l, x, m, p).number; // for vectors number is sum } return Result(sum); } @@ -1753,7 +1753,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte int count=0; foreach(Leaf *l, leaf->fparms) { - Result res = eval(context, df, l, x, m, p); // for vectors number is sum + Result res = eval(df, l, x, m, p); // for vectors number is sum sum += res.number; if (res.vector.count()) count += res.vector.count(); else count++; @@ -1767,7 +1767,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte bool set=false; foreach(Leaf *l, leaf->fparms) { - Result res = eval(context, df, l, x, m, p); + Result res = eval(df, l, x, m, p); if (res.vector.count()) { foreach(double x, res.vector) { if (set && x>max) max=x; @@ -1788,7 +1788,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte bool set=false; foreach(Leaf *l, leaf->fparms) { - Result res = eval(context, df, l, x, m, p); + Result res = eval(df, l, x, m, p); if (res.vector.count()) { foreach(double x, res.vector) { if (set && xfparms) { - Result res = eval(context, df, l, x, m, p); + Result res = eval(df, l, x, m, p); if (res.vector.count()) count += res.vector.count(); else count++; } @@ -1817,25 +1817,25 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte break; case 26 : { /* LTS (expr) */ - PMCData *pmcData = context->athlete->getPMCFor(leaf->fparms[0], df); + PMCData *pmcData = m->context->athlete->getPMCFor(leaf->fparms[0], df); return Result(pmcData->lts(m->dateTime.date())); } break; case 27 : { /* STS (expr) */ - PMCData *pmcData = context->athlete->getPMCFor(leaf->fparms[0], df); + PMCData *pmcData = m->context->athlete->getPMCFor(leaf->fparms[0], df); return Result(pmcData->sts(m->dateTime.date())); } break; case 28 : { /* SB (expr) */ - PMCData *pmcData = context->athlete->getPMCFor(leaf->fparms[0], df); + PMCData *pmcData = m->context->athlete->getPMCFor(leaf->fparms[0], df); return Result(pmcData->sb(m->dateTime.date())); } break; case 29 : { /* RR (expr) */ - PMCData *pmcData = context->athlete->getPMCFor(leaf->fparms[0], df); + PMCData *pmcData = m->context->athlete->getPMCFor(leaf->fparms[0], df); return Result(pmcData->rr(m->dateTime.date())); } break; @@ -1854,12 +1854,12 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte // what we looking for ? QString parm = leaf->fparms[1]->type == Leaf::Symbol ? *leaf->fparms[1]->lvalue.n : ""; bool toDuration = parm == "" ? true : false; - double duration = toDuration ? eval(context, df, leaf->fparms[1], x, m, p).number : 0; + double duration = toDuration ? eval(df, leaf->fparms[1], x, m, p).number : 0; // get the PD Estimate for this date - note we always work with the absolulte // power estimates in formulas, since the user can just divide by config(weight) // or Athlete_Weight (which takes into account values stored in ride files. - PDEstimate pde = context->athlete->getPDEstimateFor(m->dateTime.date(), model, false); + PDEstimate pde = m->context->athlete->getPDEstimateFor(m->dateTime.date(), model, false); // no model estimate for this date if (pde.parameters.count() == 0) return Result(0); @@ -1913,7 +1913,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte for(int i=1; i< leaf->fparms.count(); i++) { // evaluate the parameter - Result ex = eval(context, df, leaf->fparms[i], x, m, p); + Result ex = eval(df, leaf->fparms[i], x, m, p); if (ex.vector.count()) { @@ -1921,7 +1921,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte foreach(double x, ex.vector) { // did it get selected? - Result which = eval(context, df, leaf->fparms[0], x, m, p); + Result which = eval(df, leaf->fparms[0], x, m, p); if (which.number) { returning.vector << x; returning.number += x; @@ -1931,7 +1931,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte } else { // does the parameter get selected ? - Result which = eval(context, df, leaf->fparms[0], ex.number, m, p); + Result which = eval(df, leaf->fparms[0], ex.number, m, p); if (which.number) { returning.vector << ex.number; returning.number += ex.number; @@ -1947,7 +1947,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte Result returning(0); if (leaf->fparms.count() < 3) return returning; - else returning = eval(context, df, leaf->fparms[2], x, m, p); + else returning = eval(df, leaf->fparms[2], x, m, p); if (returning.number) { @@ -1965,7 +1965,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte if (!f) return Result(0); // eek! // evaluate second argument, its the value - Result r = eval(context, df, leaf->fparms[1], x, m, p); + Result r = eval(df, leaf->fparms[1], x, m, p); // now set an override or a tag if (o_symbol != "" && e) { // METRIC OVERRIDE @@ -2017,7 +2017,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte Result returning(0); if (leaf->fparms.count() < 2) return returning; - else returning = eval(context, df, leaf->fparms[1], x, m, p); + else returning = eval(df, leaf->fparms[1], x, m, p); if (returning.number) { @@ -2093,7 +2093,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte if (leaf->fparms.count() != 2) return Result(0); - return Result (60*VDOTCalculator::eqvTime(eval(context, df, leaf->fparms[0], x, m, p).number, 1000*eval(context, df, leaf->fparms[1], x, m, p).number)); + return Result (60*VDOTCalculator::eqvTime(eval(df, leaf->fparms[0], x, m, p).number, 1000*eval(df, leaf->fparms[1], x, m, p).number)); } break; @@ -2144,9 +2144,9 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte } else if (!symbol.compare("Current", Qt::CaseInsensitive)) { - if (context->currentRideItem()) + if (m->context->currentRideItem()) lhsdouble = QDate(1900,01,01). - daysTo(context->currentRideItem()->dateTime.date()); + daysTo(m->context->currentRideItem()->dateTime.date()); else lhsdouble = 0; lhsisNumber = true; @@ -2163,7 +2163,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte } else if (isCoggan(symbol)) { // a coggan PMC metric - PMCData *pmcData = context->athlete->getPMCFor("coggan_tss"); + PMCData *pmcData = m->context->athlete->getPMCFor("coggan_tss"); if (!symbol.compare("ctl", Qt::CaseInsensitive)) lhsdouble = pmcData->lts(m->dateTime.date()); if (!symbol.compare("atl", Qt::CaseInsensitive)) lhsdouble = pmcData->sts(m->dateTime.date()); if (!symbol.compare("tsb", Qt::CaseInsensitive)) lhsdouble = pmcData->sb(m->dateTime.date()); @@ -2228,7 +2228,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte case Leaf::UnaryOperation : { // get result - Result lhs = eval(context, df, leaf->lvalue.l, x, m, p); + Result lhs = eval(df, leaf->lvalue.l, x, m, p); // unary minus if (leaf->op == '-') return Result(lhs.number * -1); @@ -2249,12 +2249,12 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte { // lhs and rhs Result lhs; - if (leaf->op != ASSIGN) lhs = eval(context, df, leaf->lvalue.l, x, m, p); + if (leaf->op != ASSIGN) lhs = eval(df, leaf->lvalue.l, x, m, p); // if elvis we only evaluate rhs if we are null Result rhs; if (leaf->op != ELVIS || lhs.number == 0) { - rhs = eval(context, df, leaf->rvalue.l, x, m, p); + rhs = eval(df, leaf->rvalue.l, x, m, p); } // NOW PERFORM OPERATION @@ -2396,12 +2396,12 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte case IF_: case 0 : { - Result cond = eval(context, df, leaf->cond.l, x, m, p); - if (cond.isNumber && cond.number) return eval(context, df, leaf->lvalue.l, x, m, p); + Result cond = eval(df, leaf->cond.l, x, m, p); + if (cond.isNumber && cond.number) return eval(df, leaf->lvalue.l, x, m, p); else { // conditional may not have an else clause! - if (leaf->rvalue.l) return eval(context, df, leaf->rvalue.l, x, m, p); + if (leaf->rvalue.l) return eval(df, leaf->rvalue.l, x, m, p); else return Result(0); } } @@ -2415,8 +2415,8 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte timer.start(); Result returning(0); - while (count++ < maxwhile && eval(context, df, leaf->cond.l, x, m, p).number) { - returning = eval(context, df, leaf->lvalue.l, x, m, p); + while (count++ < maxwhile && eval(df, leaf->cond.l, x, m, p).number) { + returning = eval(df, leaf->lvalue.l, x, m, p); } // we had to terminate warn user ! @@ -2457,8 +2457,8 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte } // get date range - int fromDS = eval(context, df, leaf->fparms[0], x, m, p).number; - int toDS = eval(context, df, leaf->fparms[1], x, m, p).number; + int fromDS = eval(df, leaf->fparms[0], x, m, p).number; + int toDS = eval(df, leaf->fparms[1], x, m, p).number; // swap dates if needed if (toDS < fromDS) { @@ -2472,12 +2472,12 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte Result returning(0); // now iterate and evaluate for each - foreach(RideItem *ride, context->athlete->rideCache->rides()) { + foreach(RideItem *ride, m->context->athlete->rideCache->rides()) { if (!spec.pass(ride)) continue; // calculate value - Result res = eval(context, df, leaf->lvalue.l, x, ride, p); + Result res = eval(df, leaf->lvalue.l, x, ride, p); if (res.isNumber) { returning.number += res.number; // sum for easy access returning.vector << res.number; @@ -2502,7 +2502,7 @@ Result Leaf::eval(Context *context, DataFilter *df, Leaf *leaf, float x, RideIte Result returning(0); // evaluate each statement - foreach(Leaf *statement, *(leaf->lvalue.b)) returning = eval(context, df, statement, x, m, p); + foreach(Leaf *statement, *(leaf->lvalue.b)) returning = eval(df, statement, x, m, p); // compound statements evaluate to the value of the last statement return returning; diff --git a/src/DataFilter.h b/src/DataFilter.h index 5e038024b..2a506c5b4 100644 --- a/src/DataFilter.h +++ b/src/DataFilter.h @@ -58,8 +58,8 @@ class Leaf { Leaf(int loc, int leng) : type(none),op(0),series(NULL),dynamic(false),loc(loc),leng(leng),inerror(false) { } - // evaluate against a RideItem - Result eval(Context *context, DataFilter *df, Leaf *, float x, RideItem *m, RideFilePoint *p = NULL); + // evaluate against a RideItem using its context + Result eval(DataFilter *df, Leaf *, float x, RideItem *m, RideFilePoint *p = NULL); // tree traversal etc void print(Leaf *, int level); // print leaf and all children @@ -122,8 +122,8 @@ class DataFilter : public QObject QMap lookupMap; QMap lookupType; // true if a number, false if a string - // when used for formulas - Result evaluate(RideItem *rideItem, RideFilePoint *p = NULL); + // RideItem always available and supplies th context + Result evaluate(RideItem *rideItem, RideFilePoint *p); QStringList getErrors() { return errors; }; void colorSyntax(QTextDocument *content, int pos); @@ -143,7 +143,7 @@ class DataFilter : public QObject QHash functions; public slots: - QStringList parseFilter(QString query, QStringList *list=0); + QStringList parseFilter(Context *context, QString query, QStringList *list=0); QStringList check(QString query); void clearFilter(); void configChanged(qint32); diff --git a/src/EditUserMetricDialog.cpp b/src/EditUserMetricDialog.cpp index 88fbd4bec..4de65e6cb 100644 --- a/src/EditUserMetricDialog.cpp +++ b/src/EditUserMetricDialog.cpp @@ -90,7 +90,7 @@ EditUserMetricDialog::EditUserMetricDialog(Context *context, UserMetricSettings QLabel *precisionLabel = new QLabel(tr("Precision"), this); precision = new QDoubleSpinBox(this); - precision->setDecimals(3); + precision->setDecimals(0); precision->setValue(settings.precision); aggzero = new QCheckBox(tr("Aggregate Zero")); @@ -300,7 +300,7 @@ EditUserMetricDialog::refreshStats() setSettings(here); // Build a metric - UserMetric *test = new UserMetric(here); + UserMetric test(context, here); // fetch the inputs to ridemetric compute .. RideFile *ride = context->rideItem()->ride(); @@ -309,12 +309,12 @@ EditUserMetricDialog::refreshStats() const QHash deps; // no deps yet // compute it - test->setValue(0.0); - test->setCount(0); - test->compute(ride, context->athlete->zones(), zoneRange, context->athlete->hrZones(), hrZoneRange, deps, context); + test.setValue(0.0); + test.setCount(0); + test.compute(ride, context->athlete->zones(), zoneRange, context->athlete->hrZones(), hrZoneRange, deps, context); // get the value out - mValue->setText(test->toString(true)); - iValue->setText(test->toString(false)); + mValue->setText(test.toString(true)); + iValue->setText(test.toString(false)); } diff --git a/src/LTMPlot.cpp b/src/LTMPlot.cpp index 8a8e42d93..4b17052ff 100644 --- a/src/LTMPlot.cpp +++ b/src/LTMPlot.cpp @@ -2708,7 +2708,7 @@ LTMPlot::createFormulaData(Context *context, LTMSettings *settings, MetricDetail double value = 0; // PARSE + EVALUATE - Result res = parser.evaluate(ride); + Result res = parser.evaluate(ride, NULL); if (res.isNumber) value = res.number; // check values are bounded to stop QWT going berserk diff --git a/src/LTMSidebar.cpp b/src/LTMSidebar.cpp index 23bb1bbce..7f697b671 100644 --- a/src/LTMSidebar.cpp +++ b/src/LTMSidebar.cpp @@ -749,7 +749,7 @@ LTMSidebar::filterTreeWidgetSelectionChanged() { // use a data filter DataFilter f(this, context); - errors = f.parseFilter(ns.text, &results); + errors = f.parseFilter(context, ns.text, &results); } break; diff --git a/src/PMCData.cpp b/src/PMCData.cpp index f04c3ac63..ea3227651 100644 --- a/src/PMCData.cpp +++ b/src/PMCData.cpp @@ -216,7 +216,7 @@ void PMCData::refresh() // although metrics are cleansed, we check here because development // builds have a rideDB.json that has nan and inf values in it. double value = 0;; - if (fromDataFilter) value = expr->eval(context, df, expr, 0, item).number; + if (fromDataFilter) value = expr->eval(df, expr, 0, item).number; else value = item->getForSymbol(metricName_); if (!std::isinf(value) && !std::isnan(value)) diff --git a/src/RideMetric.cpp b/src/RideMetric.cpp index b4fa6df92..2c0f1796e 100644 --- a/src/RideMetric.cpp +++ b/src/RideMetric.cpp @@ -187,5 +187,5 @@ QString RideMetric::toString(bool useMetricUnits) const { if (isTime()) return time_to_string(value(useMetricUnits)); - return QString("%1").arg(value(useMetricUnits), 0, 'f', precision()); + return QString("%1").arg(value(useMetricUnits), 0, 'f', this->precision()); } diff --git a/src/RideMetric.h b/src/RideMetric.h index 16da544b7..165b8b065 100644 --- a/src/RideMetric.h +++ b/src/RideMetric.h @@ -213,7 +213,7 @@ class UserMetric: public RideMetric { public: - UserMetric(UserMetricSettings settings); + UserMetric(Context *context, UserMetricSettings settings); ~UserMetric(); // is this a user defined one? diff --git a/src/SearchBox.cpp b/src/SearchBox.cpp index 24934a699..1e3f9cec6 100644 --- a/src/SearchBox.cpp +++ b/src/SearchBox.cpp @@ -315,7 +315,7 @@ void SearchBox::searchSubmit() // return hit / key pressed if (text() != "") { filtered = true; - mode == Search ? submitQuery(text()) : submitFilter(text()); + mode == Search ? submitQuery(text()) : submitFilter(context, text()); } } diff --git a/src/SearchBox.h b/src/SearchBox.h index 689f09b37..9f509b6b1 100644 --- a/src/SearchBox.h +++ b/src/SearchBox.h @@ -100,7 +100,7 @@ signals: void clearQuery(); // db filter mode - void submitFilter(QString); + void submitFilter(Context*,QString); void clearFilter(); // focus in/out diff --git a/src/SearchFilterBox.cpp b/src/SearchFilterBox.cpp index 73b766d43..f56b858b8 100644 --- a/src/SearchFilterBox.cpp +++ b/src/SearchFilterBox.cpp @@ -46,7 +46,7 @@ SearchFilterBox::SearchFilterBox(QWidget *parent, Context *context, bool nochoos connect(searchbox, SIGNAL(clearQuery()), this, SIGNAL(searchClear())); // data filtering - connect(searchbox, SIGNAL(submitFilter(QString)), datafilter, SLOT(parseFilter(QString))); + connect(searchbox, SIGNAL(submitFilter(Context*,QString)), datafilter, SLOT(parseFilter(Context*,QString))); connect(datafilter, SIGNAL(results(QStringList)), this, SIGNAL(searchResults(QStringList))); connect(searchbox, SIGNAL(clearFilter()), this, SIGNAL(searchClear())); connect(searchbox, SIGNAL(clearFilter()), datafilter, SLOT(clearFilter())); @@ -87,7 +87,7 @@ SearchFilterBox::matches(Context *context, QString filter) DataFilter df(NULL, context, spec); foreach(RideItem *item, context->athlete->rideCache->rides()) { - Result res = df.evaluate(item); + Result res = df.evaluate(item, NULL); if (res.isNumber && res.number) returning << item->fileName; } diff --git a/src/UserMetric.cpp b/src/UserMetric.cpp index 34a17b0f5..76ca75b3a 100644 --- a/src/UserMetric.cpp +++ b/src/UserMetric.cpp @@ -18,24 +18,31 @@ #include "RideMetric.h" #include "UserMetricSettings.h" +#include "DataFilter.h" -UserMetric::UserMetric(UserMetricSettings settings) + +UserMetric::UserMetric(Context *context, UserMetricSettings settings) + : RideMetric(), settings(settings), program(NULL) { + // compile the program - built in a context that can close. + program = new DataFilter(NULL, context, settings.program); } UserMetric::~UserMetric() { + if (program) delete program; } void UserMetric::initialize() { + return; // nothing doing } QString UserMetric::symbol() const { - return ""; + return settings.symbol; } // A short string suitable for showing to the user in the ride @@ -44,39 +51,40 @@ UserMetric::symbol() const QString UserMetric::name() const { - return ""; + return settings.name; } QString UserMetric::internalName() const { - return ""; + return settings.name; } RideMetric::MetricType UserMetric::type() const { + return static_cast(settings.type); } // units QString UserMetric::units(bool metric) const { - return ""; + return metric ? settings.unitsMetric : settings.unitsImperial; } // Factor to multiple value to convert from metric to imperial double UserMetric::conversion() const { - return 1; + return settings.conversion; } // And sum for example Fahrenheit from CentigradE double UserMetric::conversionSum() const { - return 0; + return settings.conversionSum; } // How many digits after the decimal we should show when displaying the @@ -84,42 +92,51 @@ UserMetric::conversionSum() const int UserMetric::precision() const { - return 0; + return settings.precision; } // Get the value and apply conversion if needed double UserMetric::value(bool metric) const { - return 0; + if (metric) return value(); + else return (value() * conversion()) + conversionSum(); } // The internal value of this ride metric, useful to cache and then setValue. double UserMetric::value() const { - return 0; + return value_; } // for averages the count of items included in the average double UserMetric::count() const { - return 0; + return count_; } // when aggregating averages, should we include zeroes ? no by default bool UserMetric::aggregateZero() const { - return true; + return settings.aggzero; } // is this metric relevant bool -UserMetric::isRelevantForRide(const RideItem *) const +UserMetric::isRelevantForRide(const RideItem *item) const { - return true; + 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; + } + return false; } // Compute the ride metric from a file. @@ -130,11 +147,17 @@ UserMetric::compute(const RideFile *ride, const QHash &deps, const Context *context) { + // XXX todo + // relevant ? + // init ? + // samples ? + // value ? + // count? } bool UserMetric::isTime() const { - return false; + return settings.istime; }