aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2020-10-03 17:03:28 +0200
committerGravatar Dirk Hohndel <dirk@hohndel.org>2020-10-05 12:59:02 -0700
commit6729428b6a942f83892129d7b8d1e5ef04930d05 (patch)
tree6188d5cb5b28039ba4ebefc4b2c344b93f1dc49f
parent6f8837eca3c001d8389cfcbcfa6dfc511bd78b47 (diff)
downloadsubsurface-6729428b6a942f83892129d7b8d1e5ef04930d05.tar.gz
core: improve merging of cylinders pressures
When merging cylinders pressures derived from samples were taken as maximum of the start and minimum of the end pressure, which makes sense, since we believe that this is the same cylinder. However, for manually entered pressures, this was not done. Moreover, when one dive had manual pressures and the other only pressure from samples, the manual pressure was taken. However, that could have been the wrong one, for example if the end pressure was manually set for the cylinder of the first part of the dive, but not the last. Therefore, improve merging of manuall set pressures in two ways: 1) use maximum/minimum for start/end pressure 2) if the pressure of one cylinder was manually set, but not for the other, complete with the sample pressure (if that exists). Fixes #2884. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r--CHANGELOG.md1
-rw-r--r--core/dive.c43
2 files changed, 40 insertions, 4 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7b9095728..e8edf7268 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,5 @@
- desktop: allow adding dives to arbitrary trips
+- core: improve merging of cylinder pressures [#2884]
- desktop: respect page-up, page-down, home and end keys for selection change [#2957]
- Use pO2 from prefernces for MOD display in equipment tab
- filter: more flexible filtering system based on individual constraints
diff --git a/core/dive.c b/core/dive.c
index c3fd95bf1..2c9de41a3 100644
--- a/core/dive.c
+++ b/core/dive.c
@@ -2228,6 +2228,39 @@ static int match_cylinder(const cylinder_t *cyl, const struct dive *dive, const
}
/*
+ * Function used to merge manually set start or end pressures. This
+ * is used to merge cylinders when merging dives. We store up to two
+ * values for start _and_ end pressures: one derived from samples and
+ * one entered manually, whereby the latter takes precedence. It may
+ * happen that the user merges two dives where one has a manual,
+ * the other only a sample-derived pressure. In such a case we want to
+ * supplement the non-existing manual value by a sample derived one.
+ * Otherwise, the merged dive would end up with incomplete pressure
+ * information.
+ * The last argument to the function specifies whether the larger
+ * or smaller value of the two dives should be returned. Obviously,
+ * for the starting pressure we want the larger and for the ending
+ * pressure the smaller value.
+ */
+static pressure_t merge_pressures(pressure_t a, pressure_t sample_a, pressure_t b, pressure_t sample_b, bool take_min)
+{
+ if (!a.mbar && !b.mbar)
+ return a;
+ if (!a.mbar)
+ a = sample_a;
+ if (!b.mbar)
+ b = sample_b;
+ if (!a.mbar)
+ a = b;
+ if (!b.mbar)
+ b = a;
+ if (take_min && a.mbar < b.mbar)
+ return a;
+ else
+ return b;
+}
+
+/*
* We matched things up so that they have the same gasmix and
* use, but we might want to fill in any missing cylinder details
* in 'a' if we had it from 'b'.
@@ -2240,10 +2273,12 @@ static void merge_one_cylinder(cylinder_t *a, const cylinder_t *b)
a->type.workingpressure.mbar = b->type.workingpressure.mbar;
if (empty_string(a->type.description))
a->type.description = copy_string(b->type.description);
- if (!a->start.mbar)
- a->start.mbar = b->start.mbar;
- if (!a->end.mbar)
- a->end.mbar = b->end.mbar;
+
+ /* If either cylinder has manually entered pressures, try to merge them.
+ * Use pressures from divecomputer samples if only one cylinder has such a value.
+ * Yes, this is an actual use case we encountered. */
+ a->start = merge_pressures(a->start, a->sample_start, b->start, b->sample_start, false);
+ a->end = merge_pressures(a->end, a->sample_end, b->end, b->sample_end, true);
if (a->sample_start.mbar && b->sample_start.mbar)
a->sample_start.mbar = a->sample_start.mbar > b->sample_start.mbar ? a->sample_start.mbar : b->sample_start.mbar;