diff options
author | Dirk Hohndel <dirk@hohndel.org> | 2014-06-01 15:25:19 -0700 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2014-06-01 15:40:46 -0700 |
commit | fe773241eea51036b25815302fc676eafbcac85a (patch) | |
tree | 9bbf7ff480508a90af7ddfb266517de38107be98 | |
parent | 2bf46381a82fd6ae514b014b8d32954693bca346 (diff) | |
download | subsurface-fe773241eea51036b25815302fc676eafbcac85a.tar.gz |
Next step to using gasmix instead of o2/he
This changes the divedatapoints and functions that deal with them.
It changes plan_add_segment(), create_dp(), gasToStr(), and tankInUse() to
consume gasmix instead of o2/he.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r-- | dive.h | 13 | ||||
-rw-r--r-- | planner.c | 47 | ||||
-rw-r--r-- | qt-ui/diveplanner.cpp | 53 | ||||
-rw-r--r-- | qt-ui/diveplanner.h | 4 | ||||
-rw-r--r-- | qt-ui/models.cpp | 2 |
5 files changed, 58 insertions, 61 deletions
@@ -113,6 +113,11 @@ static inline bool is_air(int o2, int he) return (he == 0) && (o2 == 0 || ((o2 >= O2_IN_AIR - 1) && (o2 <= O2_IN_AIR + 1))); } +static inline bool gasmix_is_air(const struct gasmix *gasmix) +{ + return is_air(gasmix->o2.permille, gasmix->he.permille); +} + /* Linear interpolation between 'a' and 'b', when we are 'part'way into the 'whole' distance from a to b */ static inline int interpolate(int a, int b, int part, int whole) { @@ -626,11 +631,11 @@ extern void set_gf(short gflow, short gfhigh, bool gf_low_at_maxdepth); extern void cache_deco_state(double, char **datap); extern double restore_deco_state(char *data); +/* this should be converted to use our types */ struct divedatapoint { int time; unsigned int depth; - int o2; - int he; + struct gasmix gasmix; int po2; bool entered; struct divedatapoint *next; @@ -646,9 +651,9 @@ struct diveplan { struct divedatapoint *dp; }; -struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration, int depth, int o2, int he, int po2, bool entered); +struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration, int depth, struct gasmix gasmix, int po2, bool entered); void get_gas_string(int o2, int he, char *buf, int len); -struct divedatapoint *create_dp(int time_incr, int depth, int o2, int he, int po2); +struct divedatapoint *create_dp(int time_incr, int depth, struct gasmix gasmix, int po2); #if DEBUG_PLAN void dump_plan(struct diveplan *diveplan); #endif @@ -121,7 +121,6 @@ double tissue_at_end(struct dive *dive, char **cached_datap) struct divecomputer *dc; struct sample *sample, *psample; int i, t0, t1, gasidx, lastdepth; - int o2, he; double tissue_tolerance; struct gasmix gas; @@ -264,7 +263,8 @@ static struct dive *create_dive_from_plan(struct diveplan *diveplan, struct dive sample->po2 = dp->po2; finish_sample(dc); while (dp) { - int o2 = dp->o2, he = dp->he; + int o2 = get_o2(&dp->gasmix); + int he = get_he(&dp->gasmix); int po2 = dp->po2; int time = dp->time; int depth = dp->depth; @@ -352,15 +352,14 @@ void free_dps(struct divedatapoint *dp) } } -struct divedatapoint *create_dp(int time_incr, int depth, int o2, int he, int po2) +struct divedatapoint *create_dp(int time_incr, int depth, struct gasmix gasmix, int po2) { struct divedatapoint *dp; dp = malloc(sizeof(struct divedatapoint)); dp->time = time_incr; dp->depth = depth; - dp->o2 = o2; - dp->he = he; + dp->gasmix = gasmix; dp->po2 = po2; dp->entered = false; dp->next = NULL; @@ -371,6 +370,7 @@ struct divedatapoint *get_nth_dp(struct diveplan *diveplan, int idx) { struct divedatapoint **ldpp, *dp = diveplan->dp; int i = 0; + struct gasmix air = { 0 }; ldpp = &diveplan->dp; while (dp && i++ < idx) { @@ -378,7 +378,7 @@ struct divedatapoint *get_nth_dp(struct diveplan *diveplan, int idx) dp = dp->next; } while (i++ <= idx) { - *ldpp = dp = create_dp(0, 0, 0, 0, 0); + *ldpp = dp = create_dp(0, 0, air, 0); ldpp = &((*ldpp)->next); } return dp; @@ -400,9 +400,9 @@ void add_to_end_of_diveplan(struct diveplan *diveplan, struct divedatapoint *dp) dp->time += lasttime; } -struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration, int depth, int o2, int he, int po2, bool entered) +struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration, int depth, struct gasmix gasmix, int po2, bool entered) { - struct divedatapoint *dp = create_dp(duration, depth, o2, he, po2); + struct divedatapoint *dp = create_dp(duration, depth, gasmix, po2); dp->entered = entered; add_to_end_of_diveplan(diveplan, dp); return (dp); @@ -424,8 +424,7 @@ static struct gaschanges *analyze_gaslist(struct diveplan *diveplan, struct dive int best_depth = dive->cylinder[*asc_cylinder].depth.mm; while (dp) { if (dp->time == 0) { - gas.o2.permille = dp->o2; - gas.he.permille = dp->he; + gas = dp->gasmix; if (dp->depth <= depth) { int i = 0; nr++; @@ -516,7 +515,6 @@ static unsigned int *sort_stops(int *dstops, int dnr, struct gaschanges *gstops, static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_disclaimer) { char buffer[20000]; - int consumption[MAX_CYLINDERS] = { 0, }; int len, gasidx, lastdepth = 0, lasttime = 0; struct divedatapoint *dp = diveplan->dp; int o2, he; @@ -539,22 +537,21 @@ static void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool char gas[64]; double depthvalue; int decimals; - double used; int newo2 = -1, newhe = -1; struct divedatapoint *nextdp; if (dp->time == 0) continue; - o2 = dp->o2; - he = dp->he; + o2 = get_o2(&dp->gasmix); + he = get_he(&dp->gasmix); depthvalue = get_depth_units(dp->depth, &decimals, &depth_unit); /* analyze the dive points ahead */ nextdp = dp->next; while (nextdp && nextdp->time == 0) nextdp = nextdp->next; if (nextdp) { - newo2 = nextdp->o2; - newhe = nextdp->he; + newo2 = get_o2(&nextdp->gasmix); + newhe = get_he(&nextdp->gasmix); if (newhe == 0 && newo2 == 0) { /* same as last segment */ newo2 = o2; @@ -686,7 +683,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, s /* if all we wanted was the dive just get us back to the surface */ if (!add_deco) { transitiontime = depth / 75; /* this still needs to be made configurable */ - plan_add_segment(diveplan, transitiontime, 0, o2, he, po2, false); + plan_add_segment(diveplan, transitiontime, 0, gas, po2, false); /* re-create the dive */ delete_single_dive(dive_table.nr - 1); *divep = dive = create_dive_from_plan(diveplan, master_dive); @@ -723,8 +720,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, s stopping = true; current_cylinder = best_first_ascend_cylinder; - o2 = get_o2(&dive->cylinder[current_cylinder].gasmix); - he = get_he(&dive->cylinder[current_cylinder].gasmix); + gas = dive->cylinder[current_cylinder].gasmix; #if DEBUG_PLAN & 16 printf("switch to gas %d (%d/%d) @ %5.2lfm\n", best_first_ascend_cylinder, (o2 + 5) / 10, (he + 5) / 10, gaschanges[best_first_ascend_cylinder].depth / 1000.0); @@ -737,7 +733,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, s /* Ascend to next stop depth */ int deltad = ascend_velocity(depth, avg_depth, bottom_time) * TIMESTEP; if (ascend_velocity(depth, avg_depth, bottom_time) != last_ascend_rate) { - plan_add_segment(diveplan, clock - previous_point_time, depth, o2, he, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); previous_point_time = clock; stopping = false; last_ascend_rate = ascend_velocity(depth, avg_depth, bottom_time); @@ -757,13 +753,12 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, s if (gi >= 0 && stoplevels[stopidx] == gaschanges[gi].depth) { /* We have reached a gas change. * Record this in the dive plan */ - plan_add_segment(diveplan, clock - previous_point_time, depth, o2, he, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); previous_point_time = clock; stopping = true; current_cylinder = gaschanges[gi].gasidx; - o2 = get_o2(&dive->cylinder[current_cylinder].gasmix); - he = get_he(&dive->cylinder[current_cylinder].gasmix); + gas = dive->cylinder[current_cylinder].gasmix; #if DEBUG_PLAN & 16 printf("switch to gas %d (%d/%d) @ %5.2lfm\n", gaschanges[gi].gasidx, (o2 + 5) / 10, (he + 5) / 10, gaschanges[gi].depth / 1000.0); @@ -798,7 +793,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, s if (!stopping) { /* The last segment was an ascend segment. * Add a waypoint for start of this deco stop */ - plan_add_segment(diveplan, clock - previous_point_time, depth, o2, he, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); previous_point_time = clock; stopping = true; } @@ -809,7 +804,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, s } if (stopping) { /* Next we will ascend again. Add a waypoint if we have spend deco time */ - plan_add_segment(diveplan, clock - previous_point_time, depth, o2, he, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, depth, gas, po2, false); previous_point_time = clock; stopping = false; } @@ -817,7 +812,7 @@ void plan(struct diveplan *diveplan, char **cached_datap, struct dive **divep, s } /* We made it to the surface */ - plan_add_segment(diveplan, clock - previous_point_time, 0, o2, he, po2, false); + plan_add_segment(diveplan, clock - previous_point_time, 0, gas, po2, false); delete_single_dive(dive_table.nr - 1); *divep = dive = create_dive_from_plan(diveplan, master_dive); if (!dive) diff --git a/qt-ui/diveplanner.cpp b/qt-ui/diveplanner.cpp index 830848987..55fb19ceb 100644 --- a/qt-ui/diveplanner.cpp +++ b/qt-ui/diveplanner.cpp @@ -30,16 +30,16 @@ #define MAX_DEPTH M_OR_FT(150, 450) #define MIN_DEPTH M_OR_FT(20, 60) -QString gasToStr(const int o2Permille, const int hePermille) +QString gasToStr(struct gasmix gas) { - uint o2 = (o2Permille + 5) / 10, he = (hePermille + 5) / 10; - QString result = is_air(o2Permille, hePermille) ? QObject::tr("AIR") : he == 0 ? QString("EAN%1").arg(o2, 2, 10, QChar('0')) : QString("%1/%2").arg(o2).arg(he); + uint o2 = (gas.o2.permille + 5) / 10, he = (gas.he.permille + 5) / 10; + QString result = gasmix_is_air(&gas) ? QObject::tr("AIR") : he == 0 ? QString("EAN%1").arg(o2, 2, 10, QChar('0')) : QString("%1/%2").arg(o2).arg(he); return result; } QString dpGasToStr(const divedatapoint &p) { - return gasToStr(p.o2, p.he); + return gasToStr(p.gasmix); } static DivePlannerPointsModel *plannerModel = DivePlannerPointsModel::instance(); @@ -153,7 +153,7 @@ QStringList &DivePlannerPointsModel::getGasList() cylinder_t *cyl = &activeDive->cylinder[i]; if (cylinder_nodata(cyl)) break; - list.push_back(gasToStr(get_o2(&cyl->gasmix), get_he(&cyl->gasmix))); + list.push_back(gasToStr(cyl->gasmix)); } } return list; @@ -417,10 +417,8 @@ bool DivePlannerPointsModel::setData(const QModelIndex &index, const QVariant &v } break; case GAS: QByteArray gasv = value.toByteArray(); - if (validate_gas(gasv.data(), &gas)) { - p.o2 = get_o2(&gas); - p.he = get_he(&gas); - } + if (validate_gas(gasv.data(), &gas)) + p.gasmix = gas; break; } editStop(index.row(), p); @@ -573,8 +571,8 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, int o2, int he, const divedatapoint t = divepoints.at(lastEnteredPoint()); milimeters = t.depth; seconds = t.time + 600; // 10 minutes. - o2 = t.o2; - he = t.he; + o2 = get_o2(&t.gasmix); + he = get_he(&t.gasmix); ccpoint = t.po2; } else if (seconds == 0 && milimeters == 0 && row == 0) { milimeters = M_OR_FT(5, 15); // 5m / 15ft @@ -607,16 +605,16 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, int o2, int he, } if (o2 == -1) { if (row > 0) { - o2 = divepoints.at(row - 1).o2; - he = divepoints.at(row - 1).he; + o2 = get_o2(&divepoints.at(row - 1).gasmix); + he = get_he(&divepoints.at(row - 1).gasmix); } else { // when we add a first data point we need to make sure that there is a // tank for it to use; // first check to the right, then to the left, but if there's nothing, // we simply default to AIR if (row < divepoints.count()) { - o2 = divepoints.at(row).o2; - he = divepoints.at(row).he; + o2 = get_o2(&divepoints.at(row).gasmix); + he = get_he(&divepoints.at(row).gasmix); } else { o2 = O2_IN_AIR; if (!addGas(o2, 0)) @@ -630,8 +628,8 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, int o2, int he, divedatapoint point; point.depth = milimeters; point.time = seconds; - point.o2 = o2; - point.he = he; + point.gasmix.o2.permille = o2; + point.gasmix.he.permille = he; point.po2 = ccpoint; point.entered = entered; divepoints.append(point); @@ -714,7 +712,7 @@ void DivePlannerPointsModel::rememberTanks() oldGases = collectGases(stagingDive); } -bool DivePlannerPointsModel::tankInUse(int o2, int he) +bool DivePlannerPointsModel::tankInUse(struct gasmix gasmix) { for (int j = 0; j < rowCount(); j++) { divedatapoint &p = divepoints[j]; @@ -722,8 +720,7 @@ bool DivePlannerPointsModel::tankInUse(int o2, int he) continue; if (!p.entered) // removing deco gases is ok continue; - if ((p.o2 == o2 && p.he == he) || - (is_air(p.o2, p.he) && is_air(o2, he))) + if (gasmix_distance(&p.gasmix, &gasmix) < 200) return true; } return false; @@ -747,12 +744,12 @@ void DivePlannerPointsModel::tanksUpdated() } for (int j = 0; j < rowCount(); j++) { divedatapoint &p = divepoints[j]; - int o2 = oldGases.at(i).first; - int he = oldGases.at(i).second; - if ((p.o2 == o2 && p.he == he) || - (is_air(p.o2, p.he) && (is_air(o2, he) || (o2 == 0 && he == 0)))) { - p.o2 = gases.at(i).first; - p.he = gases.at(i).second; + struct gasmix gas; + gas.o2.permille = oldGases.at(i).first; + gas.he.permille = oldGases.at(i).second; + if (gasmix_distance(&gas, &p.gasmix) < 200) { + p.gasmix.o2.permille = gases.at(i).first; + p.gasmix.he.permille = gases.at(i).second; } } break; @@ -797,7 +794,7 @@ void DivePlannerPointsModel::createTemporaryPlan() int deltaT = lastIndex != -1 ? p.time - at(lastIndex).time : p.time; lastIndex = i; if (p.entered) - plan_add_segment(&diveplan, deltaT, p.depth, p.o2, p.he, p.po2, true); + plan_add_segment(&diveplan, deltaT, p.depth, p.gasmix, p.po2, true); } char *cache = NULL; tempDive = NULL; @@ -805,7 +802,7 @@ void DivePlannerPointsModel::createTemporaryPlan() for (int i = 0; i < MAX_CYLINDERS; i++) { cylinder_t *cyl = &stagingDive->cylinder[i]; if (cyl->depth.mm) { - dp = create_dp(0, cyl->depth.mm, get_o2(&cyl->gasmix), get_he(&cyl->gasmix), 0); + dp = create_dp(0, cyl->depth.mm, cyl->gasmix, 0); if (diveplan.dp) { dp->next = diveplan.dp->next; diveplan.dp->next = dp; diff --git a/qt-ui/diveplanner.h b/qt-ui/diveplanner.h index a281b7634..acfc83b90 100644 --- a/qt-ui/diveplanner.h +++ b/qt-ui/diveplanner.h @@ -46,7 +46,7 @@ public: bool recalcQ(); void tanksUpdated(); void rememberTanks(); - bool tankInUse(int o2, int he); + bool tankInUse(struct gasmix gasmix); void copyCylinders(struct dive *d); void setupCylinders(); /** @@ -137,7 +137,7 @@ private: Ui::DivePlanner ui; }; -QString gasToStr(const int o2Permille, const int hePermille); +QString gasToStr(gasmix gas); QString dpGasToStr(const divedatapoint &p); #endif // DIVEPLANNER_H diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp index 340276059..9b92f8197 100644 --- a/qt-ui/models.cpp +++ b/qt-ui/models.cpp @@ -356,7 +356,7 @@ void CylindersModel::remove(const QModelIndex &index) } cylinder_t *cyl = ¤t->cylinder[index.row()]; if ((DivePlannerPointsModel::instance()->currentMode() != DivePlannerPointsModel::NOTHING && - DivePlannerPointsModel::instance()->tankInUse(cyl->gasmix.o2.permille, cyl->gasmix.he.permille)) || + DivePlannerPointsModel::instance()->tankInUse(cyl->gasmix)) || (DivePlannerPointsModel::instance()->currentMode() == DivePlannerPointsModel::NOTHING && (cyl->manually_added || (current_dive && cylinder_is_used(current_dive, cyl))))) { QMessageBox::warning(MainWindow::instance(), TITLE_OR_TEXT( |