summaryrefslogtreecommitdiffstats
path: root/core/dive.c
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2017-02-08 15:00:04 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2017-02-09 21:30:49 -0800
commit0e7d8993a2c1a21b08f7d0525bf101ce6fb15fcd (patch)
tree7f1f0ad52ac5bd59f0fa76ce7dca583357c6756f /core/dive.c
parente2bbd0ceecff7193bb272430fbebfc4b02dd67c3 (diff)
downloadsubsurface-0e7d8993a2c1a21b08f7d0525bf101ce6fb15fcd.tar.gz
Make cylinder merging a bit more careful
This makes some further updates to the new cylinder merging code: - avoid re-using the cylinder if the usage type (OC/diluent/O2) is different between the two dives, even if the gasmix might be the same. - avoid re-using a cylinder if the user has manually added pressure data for it (and the pressures don't match) - when deciding to reuse a cylinder, make sure that we merge as much of the type information as makes sense. This will potentially result in more cylinders that might need manual cleanup, but at least we won't be throwing out user data. And in most cases where merging happens, none of this is an issue (because the data comes fresh from a dive computer, and won't have been manually edited to trigger the new rules). Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'core/dive.c')
-rw-r--r--core/dive.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/core/dive.c b/core/dive.c
index 80583e5b4..3dcfebc3e 100644
--- a/core/dive.c
+++ b/core/dive.c
@@ -2015,10 +2015,24 @@ static int same_gasmix(struct gasmix *a, struct gasmix *b)
return a->o2.permille == b->o2.permille && a->he.permille == b->he.permille;
}
+static int pdiff(pressure_t a, pressure_t b)
+{
+ return a.mbar && b.mbar && a.mbar != b.mbar;
+}
+
+static int different_manual_pressures(cylinder_t *a, cylinder_t *b)
+{
+ return pdiff(a->start, b->start) || pdiff(a->end, b->end);
+}
+
/*
* Can we find an exact match for a cylinder in another dive?
* Take the "already matched" map into account, so that we
* don't match multiple similar cylinders to one target.
+ *
+ * To match, the cylinders have to have the same gasmix and the
+ * same cylinder use (ie OC/Diluent/Oxygen), and if pressures
+ * have been added manually they need to match.
*/
static int match_cylinder(cylinder_t *cyl, struct dive *dive, unsigned int available)
{
@@ -2032,6 +2046,10 @@ static int match_cylinder(cylinder_t *cyl, struct dive *dive, unsigned int avail
target = dive->cylinder + i;
if (!same_gasmix(&cyl->gasmix, &target->gasmix))
continue;
+ if (cyl->cylinder_use != target->cylinder_use)
+ continue;
+ if (different_manual_pressures(cyl, target))
+ continue;
/* FIXME! Should we check sizes too? */
return i;
@@ -2058,6 +2076,25 @@ static int find_unused_cylinder(unsigned int used_map)
}
/*
+ * 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'.
+ */
+static void merge_one_cylinder(cylinder_t *a, cylinder_t *b)
+{
+ if (!a->type.size.mliter)
+ a->type.size.mliter = b->type.size.mliter;
+ if (!a->type.workingpressure.mbar)
+ a->type.workingpressure.mbar = b->type.workingpressure.mbar;
+ if (!a->type.description && b->type.description)
+ a->type.description = strdup(b->type.description);
+ if (!a->start.mbar)
+ a->start.mbar = b->start.mbar;
+ if (!a->end.mbar)
+ a->end.mbar = b->end.mbar;
+}
+
+/*
* Merging cylinder information is non-trivial, because the two dive computers
* may have different ideas of what the different cylinder indexing is.
*
@@ -2094,6 +2131,8 @@ static void merge_cylinders(struct dive *res, struct dive *a, struct dive *b)
/*
* If we had a successful match, we:
*
+ * - try to merge individual cylinder data from both cases
+ *
* - save that in the mapping table
*
* - mark it as matched so that another cylinder in 'b'
@@ -2101,6 +2140,7 @@ static void merge_cylinders(struct dive *res, struct dive *a, struct dive *b)
*
* - mark 'b' as needing renumbering if the index changed
*/
+ merge_one_cylinder(a->cylinder + j, b->cylinder + i);
mapping[i] = j;
matched |= 1u << j;
if (j != i)