diff options
-rw-r--r-- | core/dive.h | 2 | ||||
-rw-r--r-- | core/divelist.c | 153 | ||||
-rw-r--r-- | core/divelist.h | 2 | ||||
-rw-r--r-- | core/planner.c | 4 | ||||
-rw-r--r-- | core/plannernotes.c | 23 | ||||
-rw-r--r-- | qt-models/diveplannermodel.cpp | 1 |
6 files changed, 136 insertions, 49 deletions
diff --git a/core/dive.h b/core/dive.h index 74404a223..8e862f691 100644 --- a/core/dive.h +++ b/core/dive.h @@ -911,7 +911,7 @@ struct diveplan { short vpmb_conservatism; struct divedatapoint *dp; int eff_gflow, eff_gfhigh; - unsigned int surface_interval; + int surface_interval; }; struct divedatapoint *plan_add_segment(struct diveplan *diveplan, int duration, int depth, int cylinderid, int po2, bool entered); diff --git a/core/divelist.c b/core/divelist.c index d079b11bf..162d87614 100644 --- a/core/divelist.c +++ b/core/divelist.c @@ -11,7 +11,7 @@ * void get_dive_gas(struct dive *dive, int *o2_p, int *he_p, int *o2low_p) * int total_weight(struct dive *dive) * int get_divenr(struct dive *dive) - * double init_decompression(struct dive *dive) + * int init_decompression(struct dive *dive) * void update_cylinder_related_info(struct dive *dive) * void dump_trip_list(void) * dive_trip_t *find_matching_trip(timestamp_t when) @@ -367,92 +367,169 @@ int get_divesite_idx(struct dive_site *ds) static struct gasmix air = { .o2.permille = O2_IN_AIR, .he.permille = 0 }; /* take into account previous dives until there is a 48h gap between dives */ -/* return true if this is a repetitive dive */ -unsigned int init_decompression(struct dive *dive) +/* return last surface time before this dive or dummy value of 48h */ +/* return negative surface time if dives are overlapping */ +int init_decompression(struct dive *dive) { int i, divenr = -1; - unsigned int surface_time = 0; - timestamp_t when, lasttime = 0, laststart = 0; + int surface_time = 48 * 60 * 60; + timestamp_t last_endtime = 0, last_starttime = 0; bool deco_init = false; double surface_pressure; if (!dive) return false; - surface_pressure = get_surface_pressure_in_mbar(dive, true) / 1000.0; divenr = get_divenr(dive); - when = dive->when; - i = divenr; - if (i < 0) { - i = dive_table.nr - 1; - while (i >= 0 && get_dive(i)->when > when) - --i; + i = divenr >= 0 ? divenr : dive_table.nr; +#if DECO_CALC_DEBUG & 2 + if (i >= 0 && i < dive_table.nr) + printf("\n\n*** Init deco for dive #%d %d\n", i, get_dive(i)->number); + else + printf("\n\n*** Init deco for dive #%d\n", i); +#endif + /* Look at next dive in dive list table and correct i when needed */ + while (i < dive_table.nr - 1) { + struct dive *pdive = get_dive(i); + if (!pdive || pdive->when > dive->when) + break; i++; } + /* Look at previous dive in dive list table and correct i when needed */ + while (i > 0) { + struct dive *pdive = get_dive(i - 1); + if (!pdive || pdive->when < dive->when) + break; + i--; + } +#if DECO_CALC_DEBUG & 2 + printf("Dive number corrected to #%d\n", i); +#endif + last_starttime = dive->when; + /* Walk backwards to check previous dives - how far do we need to go back? */ while (i--) { + if (i == divenr && i > 0) + i--; +#if DECO_CALC_DEBUG & 2 + printf("Check if dive #%d %d has to be considered as prev dive: ", i, get_dive(i)->number); +#endif struct dive *pdive = get_dive(i); /* we don't want to mix dives from different trips as we keep looking * for how far back we need to go */ - if (dive->divetrip && pdive->divetrip != dive->divetrip) + if (dive->divetrip && pdive->divetrip != dive->divetrip) { +#if DECO_CALC_DEBUG & 2 + printf("No - other dive trip\n"); +#endif continue; - if (!pdive || pdive->when >= when || dive_endtime(pdive) + 48 * 60 * 60 < when) + } + if (!pdive || pdive->when >= dive->when || dive_endtime(pdive) + 48 * 60 * 60 < last_starttime) { +#if DECO_CALC_DEBUG & 2 + printf("No\n"); +#endif break; - /* For simultaneous dives, only consider the first */ - if (pdive->when == laststart) - continue; - lasttime = dive_endtime(pdive); + } + last_starttime = pdive->when; +#if DECO_CALC_DEBUG & 2 + printf("Yes\n"); +#endif } - while (++i < (divenr >= 0 ? divenr : dive_table.nr)) { + /* Walk forward an add dives and surface intervals to deco */ + while (++i < dive_table.nr) { +#if DECO_CALC_DEBUG & 2 + printf("Check if dive #%d %d will be really added to deco calc: ", i, get_dive(i)->number); +#endif struct dive *pdive = get_dive(i); /* again skip dives from different trips */ - if (dive->divetrip && dive->divetrip != pdive->divetrip) + if (dive->divetrip && dive->divetrip != pdive->divetrip) { +#if DECO_CALC_DEBUG & 2 + printf("No - other dive trip\n"); +#endif continue; + } /* Don't add future dives */ - if (pdive->when > dive->when) - continue; /* This could be break if the divelist is always sorted */ + if (pdive->when >= dive->when) { +#if DECO_CALC_DEBUG & 2 + printf("No - future or same dive\n"); +#endif + break; + } + /* Don't add the copy of the dive itself */ + if (i == divenr) { +#if DECO_CALC_DEBUG & 2 + printf("No - copy of dive\n"); +#endif + continue; + } +#if DECO_CALC_DEBUG & 2 + printf("Yes\n"); +#endif + surface_pressure = get_surface_pressure_in_mbar(pdive, true) / 1000.0; + /* Is it the first dive we add? */ if (!deco_init) { +#if DECO_CALC_DEBUG & 2 + printf("Init deco\n"); +#endif clear_deco(surface_pressure); deco_init = true; #if DECO_CALC_DEBUG & 2 + printf("Tissues after init:\n"); dump_tissues(); #endif } - if (pdive->when > lasttime) { - surface_time = pdive->when - lasttime; - lasttime = dive_endtime(pdive); + else { + surface_time = pdive->when - last_endtime; + if (surface_time < 0) { +#if DECO_CALC_DEBUG & 2 + printf("Exit because surface intervall is %d\n", surface_time); +#endif + return surface_time; + } add_segment(surface_pressure, &air, surface_time, 0, dive, prefs.decosac); #if DECO_CALC_DEBUG & 2 - printf("after surface intervall of %d:%02u\n", FRACTION(surface_time, 60)); + printf("Tissues after surface intervall of %d:%02u:\n", FRACTION(surface_time, 60)); dump_tissues(); #endif } + add_dive_to_deco(pdive); - laststart = pdive->when; + + last_starttime = pdive->when; + last_endtime = dive_endtime(pdive); clear_vpmb_state(); #if DECO_CALC_DEBUG & 2 - printf("added dive #%d\n", pdive->number); + printf("Tissues after added dive #%d:\n", pdive->number); dump_tissues(); #endif } - /* add the final surface time */ - if (lasttime && dive->when > lasttime) { - surface_time = dive->when - lasttime; - surface_pressure = get_surface_pressure_in_mbar(dive, true) / 1000.0; - add_segment(surface_pressure, &air, surface_time, 0, dive, prefs.decosac); + + surface_pressure = get_surface_pressure_in_mbar(dive, true) / 1000.0; + /* We don't have had a previous dive at all? */ + if (!deco_init) { +#if DECO_CALC_DEBUG & 2 + printf("Init deco\n"); +#endif + clear_deco(surface_pressure); #if DECO_CALC_DEBUG & 2 - printf("after surface intervall of %d:%02u\n", FRACTION(surface_time, 60)); + printf("Tissues after no previous dive, surface time set to 48h:\n"); dump_tissues(); #endif } - if (!deco_init) { - surface_pressure = get_surface_pressure_in_mbar(dive, true) / 1000.0; - clear_deco(surface_pressure); + else { + surface_time = dive->when - last_endtime; + if (surface_time < 0) { #if DECO_CALC_DEBUG & 2 - printf("no previous dive\n"); + printf("Exit because surface intervall is %d\n", surface_time); +#endif + return surface_time; + } + add_segment(surface_pressure, &air, surface_time, 0, dive, prefs.decosac); +#if DECO_CALC_DEBUG & 2 + printf("Tissues after surface intervall of %d:%02u:\n", FRACTION(surface_time, 60)); dump_tissues(); #endif } + // I do not dare to remove this call. We don't need the result but it might have side effects. Bummer. tissue_tolerance_calc(dive, surface_pressure); return surface_time; diff --git a/core/divelist.h b/core/divelist.h index 74b616890..44f0bf0b0 100644 --- a/core/divelist.h +++ b/core/divelist.h @@ -15,7 +15,7 @@ extern void update_cylinder_related_info(struct dive *); extern void mark_divelist_changed(int); extern int unsaved_changes(void); extern void remove_autogen_trips(void); -extern unsigned int init_decompression(struct dive *dive); +extern int init_decompression(struct dive *dive); /* divelist core logic functions */ extern void process_dives(bool imported, bool prefer_imported); diff --git a/core/planner.c b/core/planner.c index 8010979d9..18f3c8701 100644 --- a/core/planner.c +++ b/core/planner.c @@ -127,7 +127,7 @@ void interpolate_transition(struct dive *dive, duration_t t0, duration_t t1, dep } /* returns the tissue tolerance at the end of this (partial) dive */ -unsigned int tissue_at_end(struct dive *dive, struct deco_state **cached_datap) +int tissue_at_end(struct dive *dive, struct deco_state **cached_datap) { struct divecomputer *dc; struct sample *sample, *psample; @@ -135,7 +135,7 @@ unsigned int tissue_at_end(struct dive *dive, struct deco_state **cached_datap) depth_t lastdepth = {}; duration_t t0 = {}, t1 = {}; struct gasmix gas; - unsigned int surface_interval = 0; + int surface_interval = 0; if (!dive) return 0; diff --git a/core/plannernotes.c b/core/plannernotes.c index ffbf0b1cb..131820a5b 100644 --- a/core/plannernotes.c +++ b/core/plannernotes.c @@ -85,20 +85,29 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d len = show_disclaimer ? snprintf(buffer, sz_buffer, "<div><b>%s</b><br></div>", disclaimer) : 0; - if (diveplan->surface_interval > 60) { - len += snprintf(buffer + len, sz_buffer - len, "<div><b>%s (%s) %s %d:%02d) %s %s<br>", + if (diveplan->surface_interval < 0) { + len += snprintf(buffer + len, sz_buffer - len, "<div><b>%s (%s) %s<br>", translate("gettextFromC", "Subsurface"), subsurface_canonical_version(), - translate("gettextFromC", "dive plan</b> (surface interval "), - FRACTION(diveplan->surface_interval / 60, 60), - translate("gettextFromC", "created on"), - get_current_date()); - } else { + translate("gettextFromC", "dive plan</b> (Overlapping dives detected)")); + dive->notes = strdup(buffer); + free((void *)buffer); + free((void *)temp); + return; + } else if (diveplan->surface_interval >= 48 * 60 *60) { len += snprintf(buffer + len, sz_buffer - len, "<div><b>%s (%s) %s %s</b><br>", translate("gettextFromC", "Subsurface"), subsurface_canonical_version(), translate("gettextFromC", "dive plan</b> created on"), get_current_date()); + } else { + len += snprintf(buffer + len, sz_buffer - len, "<div><b>%s (%s) %s %d:%02d) %s %s<br>", + translate("gettextFromC", "Subsurface"), + subsurface_canonical_version(), + translate("gettextFromC", "dive plan</b> (surface interval "), + FRACTION(diveplan->surface_interval / 60, 60), + translate("gettextFromC", "created on"), + get_current_date()); } if (prefs.display_variations) diff --git a/qt-models/diveplannermodel.cpp b/qt-models/diveplannermodel.cpp index 0c90b0a48..10d912846 100644 --- a/qt-models/diveplannermodel.cpp +++ b/qt-models/diveplannermodel.cpp @@ -1101,6 +1101,7 @@ void DivePlannerPointsModel::createPlan(bool replanCopy) copy_dive(&displayed_dive, current_dive); } mark_divelist_changed(true); + sort_table(&dive_table); // Remove and clean the diveplan, so we don't delete // the dive by mistake. |