diff --git a/core/dive.cpp b/core/dive.cpp index d57440d34..5cad9f867 100644 --- a/core/dive.cpp +++ b/core/dive.cpp @@ -2666,3 +2666,40 @@ temperature_t dive::dc_airtemp() const return temperature_t(); return temperature_t{ static_cast((sum + nr / 2) / nr) }; } + +/* + * Get "maximal" dive gas for a dive. + * Rules: + * - Trimix trumps nitrox (highest He wins, O2 breaks ties) + * - Nitrox trumps air (even if hypoxic) + * These are the same rules as the inter-dive sorting rules. + */ +dive::get_maximal_gas_result dive::get_maximal_gas() const +{ + int maxo2 = -1, maxhe = -1, mino2 = 1000; + + for (auto [i, cyl]: enumerated_range(cylinders)) { + int o2 = get_o2(cyl.gasmix); + int he = get_he(cyl.gasmix); + + if (!is_cylinder_used(this, i)) + continue; + if (cyl.cylinder_use == OXYGEN) + continue; + if (cyl.cylinder_use == NOT_USED) + continue; + if (o2 > maxo2) + maxo2 = o2; + if (o2 < mino2 && maxhe <= 0) + mino2 = o2; + if (he > maxhe) { + maxhe = he; + mino2 = o2; + } + } + /* All air? Show/sort as "air"/zero */ + if ((!maxhe && maxo2 == O2_IN_AIR && mino2 == maxo2) || + (maxo2 == -1 && maxhe == -1 && mino2 == 1000)) + maxo2 = mino2 = 0; + return { mino2, maxhe, maxo2 }; +} diff --git a/core/dive.h b/core/dive.h index 0f4fbe8d7..0ea75d4c6 100644 --- a/core/dive.h +++ b/core/dive.h @@ -85,6 +85,9 @@ struct dive { temperature_t dc_airtemp() const; /* average over divecomputers */ temperature_t dc_watertemp() const; /* average over divecomputers */ + struct get_maximal_gas_result { int o2_p; int he_p; int o2low_p; }; + get_maximal_gas_result get_maximal_gas() const; + bool is_planned() const; bool is_logged() const; bool likely_same(const struct dive &b) const; diff --git a/core/divelist.cpp b/core/divelist.cpp index 9023d1d97..28152847f 100644 --- a/core/divelist.cpp +++ b/core/divelist.cpp @@ -104,45 +104,6 @@ std::unique_ptr dive_table::default_dive() return d; } -/* - * Get "maximal" dive gas for a dive. - * Rules: - * - Trimix trumps nitrox (highest He wins, O2 breaks ties) - * - Nitrox trumps air (even if hypoxic) - * These are the same rules as the inter-dive sorting rules. - */ -void get_dive_gas(const struct dive *dive, int *o2_p, int *he_p, int *o2max_p) -{ - int maxo2 = -1, maxhe = -1, mino2 = 1000; - - for (auto [i, cyl]: enumerated_range(dive->cylinders)) { - int o2 = get_o2(cyl.gasmix); - int he = get_he(cyl.gasmix); - - if (!is_cylinder_used(dive, i)) - continue; - if (cyl.cylinder_use == OXYGEN) - continue; - if (cyl.cylinder_use == NOT_USED) - continue; - if (o2 > maxo2) - maxo2 = o2; - if (o2 < mino2 && maxhe <= 0) - mino2 = o2; - if (he > maxhe) { - maxhe = he; - mino2 = o2; - } - } - /* All air? Show/sort as "air"/zero */ - if ((!maxhe && maxo2 == O2_IN_AIR && mino2 == maxo2) || - (maxo2 == -1 && maxhe == -1 && mino2 == 1000)) - maxo2 = mino2 = 0; - *o2_p = mino2; - *he_p = maxhe; - *o2max_p = maxo2; -} - int total_weight(const struct dive *dive) { int total_grams = 0; diff --git a/core/divelist.h b/core/divelist.h index fc267b62c..8aa05a7b8 100644 --- a/core/divelist.h +++ b/core/divelist.h @@ -51,8 +51,6 @@ private: /* this is used for both git and xml format */ #define DATAFORMAT_VERSION 3 -extern void get_dive_gas(const struct dive *dive, int *o2_p, int *he_p, int *o2low_p); - int get_min_datafile_version(); void report_datafile_version(int version); void clear_dive_file_data(); diff --git a/core/profile.cpp b/core/profile.cpp index a1f8bd5d5..e2c1b6281 100644 --- a/core/profile.cpp +++ b/core/profile.cpp @@ -1250,13 +1250,12 @@ static void debug_print_profiledata(struct plot_info &pi) */ struct plot_info create_plot_info_new(const struct dive *dive, const struct divecomputer *dc, const struct deco_state *planner_ds) { - int o2, he, o2max; struct deco_state plot_deco_state; bool in_planner = planner_ds != NULL; divelog.dives.init_decompression(&plot_deco_state, dive, in_planner); plot_info pi; calculate_max_limits_new(dive, dc, pi, in_planner); - get_dive_gas(dive, &o2, &he, &o2max); + auto [o2, he, o2max ] = dive->get_maximal_gas(); if (dc->divemode == FREEDIVE) { pi.dive_type = plot_info::FREEDIVING; } else if (he > 0) { diff --git a/core/string-format.cpp b/core/string-format.cpp index b07618843..b97732824 100644 --- a/core/string-format.cpp +++ b/core/string-format.cpp @@ -259,8 +259,7 @@ QString formatDiveDateTime(const dive *d) QString formatDiveGasString(const dive *d) { - int o2, he, o2max; - get_dive_gas(d, &o2, &he, &o2max); + auto [o2, he, o2max ] = d->get_maximal_gas(); o2 = (o2 + 5) / 10; he = (he + 5) / 10; o2max = (o2max + 5) / 10; diff --git a/qt-models/divetripmodel.cpp b/qt-models/divetripmodel.cpp index f1b70b983..3deb4a81c 100644 --- a/qt-models/divetripmodel.cpp +++ b/qt-models/divetripmodel.cpp @@ -28,8 +28,7 @@ static int nitrox_sort_value(const struct dive *dive) { - int o2, he, o2max; - get_dive_gas(dive, &o2, &he, &o2max); + auto [o2, he, o2max ] = dive->get_maximal_gas(); return he * 1000 + o2; } diff --git a/stats/statsvariables.cpp b/stats/statsvariables.cpp index 8f31190bc..86de9244c 100644 --- a/stats/statsvariables.cpp +++ b/stats/statsvariables.cpp @@ -216,7 +216,7 @@ bool StatsQuartiles::isValid() const // Define an ordering for gas types // invalid < air < ean (including oxygen) < trimix // The latter two are sorted by (helium, oxygen) -// This is in analogy to the global get_dive_gas() function. +// This is in analogy to the dive::get_maximal_gas() function. static bool operator<(const gas_bin_t &t1, const gas_bin_t &t2) { if (t1.type != t2.type)