diff options
author | Berthold Stoeger <bstoeger@mail.tuwien.ac.at> | 2018-10-06 09:21:27 +0200 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2018-10-07 05:41:48 +0300 |
commit | c32e71e64d97016d201aea26f0623de6cd65d74d (patch) | |
tree | d2dbd6a326701aba1e031a5f6508a5d811e2a34f | |
parent | cec0b703652ffb4ab53fd792bee0cbf095b38cca (diff) | |
download | subsurface-c32e71e64d97016d201aea26f0623de6cd65d74d.tar.gz |
Dive information: fix surface interval calculation
The old surface interval calculation had fundamental issues:
1) process_all_dives(), which calculates the statistics over *all*
dives was used to get the pointer to the previous dive.
2) If two dives in the table had the same time, one of those would
have been considered the "previous" dive.
3) If the dive, for which the surface interval is calculated is
not yet in the table, no previous dive would be determined.
Fix all this by creating a get_surface_interval() function and
removing the "get previous dive" functionality of process_all_dives().
Remove the process_all_dives() call from TabDiveInformation::updateData().
Reported-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
-rw-r--r-- | core/divelist.c | 29 | ||||
-rw-r--r-- | core/divelist.h | 1 | ||||
-rw-r--r-- | core/statistics.c | 10 | ||||
-rw-r--r-- | core/statistics.h | 2 | ||||
-rw-r--r-- | desktop-widgets/tab-widgets/TabDiveInformation.cpp | 9 | ||||
-rw-r--r-- | desktop-widgets/tab-widgets/maintab.cpp | 4 | ||||
-rw-r--r-- | export-html.cpp | 6 |
7 files changed, 38 insertions, 23 deletions
diff --git a/core/divelist.c b/core/divelist.c index 84290e6b6..94adc92dc 100644 --- a/core/divelist.c +++ b/core/divelist.c @@ -1420,3 +1420,32 @@ void sort_table(struct dive_table *table) { qsort(table->dives, table->nr, sizeof(struct dive *), sortfn); } + +/* + * Calculate surface interval for dive starting at "when". Currently, we + * might display dives which are not yet in the divelist, therefore the + * input parameter is a timestamp. + * If the given dive starts during a different dive, the surface interval + * is 0. If we can't determine a surface interval (first dive), <0 is + * returned. This does *not* consider pathological cases such as dives + * that happened inside other dives. The interval will always be calculated + * with respect to the dive that started previously. + */ +timestamp_t get_surface_interval(timestamp_t when) +{ + int i; + timestamp_t prev_end; + + /* find previous dive. might want to use a binary search. */ + for (i = dive_table.nr - 1; i >= 0; --i) { + if (dive_table.dives[i]->when < when) + break; + } + if (i < 0) + return -1; + + prev_end = dive_endtime(dive_table.dives[i]); + if (prev_end > when) + return 0; + return when - prev_end; +} diff --git a/core/divelist.h b/core/divelist.h index 937909d2b..af47d0f23 100644 --- a/core/divelist.h +++ b/core/divelist.h @@ -42,6 +42,7 @@ extern struct dive *first_selected_dive(); extern struct dive *last_selected_dive(); extern bool is_trip_before_after(const struct dive *dive, bool before); extern void set_dive_nr_for_current_dive(); +extern timestamp_t get_surface_interval(timestamp_t when); int get_min_datafile_version(); void reset_min_datafile_version(); diff --git a/core/statistics.c b/core/statistics.c index beeb258a6..b25080a9f 100644 --- a/core/statistics.c +++ b/core/statistics.c @@ -3,7 +3,7 @@ * * core logic for the Info & Stats page - * char *get_minutes(int seconds); - * void process_all_dives(struct dive *dive, struct dive **prev_dive); + * void process_all_dives(); */ #include "gettext.h" #include <string.h> @@ -91,7 +91,7 @@ char *get_minutes(int seconds) return buf; } -void process_all_dives(struct dive *dive, struct dive **prev_dive) +void process_all_dives() { int idx; struct dive *dp; @@ -105,7 +105,6 @@ void process_all_dives(struct dive *dive, struct dive **prev_dive) dive_trip_t *trip_ptr = 0; unsigned int size, tsize; - *prev_dive = NULL; memset(&stats, 0, sizeof(stats)); if (dive_table.nr > 0) { stats.shortest_time.seconds = dive_table.dives[0]->duration.seconds; @@ -152,11 +151,6 @@ void process_all_dives(struct dive *dive, struct dive **prev_dive) /* this relies on the fact that the dives in the dive_table * are in chronological order */ for_each_dive (idx, dp) { - if (dive && dp->when == dive->when) { - /* that's the one we are showing */ - if (idx > 0) - *prev_dive = dive_table.dives[idx - 1]; - } process_dive(dp, &stats); /* yearly statistics */ diff --git a/core/statistics.h b/core/statistics.h index 597edfb94..7766d3154 100644 --- a/core/statistics.h +++ b/core/statistics.h @@ -48,7 +48,7 @@ extern stats_t *stats_by_trip; extern stats_t *stats_by_type; extern char *get_minutes(int seconds); -extern void process_all_dives(struct dive *dive, struct dive **prev_dive); +extern void process_all_dives(); extern void get_gas_used(struct dive *dive, volume_t gases[MAX_CYLINDERS]); extern void process_selected_dives(void); void selected_dives_gas_parts(volume_t *o2_tot, volume_t *he_tot); diff --git a/desktop-widgets/tab-widgets/TabDiveInformation.cpp b/desktop-widgets/tab-widgets/TabDiveInformation.cpp index a4f8f455f..aff781a3b 100644 --- a/desktop-widgets/tab-widgets/TabDiveInformation.cpp +++ b/desktop-widgets/tab-widgets/TabDiveInformation.cpp @@ -77,12 +77,9 @@ void TabDiveInformation::updateData() ui->diveTimeText->setText(get_dive_duration_string(displayed_dive.duration.seconds, tr("h"), tr("min"), tr("sec"), " ", displayed_dive.dc.divemode == FREEDIVE)); - struct dive *prevd; - process_all_dives(&displayed_dive, &prevd); - - if (prevd) - ui->surfaceIntervalText->setText(get_dive_surfint_string(displayed_dive.when - (dive_endtime(prevd)), tr("d"), tr("h"), tr("min"))); - + timestamp_t surface_interval = get_surface_interval(displayed_dive.when); + if (surface_interval >= 0) + ui->surfaceIntervalText->setText(get_dive_surfint_string(surface_interval, tr("d"), tr("h"), tr("min"))); else ui->surfaceIntervalText->clear(); diff --git a/desktop-widgets/tab-widgets/maintab.cpp b/desktop-widgets/tab-widgets/maintab.cpp index eb8292b1a..ffcb70f5a 100644 --- a/desktop-widgets/tab-widgets/maintab.cpp +++ b/desktop-widgets/tab-widgets/maintab.cpp @@ -429,10 +429,8 @@ void MainTab::updateDiveInfo(bool clear) // If exactly one trip has been selected, we show the location / notes // for the trip in the Info tab, otherwise we show the info of the // selected_dive - struct dive *prevd; - process_selected_dives(); - process_all_dives(&displayed_dive, &prevd); + process_all_dives(); for (auto widget : extraWidgets) { widget->updateData(); diff --git a/export-html.cpp b/export-html.cpp index f66bd6909..fecbb5235 100644 --- a/export-html.cpp +++ b/export-html.cpp @@ -54,11 +54,7 @@ int main(int argc, char **argv) prefs.units = git_prefs.units; // populate the statistics - struct dive *d = get_dive(0); - struct dive *pd; - if (d) { - process_all_dives(d, &pd); - } + process_all_dives(); // now set up the export settings to create the HTML export struct htmlExportSetting hes; |