mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-30 22:20:21 +00:00
Start merging dives by keeping the dive computer data from both dives
Also, note that we do *not* do the "find_sample_offset()" any more when we merge two dives that happen at the same time - since we just keep both sets of dive computer data around. But we keep the function to find the best offset around, because we may well want to use it later when *showing* the dive, and trying to match up the different sample data from the multiple dive computers associated with the dive. Because of that, this causes warnings about the now unused function. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
parent
5a4640cf44
commit
1b861ba20e
2 changed files with 129 additions and 24 deletions
131
dive.c
131
dive.c
|
@ -1051,21 +1051,100 @@ static int find_sample_offset(struct divecomputer *a, struct divecomputer *b)
|
|||
*/
|
||||
struct dive *try_to_merge(struct dive *a, struct dive *b, gboolean prefer_downloaded)
|
||||
{
|
||||
int offset = 0;
|
||||
|
||||
/*
|
||||
* This assumes that the clocks on the dive computers are
|
||||
* roughly synchronized.
|
||||
*/
|
||||
if ((a->when >= b->when + 60) || (a->when <= b->when - 60))
|
||||
return NULL;
|
||||
if (!prefer_downloaded) {
|
||||
/* Dive 'a' is 'offset' seconds before dive 'b' */
|
||||
offset = find_sample_offset(&a->dc, &b->dc);
|
||||
if (offset > 120 || offset < -120)
|
||||
return NULL;
|
||||
return merge_dives(a, b, 0, prefer_downloaded);
|
||||
}
|
||||
|
||||
static void free_events(struct event *ev)
|
||||
{
|
||||
while (ev) {
|
||||
struct event *next = ev->next;
|
||||
free(ev);
|
||||
ev = next;
|
||||
}
|
||||
return merge_dives(a, b, offset, prefer_downloaded);
|
||||
}
|
||||
|
||||
static void free_dc(struct divecomputer *dc)
|
||||
{
|
||||
free(dc->sample);
|
||||
free_events(dc->events);
|
||||
free(dc);
|
||||
}
|
||||
|
||||
static int same_event(struct event *a, struct event *b)
|
||||
{
|
||||
if (a->time.seconds != b->time.seconds)
|
||||
return 0;
|
||||
if (a->type != b->type)
|
||||
return 0;
|
||||
if (a->flags != b->flags)
|
||||
return 0;
|
||||
if (a->value != b->value)
|
||||
return 0;
|
||||
return !strcmp(a->name, b->name);
|
||||
}
|
||||
|
||||
static int same_sample(struct sample *a, struct sample *b)
|
||||
{
|
||||
if (a->time.seconds != b->time.seconds)
|
||||
return 0;
|
||||
if (a->depth.mm != b->depth.mm)
|
||||
return 0;
|
||||
if (a->temperature.mkelvin != b->temperature.mkelvin)
|
||||
return 0;
|
||||
if (a->cylinderpressure.mbar != b->cylinderpressure.mbar)
|
||||
return 0;
|
||||
return a->cylinderindex == b->cylinderindex;
|
||||
}
|
||||
|
||||
static int same_dc(struct divecomputer *a, struct divecomputer *b)
|
||||
{
|
||||
int i;
|
||||
struct event *eva, *evb;
|
||||
|
||||
if (a->when && b->when && a->when != b->when)
|
||||
return 0;
|
||||
if (a->samples != b->samples)
|
||||
return 0;
|
||||
for (i = 0; i < a->samples; i++)
|
||||
if (!same_sample(a->sample+i, b->sample+i))
|
||||
return 0;
|
||||
eva = a->events;
|
||||
evb = b->events;
|
||||
while (eva && evb) {
|
||||
if (!same_event(eva, evb))
|
||||
return 0;
|
||||
eva = eva->next;
|
||||
evb = evb->next;
|
||||
}
|
||||
return eva == evb;
|
||||
}
|
||||
|
||||
static void remove_redundant_dc(struct divecomputer *dc)
|
||||
{
|
||||
do {
|
||||
struct divecomputer **p = &dc->next;
|
||||
|
||||
/* Check this dc against all the following ones.. */
|
||||
while (*p) {
|
||||
struct divecomputer *check = *p;
|
||||
if (same_dc(dc, check)) {
|
||||
*p = check->next;
|
||||
check->next = NULL;
|
||||
free_dc(check);
|
||||
continue;
|
||||
}
|
||||
p = &check->next;
|
||||
}
|
||||
|
||||
/* .. and then continue down the chain */
|
||||
dc = dc->next;
|
||||
} while (dc);
|
||||
}
|
||||
|
||||
struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean prefer_downloaded)
|
||||
|
@ -1079,7 +1158,7 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean pr
|
|||
else if (b->downloaded)
|
||||
dl = b;
|
||||
}
|
||||
res->when = a->when;
|
||||
res->when = dl ? dl->when : a->when;
|
||||
res->selected = a->selected || b->selected;
|
||||
merge_trip(res, a, b);
|
||||
MERGE_NONZERO(res, a, b, latitude);
|
||||
|
@ -1110,9 +1189,39 @@ struct dive *merge_dives(struct dive *a, struct dive *b, int offset, gboolean pr
|
|||
* dive computer data is cleared out.
|
||||
*/
|
||||
memset(&dl->dc, 0, sizeof(dl->dc));
|
||||
} else if (offset) {
|
||||
struct divecomputer *a_dc = &a->dc;
|
||||
struct divecomputer *b_dc = &b->dc;
|
||||
struct divecomputer *res_dc = &res->dc;
|
||||
|
||||
/*
|
||||
* FIXME! We should try to match these things up some way,
|
||||
* now we just depend on the merged dives having the same
|
||||
* dive computers in the same order!
|
||||
*/
|
||||
for (;;) {
|
||||
merge_events(res_dc, a_dc, b_dc, offset);
|
||||
merge_samples(res_dc, a_dc, b_dc, offset);
|
||||
a_dc = a_dc->next;
|
||||
b_dc = b_dc->next;
|
||||
if (!a_dc || !b_dc)
|
||||
break;
|
||||
res_dc->next = calloc(1, sizeof(*res_dc));
|
||||
res_dc = res_dc->next;
|
||||
if (!res_dc)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
merge_events(&res->dc, &a->dc, &b->dc, offset);
|
||||
merge_samples(&res->dc, &a->dc, &b->dc, offset);
|
||||
struct divecomputer *dc;
|
||||
res->dc = a->dc;
|
||||
memset(&a->dc, 0, sizeof(a->dc));
|
||||
dc = &res->dc;
|
||||
while (dc->next)
|
||||
dc = dc->next;
|
||||
dc->next = calloc(1, sizeof(*dc));
|
||||
*dc->next = b->dc;
|
||||
memset(&b->dc, 0,sizeof(b->dc));
|
||||
remove_redundant_dc(&res->dc);
|
||||
}
|
||||
fixup_dive(res);
|
||||
return res;
|
||||
|
|
22
save-xml.c
22
save-xml.c
|
@ -349,23 +349,19 @@ static void save_trip(FILE *f, dive_trip_t *trip)
|
|||
static void save_dc(FILE *f, struct dive *dive, struct divecomputer *dc)
|
||||
{
|
||||
int i;
|
||||
const char *post = "";
|
||||
|
||||
if (dc->when || dc->vendor || dc->product) {
|
||||
fprintf(f, "<divecomputer");
|
||||
if (dc->vendor)
|
||||
show_utf8(f, dc->vendor, " vendor='", "'", 1);
|
||||
if (dc->product)
|
||||
show_utf8(f, dc->product, " product='", "'", 1);
|
||||
if (dc->when && dc->when != dive->when)
|
||||
show_date(f, dc->when);
|
||||
fprintf(f, ">\n");
|
||||
post = "</divecomputer>\n";
|
||||
}
|
||||
fprintf(f, " <divecomputer");
|
||||
if (dc->vendor)
|
||||
show_utf8(f, dc->vendor, " vendor='", "'", 1);
|
||||
if (dc->product)
|
||||
show_utf8(f, dc->product, " product='", "'", 1);
|
||||
if (dc->when && dc->when != dive->when)
|
||||
show_date(f, dc->when);
|
||||
fprintf(f, ">\n");
|
||||
save_events(f, dc->events);
|
||||
for (i = 0; i < dc->samples; i++)
|
||||
save_sample(f, dc->sample+i);
|
||||
fprintf(f, post);
|
||||
fprintf(f, " </divecomputer>\n");
|
||||
}
|
||||
|
||||
static void save_dive(FILE *f, struct dive *dive)
|
||||
|
|
Loading…
Reference in a new issue