mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
Implement get_divemode() to find the divemode at a particular time
Replaced a rather cumbersome function that that did the above. Upon the suggestion of Robert Helling who proposed a much shorter way, this new function replaced the previous ones. This necessitated changes to divelist.c, profile.c and plannernotes.c, as well as dive.c/h. Signed-off-by: Willem Ferguson <willemferguson@zoology.up.ac.za>
This commit is contained in:
parent
b9174332d5
commit
cad4eb39c4
5 changed files with 28 additions and 62 deletions
52
core/dive.c
52
core/dive.c
|
@ -241,44 +241,23 @@ void add_extra_data(struct divecomputer *dc, const char *key, const char *value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct event *get_next_divemodechange(struct event **evd, bool update_pointer)
|
/* Find the divemode at time 'time' (in seconds) into the dive. Sequentially step through the divemode-change events,
|
||||||
{ /* Starting at the event pointed to by evd, find the next divemode change event and initialise its
|
* saving the dive mode for each event. When the events occur AFTER 'time' seconds, the last stored divemode
|
||||||
* type and divemode. Requires an external pointer (evd) to a divemode change event, usually
|
* is returned. This function is self-tracking, relying on setting the event pointer 'evp' so that, in each iteration
|
||||||
* a copy of dc->events. This function is self-tracking if update_pointer is TRUE and the value
|
* that calls this function, the search does not have to begin at the first event of the dive */
|
||||||
* of evd needs no manipulation outside of this function. If update_pointer is FALSE, pointer evd
|
enum dive_comp_type get_current_divemode(struct divecomputer *dc, int time, struct event **evp, enum dive_comp_type *divemode)
|
||||||
* is NOT updated with the address of the last examined event in the while() loop. */
|
{
|
||||||
struct event *ev = *evd;
|
struct event *ev = *evp;
|
||||||
while (ev) { // Step through the events.
|
if (*divemode == UNDEF_COMP_TYPE) {
|
||||||
for (int i=0; i<3; i++) { // For each event name search for one of the above strings
|
*divemode = dc->divemode;
|
||||||
if (!strcmp(ev->name,divemode_text[i])) { // if the event name is one of the divemode names
|
ev = dc ? dc->events : NULL;
|
||||||
ev->divemode = i; // set the event type to the dive mode
|
|
||||||
if (update_pointer)
|
|
||||||
*evd = ev->next;
|
|
||||||
return (ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ev = ev->next;
|
|
||||||
}
|
}
|
||||||
if (update_pointer)
|
while (ev && ev->time.seconds < time) {
|
||||||
*evd = NULL;
|
*divemode = (enum dive_comp_type) ev->value;
|
||||||
return (NULL);
|
ev = get_next_event(ev->next, "modechange");
|
||||||
}
|
|
||||||
|
|
||||||
enum dive_comp_type get_divemode_at_time(struct divecomputer *dc, int dtime, struct event **ev_dmc)
|
|
||||||
{ /* For a particular dive computer and its linked list of events, find the divemode dtime seconds
|
|
||||||
* into the dive. Requires an external pointer (ev_dmc) to a divemode change event, usually
|
|
||||||
* initialised by a call to get_next_divemodechange(©-of-dc->events). This function is self-tracking
|
|
||||||
* and the value of ev_dmc needs no manipulation outside of this function. */
|
|
||||||
enum dive_comp_type mode = dc->divemode;
|
|
||||||
struct event *ev_last = *ev_dmc, *ev = *ev_dmc; // ev_dmc points to event initialised by get_next_divemodechange()
|
|
||||||
while (ev && (dtime >= ev->time.seconds)) { // If dtime is AFTER this event time, store divemode
|
|
||||||
mode = ev->divemode;
|
|
||||||
ev_last = ev;
|
|
||||||
// ev = peek_next_divemodechange(ev->next); // peek at the time of the following divemode change event
|
|
||||||
ev = get_next_divemodechange(&ev->next, FALSE);
|
|
||||||
}
|
}
|
||||||
*ev_dmc = ev_last;
|
*evp = ev;
|
||||||
return (mode);
|
return *divemode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this returns a pointer to static variable - so use it right away after calling */
|
/* this returns a pointer to static variable - so use it right away after calling */
|
||||||
|
@ -291,7 +270,6 @@ struct gasmix *get_gasmix_from_event(struct dive *dive, struct event *ev)
|
||||||
return &dive->cylinder[index].gasmix;
|
return &dive->cylinder[index].gasmix;
|
||||||
return &ev->gas.mix;
|
return &ev->gas.mix;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &dummy;
|
return &dummy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -362,6 +362,7 @@ struct dive_components {
|
||||||
unsigned int weights : 1;
|
unsigned int weights : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern enum dive_comp_type get_current_divemode(struct divecomputer *dc, int time, struct event **evp, enum dive_comp_type *divemode);
|
||||||
extern struct event *get_next_divemodechange(struct event **evd, bool update_pointer);
|
extern struct event *get_next_divemodechange(struct event **evd, bool update_pointer);
|
||||||
extern enum dive_comp_type get_divemode_at_time(struct divecomputer *dc, int dtime, struct event **ev_dmc);
|
extern enum dive_comp_type get_divemode_at_time(struct divecomputer *dc, int dtime, struct event **ev_dmc);
|
||||||
|
|
||||||
|
|
|
@ -414,9 +414,9 @@ static void add_dive_to_deco(struct deco_state *ds, struct dive *dive)
|
||||||
{
|
{
|
||||||
struct divecomputer *dc = &dive->dc;
|
struct divecomputer *dc = &dive->dc;
|
||||||
struct gasmix *gasmix = NULL;
|
struct gasmix *gasmix = NULL;
|
||||||
struct event *ev = NULL;
|
|
||||||
struct event *ev_dmc = dc->events, *ev_dmt = get_next_divemodechange(&ev_dmc, TRUE);
|
|
||||||
int i;
|
int i;
|
||||||
|
struct event *ev = NULL, *evd = NULL;
|
||||||
|
enum dive_comp_type current_divemode = UNDEF_COMP_TYPE;
|
||||||
|
|
||||||
if (!dc)
|
if (!dc)
|
||||||
return;
|
return;
|
||||||
|
@ -432,7 +432,7 @@ static void add_dive_to_deco(struct deco_state *ds, struct dive *dive)
|
||||||
int depth = interpolate(psample->depth.mm, sample->depth.mm, j - t0, t1 - t0);
|
int depth = interpolate(psample->depth.mm, sample->depth.mm, j - t0, t1 - t0);
|
||||||
gasmix = get_gasmix(dive, dc, j, &ev, gasmix);
|
gasmix = get_gasmix(dive, dc, j, &ev, gasmix);
|
||||||
add_segment(ds, depth_to_bar(depth, dive), gasmix, 1, sample->setpoint.mbar,
|
add_segment(ds, depth_to_bar(depth, dive), gasmix, 1, sample->setpoint.mbar,
|
||||||
get_divemode_at_time(dc, j, &ev_dmt), dive->sac);
|
get_current_divemode(&dive->dc, j, &evd, ¤t_divemode), dive->sac);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -539,10 +539,8 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
|
||||||
bool o2warning_exist = false;
|
bool o2warning_exist = false;
|
||||||
enum dive_comp_type current_divemode;
|
enum dive_comp_type current_divemode;
|
||||||
double amb;
|
double amb;
|
||||||
struct event *nextev, *evd = dive->dc.events;
|
struct event *evd = NULL;
|
||||||
|
current_divemode = UNDEF_COMP_TYPE;
|
||||||
current_divemode = dive->dc.divemode;
|
|
||||||
nextev = get_next_divemodechange(&evd, TRUE);
|
|
||||||
|
|
||||||
if (dive->dc.divemode != CCR) {
|
if (dive->dc.divemode != CCR) {
|
||||||
while (dp) {
|
while (dp) {
|
||||||
|
@ -550,11 +548,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
|
||||||
struct gas_pressures pressures;
|
struct gas_pressures pressures;
|
||||||
struct gasmix *gasmix = &dive->cylinder[dp->cylinderid].gasmix;
|
struct gasmix *gasmix = &dive->cylinder[dp->cylinderid].gasmix;
|
||||||
|
|
||||||
if (nextev && (dp->time >= nextev->time.seconds)) { // If there are divemode changes and divedatapoint time
|
current_divemode = get_current_divemode(&dive->dc, dp->time, &evd, ¤t_divemode);
|
||||||
current_divemode = nextev->divemode; // has reached that of the current divemode event, then set the
|
|
||||||
nextev = get_next_divemodechange(&evd, TRUE); // current divemode and find the next divemode event
|
|
||||||
}
|
|
||||||
|
|
||||||
amb = depth_to_atm(dp->depth.mm, dive);
|
amb = depth_to_atm(dp->depth.mm, dive);
|
||||||
fill_pressures(&pressures, amb, gasmix, (current_divemode == OC) ? 0.0 : amb * gasmix->o2.permille / 1000.0, current_divemode);
|
fill_pressures(&pressures, amb, gasmix, (current_divemode == OC) ? 0.0 : amb * gasmix->o2.permille / 1000.0, current_divemode);
|
||||||
|
|
||||||
|
|
|
@ -996,7 +996,6 @@ void calculate_deco_information(struct deco_state *ds, struct deco_state *planne
|
||||||
double surface_pressure = (dc->surface_pressure.mbar ? dc->surface_pressure.mbar : get_surface_pressure_in_mbar(dive, true)) / 1000.0;
|
double surface_pressure = (dc->surface_pressure.mbar ? dc->surface_pressure.mbar : get_surface_pressure_in_mbar(dive, true)) / 1000.0;
|
||||||
bool first_iteration = true;
|
bool first_iteration = true;
|
||||||
int prev_deco_time = 10000000, time_deep_ceiling = 0;
|
int prev_deco_time = 10000000, time_deep_ceiling = 0;
|
||||||
enum dive_comp_type current_divemode;
|
|
||||||
|
|
||||||
if (!in_planner()) {
|
if (!in_planner()) {
|
||||||
ds->deco_time = 0;
|
ds->deco_time = 0;
|
||||||
|
@ -1018,16 +1017,16 @@ void calculate_deco_information(struct deco_state *ds, struct deco_state *planne
|
||||||
if (decoMode() == VPMB)
|
if (decoMode() == VPMB)
|
||||||
ds->first_ceiling_pressure.mbar = depth_to_mbar(first_ceiling, dive);
|
ds->first_ceiling_pressure.mbar = depth_to_mbar(first_ceiling, dive);
|
||||||
struct gasmix *gasmix = NULL;
|
struct gasmix *gasmix = NULL;
|
||||||
struct event *ev = NULL, *ev_dmc = dc->events, *ev_dmt = get_next_divemodechange(&ev_dmc, TRUE);
|
struct event *ev = NULL, *evd = NULL;
|
||||||
|
enum dive_comp_type current_divemode = UNDEF_COMP_TYPE;
|
||||||
|
|
||||||
for (i = 1; i < pi->nr; i++) {
|
for (i = 1; i < pi->nr; i++) {
|
||||||
struct plot_data *entry = pi->entry + i;
|
struct plot_data *entry = pi->entry + i;
|
||||||
int j, t0 = (entry - 1)->sec, t1 = entry->sec;
|
int j, t0 = (entry - 1)->sec, t1 = entry->sec;
|
||||||
int time_stepsize = 20;
|
int time_stepsize = 20;
|
||||||
|
|
||||||
current_divemode = get_divemode_at_time(dc, entry->sec, &ev_dmt);
|
current_divemode = get_current_divemode(dc, entry->sec, &evd, ¤t_divemode);
|
||||||
gasmix = get_gasmix(dive, dc, t1, &ev, gasmix);
|
gasmix = get_gasmix(dive, dc, t1, &ev, gasmix);
|
||||||
|
|
||||||
entry->ambpressure = depth_to_bar(entry->depth, dive);
|
entry->ambpressure = depth_to_bar(entry->depth, dive);
|
||||||
entry->gfline = get_gf(ds, entry->ambpressure, dive) * (100.0 - AMB_PERCENTAGE) + AMB_PERCENTAGE;
|
entry->gfline = get_gf(ds, entry->ambpressure, dive) * (100.0 - AMB_PERCENTAGE) + AMB_PERCENTAGE;
|
||||||
if (t0 > t1) {
|
if (t0 > t1) {
|
||||||
|
@ -1205,24 +1204,18 @@ static int calculate_ccr_po2(struct plot_data *entry, struct divecomputer *dc)
|
||||||
static void calculate_gas_information_new(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
|
static void calculate_gas_information_new(struct dive *dive, struct divecomputer *dc, struct plot_info *pi)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
enum dive_comp_type current_divemode;
|
|
||||||
double amb_pressure;
|
double amb_pressure;
|
||||||
struct gasmix *gasmix = NULL;
|
struct gasmix *gasmix = NULL;
|
||||||
struct event *nextev, *evg = NULL, *evd = dc->events;
|
struct event *evg = NULL, *evd = NULL;
|
||||||
|
enum dive_comp_type current_divemode = UNDEF_COMP_TYPE;
|
||||||
current_divemode = dc->divemode;
|
|
||||||
nextev = get_next_divemodechange(&evd, TRUE);
|
|
||||||
|
|
||||||
for (i = 1; i < pi->nr; i++) {
|
for (i = 1; i < pi->nr; i++) {
|
||||||
int fn2, fhe;
|
int fn2, fhe;
|
||||||
struct plot_data *entry = pi->entry + i;
|
struct plot_data *entry = pi->entry + i;
|
||||||
|
|
||||||
gasmix = get_gasmix(dive, dc, entry->sec, &evg, gasmix);
|
gasmix = get_gasmix(dive, dc, entry->sec, &evg, gasmix);
|
||||||
if (nextev && (entry->sec > nextev->time.seconds)) { // If there are divemode changes and sample time
|
|
||||||
current_divemode = nextev->divemode; // has reached that of the current divemode event, then set the
|
|
||||||
nextev = get_next_divemodechange(&evd, TRUE); // current divemode and find the next divemode event
|
|
||||||
}
|
|
||||||
amb_pressure = depth_to_bar(entry->depth, dive);
|
amb_pressure = depth_to_bar(entry->depth, dive);
|
||||||
|
current_divemode = get_current_divemode(dc, entry->sec, &evd, ¤t_divemode);
|
||||||
fill_pressures(&entry->pressures, amb_pressure, gasmix, (current_divemode == OC) ? 0.0 : entry->o2pressure.mbar / 1000.0, current_divemode);
|
fill_pressures(&entry->pressures, amb_pressure, gasmix, (current_divemode == OC) ? 0.0 : entry->o2pressure.mbar / 1000.0, current_divemode);
|
||||||
fn2 = (int)(1000.0 * entry->pressures.n2 / amb_pressure);
|
fn2 = (int)(1000.0 * entry->pressures.n2 / amb_pressure);
|
||||||
fhe = (int)(1000.0 * entry->pressures.he / amb_pressure);
|
fhe = (int)(1000.0 * entry->pressures.he / amb_pressure);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue