core: make calculate_cns() member of dive_table

This function implicitely accessed the global divelog. To make
that explicit make it a member of dive_table, such that the
caller must access it via the global variable.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-06-18 22:23:57 +02:00 committed by bstoeger
parent f3b8e3c4aa
commit b34116e2e2
8 changed files with 68 additions and 67 deletions

View file

@ -1101,7 +1101,7 @@ void AddCylinder::undo()
{
for (size_t i = 0; i < dives.size(); ++i) {
remove_cylinder(dives[i], indexes[i]);
update_cylinder_related_info(dives[i]);
divelog.dives.update_cylinder_related_info(dives[i]);
emit diveListNotifier.cylinderRemoved(dives[i], indexes[i]);
invalidate_dive_cache(dives[i]); // Ensure that dive is written in git_save()
}
@ -1114,7 +1114,7 @@ void AddCylinder::redo()
int index = first_hidden_cylinder(d);
indexes.push_back(index);
add_cylinder(&d->cylinders, index, cyl);
update_cylinder_related_info(d);
divelog.dives.update_cylinder_related_info(d);
emit diveListNotifier.cylinderAdded(d, index);
invalidate_dive_cache(d); // Ensure that dive is written in git_save()
}
@ -1201,7 +1201,7 @@ void RemoveCylinder::undo()
std::vector<int> mapping = get_cylinder_map_for_add(dives[i]->cylinders.size(), indexes[i]);
add_cylinder(&dives[i]->cylinders, indexes[i], cyl[i]);
cylinder_renumber(*dives[i], &mapping[0]);
update_cylinder_related_info(dives[i]);
divelog.dives.update_cylinder_related_info(dives[i]);
emit diveListNotifier.cylinderAdded(dives[i], indexes[i]);
invalidate_dive_cache(dives[i]); // Ensure that dive is written in git_save()
}
@ -1213,7 +1213,7 @@ void RemoveCylinder::redo()
std::vector<int> mapping = get_cylinder_map_for_remove(dives[i]->cylinders.size(), indexes[i]);
remove_cylinder(dives[i], indexes[i]);
cylinder_renumber(*dives[i], &mapping[0]);
update_cylinder_related_info(dives[i]);
divelog.dives.update_cylinder_related_info(dives[i]);
emit diveListNotifier.cylinderRemoved(dives[i], indexes[i]);
invalidate_dive_cache(dives[i]); // Ensure that dive is written in git_save()
}
@ -1273,7 +1273,7 @@ void EditCylinder::redo()
const std::string &name = cyl[i].type.description;
set_tank_info_data(tank_info_table, name, cyl[i].type.size, cyl[i].type.workingpressure);
std::swap(*get_cylinder(dives[i], indexes[i]), cyl[i]);
update_cylinder_related_info(dives[i]);
divelog.dives.update_cylinder_related_info(dives[i]);
emit diveListNotifier.cylinderEdited(dives[i], indexes[i]);
invalidate_dive_cache(dives[i]); // Ensure that dive is written in git_save()
}

View file

