Fix sample times in dive merging

Commit c27314d60 ("core: replace add_sample() by append_sample()") broke
the dive computer interleaving when merging two dives: the sample
merging (done by "merge_samples()") no longer took the offset between
the two merged dives into account, and instead just blindly copied the
samples from the second dive computer with no time offset.

The end result was a completely broken profile.

This adds back the sample offset.  It also takes the offset not from the
difference in time of the two dives, but the difference in time of the
dive computers.  That way we're not mixing up different times from
different sources that aren't necessarily in sync (the time *difference*
is hopefully the same, but still..).

The dive merging still messes up the dive location. That's some other bug.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2024-08-28 16:50:37 +12:00 committed by bstoeger
parent 914cdb102b
commit da6c753502

View file

@ -1210,7 +1210,9 @@ static void merge_samples(struct divecomputer &res,
/* Only samples from b? */
if (at < 0) {
add_sample_b:
merge_one_sample(*bs, res);
struct sample sample = *bs;
sample.time.seconds += offset;
merge_one_sample(sample, res);
renumber_last_sample(res, cylinders_map_b);
bs++;
continue;
@ -1223,6 +1225,7 @@ static void merge_samples(struct divecomputer &res,
/* same-time sample: add a merged sample. Take the non-zero ones */
struct sample sample = *bs;
sample.time.seconds += offset;
sample_renumber(sample, nullptr, cylinders_map_b);
if (as->depth.mm)
sample.depth = as->depth;
@ -2112,8 +2115,7 @@ static void copy_dive_computer(struct divecomputer &res, const struct divecomput
*/
static void interleave_dive_computers(struct dive &res,
const struct dive &a, const struct dive &b,
const int cylinders_map_a[], const int cylinders_map_b[],
int offset)
const int cylinders_map_a[], const int cylinders_map_b[])
{
res.dcs.clear();
for (const auto &dc1: a.dcs) {
@ -2122,6 +2124,7 @@ static void interleave_dive_computers(struct dive &res,
copy_dive_computer(newdc, dc1);
const divecomputer *match = find_matching_computer(dc1, b);
if (match) {
int offset = match->when - dc1.when;
merge_events(res, newdc, dc1, *match, cylinders_map_a, cylinders_map_b, offset);
merge_samples(newdc, dc1, *match, cylinders_map_a, cylinders_map_b, offset);
merge_extra_data(newdc, dc1, *match);
@ -2227,7 +2230,7 @@ std::unique_ptr<dive> dive::create_merged_dive(const struct dive &a, const struc
/* If we prefer downloaded, do those first, and get rid of "might be same" computers */
join_dive_computers(*res, b, a, cylinders_map_b.get(), cylinders_map_a.get(), true);
} else if (offset && might_be_same_device(a.dcs[0], b.dcs[0])) {
interleave_dive_computers(*res, a, b, cylinders_map_a.get(), cylinders_map_b.get(), offset);
interleave_dive_computers(*res, a, b, cylinders_map_a.get(), cylinders_map_b.get());
} else {
join_dive_computers(*res, a, b, cylinders_map_a.get(), cylinders_map_b.get(), false);
}