summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorGravatar Berthold Stoeger <bstoeger@mail.tuwien.ac.at>2018-11-10 09:07:42 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2018-11-18 16:50:09 -0800
commit243962a67a41c71f39a098e8f18dafdcd9adb37e (patch)
treec23806d69bf74a5e7d10f3176cc97c129384ad86 /core
parentef98a4ff5ad05b3a1fc51ffb5996d49d1c462a75 (diff)
downloadsubsurface-243962a67a41c71f39a098e8f18dafdcd9adb37e.tar.gz
Dive list: move sort-functionality into core
To make sorting more controlled, move all sorting functions into the core. For this, introduce a "dive_or_trip" structure, which represents a top-level item. Adapt the DiveTripModel accordingly. There are now three sorting functions: 1) dive_less_than 2) trip_less_than 3) dive_or_trip_less_than These should be used by all sorting code. By moving them to a single place, the mess can hopefully be cleaned up. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Diffstat (limited to 'core')
-rw-r--r--core/dive.h7
-rw-r--r--core/divelist.c38
2 files changed, 39 insertions, 6 deletions
diff --git a/core/dive.h b/core/dive.h
index 7356f91a1..76f01a8c0 100644
--- a/core/dive.h
+++ b/core/dive.h
@@ -338,6 +338,12 @@ struct dive {
unsigned char git_id[20];
};
+/* For the top-level list: an entry is either a dive or a trip */
+struct dive_or_trip {
+ struct dive *dive;
+ struct dive_trip *trip;
+};
+
extern void invalidate_dive_cache(struct dive *dive);
extern bool dive_cache_is_valid(const struct dive *dive);
@@ -557,6 +563,7 @@ extern int legacy_format_o2pressures(const struct dive *dive, const struct divec
extern bool dive_less_than(const struct dive *a, const struct dive *b);
extern bool trip_less_than(const struct dive_trip *a, const struct dive_trip *b);
+extern bool dive_or_trip_less_than(struct dive_or_trip a, struct dive_or_trip b);
extern void sort_table(struct dive_table *table);
extern struct dive *fixup_dive(struct dive *dive);
extern void fixup_dc_duration(struct divecomputer *dc);
diff --git a/core/divelist.c b/core/divelist.c
index f9010b958..0fea7594e 100644
--- a/core/divelist.c
+++ b/core/divelist.c
@@ -40,6 +40,7 @@
* void remove_autogen_trips()
* bool dive_less_than(const struct dive *a, const struct dive *b)
* bool trip_less_than(const struct dive_trip *a, const struct dive_trip *b)
+ * bool dive_or_trip_less_than(struct dive_or_trip a, struct dive_or_trip b)
* void sort_table(struct dive_table *table)
* bool is_trip_before_after(const struct dive *dive, bool before)
* void delete_dive_from_table(struct dive_table *table, int idx)
@@ -1559,7 +1560,7 @@ void process_imported_dives(struct dive_table *import_table, bool prefer_importe
struct dive *dive_to_add = import_table->dives[i];
/* Find insertion point. */
- while (j < dive_table.nr && dive_table.dives[j]->when < dive_to_add->when)
+ while (j < dive_table.nr && dive_less_than(dive_table.dives[j], dive_to_add))
j++;
/* Try to merge into previous dive. */
@@ -1742,13 +1743,11 @@ bool dive_less_than(const struct dive *a, const struct dive *b)
return comp_dives(a, b) < 0;
}
-/* Trips are compared according to the first dive in the trip.
- * Even though it shouldn't happen, take care about "empty" trips.
- * Since a dive can only belong to one trip, no two trips should
- * compare as equal
- */
+/* Trips are compared according to the first dive in the trip. */
static int comp_trips(const struct dive_trip *a, const struct dive_trip *b)
{
+ /* This should never happen, nevertheless don't crash on trips
+ * with no (or worse a negative number of) dives. */
if (a->dives.nr <= 0)
return b->dives.nr <= 0 ? 0 : -1;
if (b->dives.nr <= 0)
@@ -1761,6 +1760,33 @@ bool trip_less_than(const struct dive_trip *a, const struct dive_trip *b)
return comp_trips(a, b) < 0;
}
+/* When comparing a dive to a trip, use the first dive of the trip. */
+static int comp_dive_to_trip(struct dive *a, struct dive_trip *b)
+{
+ /* This should never happen, nevertheless don't crash on trips
+ * with no (or worse a negative number of) dives. */
+ if (b->dives.nr <= 0)
+ return -1;
+ return comp_dives(a, b->dives.dives[0]);
+}
+
+static int comp_dive_or_trip(struct dive_or_trip a, struct dive_or_trip b)
+{
+ if (a.dive && b.dive)
+ return comp_dives(a.dive, b.dive);
+ if (a.trip && b.trip)
+ return comp_trips(a.trip, b.trip);
+ if (a.dive)
+ return comp_dive_to_trip(a.dive, b.trip);
+ else
+ return -comp_dive_to_trip(b.dive, a.trip);
+}
+
+bool dive_or_trip_less_than(struct dive_or_trip a, struct dive_or_trip b)
+{
+ return comp_dive_or_trip(a, b) < 0;
+}
+
static int sortfn(const void *_a, const void *_b)
{
const struct dive *a = (const struct dive *)*(const void **)_a;