@ -1092,7 +1092,7 @@ struct dive *fixup_dive(struct dive *dive)
if (same_rounded_pressure(cyl.sample_end, cyl.end))
cyl.end.mbar = 0;
}
update_cylinder_related_info(dive);
divelog.dives.update_cylinder_related_info(dive);
for (auto &ws: dive->weightsystems)
add_weightsystem_description(ws);
/* we should always have a uniq ID as that gets assigned during dive creation,

View file

@ -181,15 +181,15 @@ static int calculate_otu(const struct dive *dive)
po2 for each segment. Empirical testing showed that, for large changes in depth, the cns calculation for the mean po2
value is extremely close, if not identical to the additive calculations for 0.1 bar increments in po2 from the start
to the end of the segment, assuming a constant rate of change in po2 (i.e. depth) with time. */
static double calculate_cns_dive(const struct dive *dive)
static double calculate_cns_dive(const struct dive &dive)
{
const struct divecomputer *dc = &dive->dcs[0];
const struct divecomputer *dc = &dive.dcs[0];
double cns = 0.0;
double rate;
/* Calculate the CNS for each sample in this dive and sum them */
for (auto [psample, sample]: pairwise_range(dc->samples)) {
int t = sample.time.seconds - psample.time.seconds;
int po2 = get_sample_o2(dive, dc, sample, psample);
int po2 = get_sample_o2(&dive, dc, sample, psample);
/* Don't increase CNS when po2 below 500 matm */
if (po2 <= 500)
continue;
@ -204,7 +204,7 @@ static double calculate_cns_dive(const struct dive *dive)
/* this only gets called if dive->maxcns == 0 which means we know that
* none of the divecomputers has tracked any CNS for us
* so we calculated it "by hand" */
static int calculate_cns(struct dive *dive)
int dive_table::calculate_cns(struct dive *dive) const
{
double cns = 0.0;
timestamp_t last_starttime, last_endtime = 0;
@ -213,27 +213,25 @@ static int calculate_cns(struct dive *dive)
if (dive->cns)
return dive->cns;
size_t divenr = divelog.dives.get_idx(dive);
size_t divenr = get_idx(dive);
int nr_dives = static_cast<int>(size());
int i = divenr != std::string::npos ? static_cast<int>(divenr)
: static_cast<int>(divelog.dives.size());
int nr_dives = static_cast<int>(divelog.dives.size());
: nr_dives;
#if DECO_CALC_DEBUG & 2
if (static_cast<size_t>(i) < divelog.table->size())
printf("\n\n*** CNS for dive #%d %d\n", i, (*divelog.table)[i]->number);
if (static_cast<size_t>(i) < size())
printf("\n\n*** CNS for dive #%d %d\n", i, ()[i]->number);
else
printf("\n\n*** CNS for dive #%d\n", i);
#endif
/* Look at next dive in dive list table and correct i when needed */
while (i < nr_dives - 1) {
struct dive *pdive = get_dive(i);
if (!pdive || pdive->when > dive->when)
if ((*this)[i]->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)
if ((*this)[i - 1]->when < dive->when)
break;
i--;
}
@ -246,24 +244,24 @@ static int calculate_cns(struct dive *dive)
if (static_cast<size_t>(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);
printf("Check if dive #%d %d has to be considered as prev dive: ", i, (*this)[i]->number);
#endif
struct dive *pdive = get_dive(i);
const struct dive &pdive = *(*this)[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 >= dive->when || pdive->endtime() + 12 * 60 * 60 < last_starttime) {
if (pdive.when >= dive->when || pdive.endtime() + 12 * 60 * 60 < last_starttime) {
#if DECO_CALC_DEBUG & 2
printf("No\n");
#endif
break;
}
last_starttime = pdive->when;
last_starttime = pdive.when;
#if DECO_CALC_DEBUG & 2
printf("Yes\n");
#endif
@ -271,18 +269,18 @@ static int calculate_cns(struct dive *dive)
/* Walk forward and add dives and surface intervals to CNS */
while (++i < nr_dives) {
#if DECO_CALC_DEBUG & 2
printf("Check if dive #%d %d will be really added to CNS calc: ", i, get_dive(i)->number);
printf("Check if dive #%d %d will be really added to CNS calc: ", i, (*this)[i]->number);
#endif
struct dive *pdive = get_dive(i);
const struct dive &pdive = *(*this)[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) {
if (pdive.when >= dive->when) {
#if DECO_CALC_DEBUG & 2
printf("No - future or same dive\n");
#endif
@ -301,7 +299,7 @@ static int calculate_cns(struct dive *dive)
/* CNS reduced with 90min halftime during surface interval */
if (last_endtime)
cns /= pow(2, (pdive->when - last_endtime) / (90.0 * 60.0));
cns /= pow(2, (pdive.when - last_endtime) / (90.0 * 60.0));
#if DECO_CALC_DEBUG & 2
printf("CNS after surface interval: %f\n", cns);
#endif
@ -311,8 +309,8 @@ static int calculate_cns(struct dive *dive)
printf("CNS after previous dive: %f\n", cns);
#endif
last_starttime = pdive->when;
last_endtime = pdive->endtime();
last_starttime = pdive.when;
last_endtime = pdive.endtime();
}
/* CNS reduced with 90min halftime during surface interval */
@ -322,7 +320,7 @@ static int calculate_cns(struct dive *dive)
printf("CNS after last surface interval: %f\n", cns);
#endif
cns += calculate_cns_dive(dive);
cns += calculate_cns_dive(*dive);
#if DECO_CALC_DEBUG & 2
printf("CNS after dive: %f\n", cns);
#endif
@ -391,9 +389,9 @@ static int calculate_sac(const struct dive *dive)
}
/* for now we do this based on the first divecomputer */
static void add_dive_to_deco(struct deco_state *ds, struct dive *dive, bool in_planner)
static void add_dive_to_deco(struct deco_state *ds, const struct dive *dive, bool in_planner)
{
struct divecomputer *dc = &dive->dcs[0];
const struct divecomputer *dc = &dive->dcs[0];
gasmix_loop loop(*dive, dive->dcs[0]);
divemode_loop loop_d(dive->dcs[0]);
@ -417,7 +415,7 @@ static void add_dive_to_deco(struct deco_state *ds, struct dive *dive, bool in_p
/* return negative surface time if dives are overlapping */
/* The place you call this function is likely the place where you want
* to create the deco_state */
int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_planner)
int dive_table::init_decompression(struct deco_state *ds, const struct dive *dive, bool in_planner) const
{
int surface_time = 48 * 60 * 60;
timestamp_t last_endtime = 0, last_starttime = 0;
@ -427,27 +425,25 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
if (!dive)
return false;
int nr_dives = static_cast<int>(divelog.dives.size());
size_t divenr = divelog.dives.get_idx(dive);
int nr_dives = static_cast<int>(size());
size_t divenr = get_idx(dive);
int i = divenr != std::string::npos ? static_cast<int>(divenr)
: static_cast<int>(divelog.dives.size());
: nr_dives;
#if DECO_CALC_DEBUG & 2
if (i < dive_table.nr)
printf("\n\n*** Init deco for dive #%d %d\n", i, get_dive(i)->number);
printf("\n\n*** Init deco for dive #%d %d\n", i, (*this)[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 + 1 < nr_dives) {
struct dive *pdive = get_dive(i);
if (!pdive || pdive->when > dive->when)
if ((*this)[i]->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)
if ((*this)[i - 1]->when < dive->when)
break;
i--;
}
@ -460,24 +456,24 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
if (static_cast<size_t>(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);
printf("Check if dive #%d %d has to be considered as prev dive: ", i, (*this)[i]->number);
#endif
struct dive *pdive = get_dive(i);
const struct dive &pdive = *(*this)[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 >= dive->when || pdive->endtime() + 48 * 60 * 60 < last_starttime) {
if (pdive.when >= dive->when || pdive.endtime() + 48 * 60 * 60 < last_starttime) {
#if DECO_CALC_DEBUG & 2
printf("No\n");
#endif
break;
}
last_starttime = pdive->when;
last_starttime = pdive.when;
#if DECO_CALC_DEBUG & 2
printf("Yes\n");
#endif
@ -485,18 +481,18 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
/* Walk forward an add dives and surface intervals to deco */
while (++i < nr_dives) {
#if DECO_CALC_DEBUG & 2
printf("Check if dive #%d %d will be really added to deco calc: ", i, get_dive(i)->number);
printf("Check if dive #%d %d will be really added to deco calc: ", i, (*this)[i]->number);
#endif
struct dive *pdive = get_dive(i);
const struct dive &pdive = *(*this)[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) {
if (pdive.when >= dive->when) {
#if DECO_CALC_DEBUG & 2
printf("No - future or same dive\n");
#endif
@ -513,7 +509,7 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
printf("Yes\n");
#endif
surface_pressure = get_surface_pressure_in_mbar(pdive, true) / 1000.0;
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
@ -526,7 +522,7 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
dump_tissues(ds);
#endif
} else {
surface_time = pdive->when - last_endtime;
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);
@ -540,13 +536,13 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
#endif
}
add_dive_to_deco(ds, pdive, in_planner);
add_dive_to_deco(ds, &pdive, in_planner);
last_starttime = pdive->when;
last_endtime = pdive->endtime();
last_starttime = pdive.when;
last_endtime = pdive.endtime();
clear_vpmb_state(ds);
#if DECO_CALC_DEBUG & 2
printf("Tissues after added dive #%d:\n", pdive->number);
printf("Tissues after added dive #%d:\n", pdive.number);
dump_tissues(ds);
#endif
}
@ -582,7 +578,7 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
return surface_time;
}
void update_cylinder_related_info(struct dive *dive)
void dive_table::update_cylinder_related_info(struct dive *dive) const
{
if (dive != NULL) {
dive->sac = calculate_sac(dive);

View file

@ -22,16 +22,18 @@ struct dive_table : public sorted_owning_table<dive, &comp_dives> {
struct dive *register_dive(std::unique_ptr<dive> d);
std::unique_ptr<dive> unregister_dive(int idx);
int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_planner) const;
void update_cylinder_related_info(struct dive *) const;
int get_dive_nr_at_idx(int idx) const;
timestamp_t get_surface_interval(timestamp_t when) const;
struct dive *find_next_visible_dive(timestamp_t when);
private:
int calculate_cns(struct dive *dive) const; // Note: writes into dive->cns
};
/* this is used for both git and xml format */
#define DATAFORMAT_VERSION 3
extern void update_cylinder_related_info(struct dive *);
extern int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_planner);
/* divelist core logic functions */
extern void process_loaded_dives();

View file

@ -12,6 +12,7 @@
#include <string.h>
#include "dive.h"
#include "divelist.h" // for init_decompression()
#include "divelog.h"
#include "sample.h"
#include "subsurface-string.h"
#include "deco.h"
@ -122,7 +123,7 @@ static int tissue_at_end(struct deco_state *ds, struct dive *dive, const struct
if (cache) {
cache.restore(ds, true);
} else {
surface_interval = init_decompression(ds, dive, true);
surface_interval = divelog.dives.init_decompression(ds, dive, true);
cache.cache(ds);
}
if (dc->samples.empty())

View file

@ -10,11 +10,12 @@
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "dive.h"
#include "deco.h"
#include "dive.h"
#include "divelist.h"
#include "divelog.h"
#include "event.h"
#include "units.h"
#include "divelist.h"
#include "planner.h"
#include "range.h"
#include "gettext.h"
@ -409,7 +410,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
/* Print the CNS and OTU next.*/
dive->cns = 0;
dive->maxcns = 0;
update_cylinder_related_info(dive);
divelog.dives.update_cylinder_related_info(dive);
buf += casprintf_loc("<div>\n%s: %i%%", translate("gettextFromC", "CNS"), dive->cns);
buf += casprintf_loc("<br/>\n%s: %i<br/>\n</div>\n", translate("gettextFromC", "OTU"), dive->otu);

View file

@ -10,6 +10,7 @@
#include "dive.h"
#include "divelist.h"
#include "divelog.h"
#include "errorhelper.h"
#include "event.h"
#include "interpolate.h"
@ -1252,7 +1253,7 @@ struct plot_info create_plot_info_new(const struct dive *dive, const struct dive
int o2, he, o2max;
struct deco_state plot_deco_state;
bool in_planner = planner_ds != NULL;
init_decompression(&plot_deco_state, dive, in_planner);
divelog.dives.init_decompression(&plot_deco_state, dive, in_planner);
plot_info pi;
calculate_max_limits_new(dive, dc, pi, in_planner);
get_dive_gas(dive, &o2, &he, &o2max);

View file

@ -708,7 +708,7 @@ void DiveTripModelTree::populate()
uiNotification(QObject::tr("populate data model"));
uiNotification(QObject::tr("start processing"));
for (auto &d: divelog.dives) {
update_cylinder_related_info(d.get());
divelog.dives.update_cylinder_related_info(d.get());
if (d->hidden_by_filter)
continue;
dive_trip *trip = d->divetrip;