core: move functions into struct dive

Nothing against free-standing functions, but in the case
of dc_watertemp(), dc_airtemp(), endtime() and totaltime(),
it seems natural to move this into the dive class and avoid
polution of the global name space.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-06-05 17:02:40 +02:00 committed by bstoeger
parent b9df26066e
commit a1e6df46d9
13 changed files with 63 additions and 64 deletions

View file

@ -622,7 +622,7 @@ pressure_t calculate_surface_pressure(const struct dive *dive)
pressure_t res;
int sum = 0, nr = 0;
bool logged = is_logged(dive);
bool logged = dive->is_logged();
for (auto &dc: dive->dcs) {
if ((logged || !is_dc_planner(&dc)) && dc.surface_pressure.mbar) {
sum += dc.surface_pressure.mbar;
@ -653,7 +653,7 @@ static void fixup_water_salinity(struct dive *dive)
{
int sum = 0, nr = 0;
bool logged = is_logged(dive);
bool logged = dive->is_logged();
for (auto &dc: dive->dcs) {
if ((logged || !is_dc_planner(&dc)) && dc.salinity) {
if (dc.salinity < 500)
@ -675,7 +675,7 @@ static void fixup_meandepth(struct dive *dive)
{
int sum = 0, nr = 0;
bool logged = is_logged(dive);
bool logged = dive->is_logged();
for (auto &dc: dive->dcs) {
if ((logged || !is_dc_planner(&dc)) && dc.meandepth.mm) {
sum += dc.meandepth.mm;
@ -691,7 +691,7 @@ static void fixup_duration(struct dive *dive)
{
duration_t duration = { };
bool logged = is_logged(dive);
bool logged = dive->is_logged();
for (auto &dc: dive->dcs) {
if (logged || !is_dc_planner(&dc))
duration.seconds = std::max(duration.seconds, dc.duration.seconds);
@ -702,13 +702,13 @@ static void fixup_duration(struct dive *dive)
static void fixup_watertemp(struct dive *dive)
{
if (!dive->watertemp.mkelvin)
dive->watertemp = dc_watertemp(dive);
dive->watertemp = dive->dc_watertemp();
}
static void fixup_airtemp(struct dive *dive)
{
if (!dive->airtemp.mkelvin)
dive->airtemp = dc_airtemp(dive);
dive->airtemp = dive->dc_airtemp();
}
/* if the air temperature in the dive data is redundant to the one in its
@ -716,10 +716,8 @@ static void fixup_airtemp(struct dive *dive)
* return 0, otherwise return the air temperature given in the dive */
static temperature_t un_fixup_airtemp(const struct dive &a)
{
temperature_t res = a.airtemp;
if (a.airtemp.mkelvin && a.airtemp.mkelvin == dc_airtemp(&a).mkelvin)
res.mkelvin = 0;
return res;
return a.airtemp.mkelvin == a.dc_airtemp().mkelvin ?
temperature_t() : a.airtemp;
}
/*
@ -795,7 +793,7 @@ static void fixup_dc_depths(struct dive *dive, struct divecomputer &dc)
}
update_depth(&dc.maxdepth, maxdepth);
if (!is_logged(dive) || !is_dc_planner(&dc))
if (!dive->is_logged() || !is_dc_planner(&dc))
if (maxdepth > dive->maxdepth.mm)
dive->maxdepth.mm = maxdepth;
}
@ -2203,22 +2201,22 @@ static void join_dive_computers(struct dive &d,
remove_redundant_dc(d, prefer_downloaded);
}
static bool has_dc_type(const struct dive *dive, bool dc_is_planner)
static bool has_dc_type(const struct dive &dive, bool dc_is_planner)
{
return std::any_of(dive->dcs.begin(), dive->dcs.end(),
return std::any_of(dive.dcs.begin(), dive.dcs.end(),
[dc_is_planner] (const divecomputer &dc)
{ return is_dc_planner(&dc) == dc_is_planner; });
}
// Does this dive have a dive computer for which is_dc_planner has value planned
bool is_planned(const struct dive *dive)
bool dive::is_planned() const
{
return has_dc_type(dive, true);
return has_dc_type(*this, true);
}
bool is_logged(const struct dive *dive)
bool dive::is_logged() const
{
return has_dc_type(dive, false);
return has_dc_type(*this, false);
}
/*
@ -2569,30 +2567,30 @@ static inline int dc_totaltime(const struct divecomputer &dc)
* time in the samples (and just default to the dive duration if
* there are no samples).
*/
static inline int dive_totaltime(const struct dive *dive)
duration_t dive::totaltime() const
{
int time = dive->duration.seconds;
int time = duration.seconds;
bool logged = is_logged(dive);
for (auto &dc: dive->dcs) {
bool logged = is_logged();
for (auto &dc: dcs) {
if (logged || !is_dc_planner(&dc)) {
int dc_time = dc_totaltime(dc);
if (dc_time > time)
time = dc_time;
}
}
return time;
return { time };
}
timestamp_t dive_endtime(const struct dive *dive)
timestamp_t dive::endtime() const
{
return dive->when + dive_totaltime(dive);
return when + totaltime().seconds;
}
bool time_during_dive_with_offset(const struct dive *dive, timestamp_t when, timestamp_t offset)
{
timestamp_t start = dive->when;
timestamp_t end = dive_endtime(dive);
timestamp_t end = dive->endtime();
return start - offset <= when && when <= end + offset;
}
@ -3081,11 +3079,11 @@ bool cylinder_with_sensor_sample(const struct dive *dive, int cylinder_id)
* What do the dive computers say the water temperature is?
* (not in the samples, but as dc property for dcs that support that)
*/
temperature_t dc_watertemp(const struct dive *d)
temperature_t dive::dc_watertemp() const
{
int sum = 0, nr = 0;
for (auto &dc: d->dcs) {
for (auto &dc: dcs) {
if (dc.watertemp.mkelvin) {
sum += dc.watertemp.mkelvin;
nr++;
@ -3099,11 +3097,11 @@ temperature_t dc_watertemp(const struct dive *d)
/*
* What do the dive computers say the air temperature is?
*/
temperature_t dc_airtemp(const struct dive *d)
temperature_t dive::dc_airtemp() const
{
int sum = 0, nr = 0;
for (auto &dc: d->dcs) {
for (auto &dc: dcs) {
if (dc.airtemp.mkelvin) {
sum += dc.airtemp.mkelvin;
nr++;

View file

@ -78,6 +78,15 @@ struct dive {
dive(const dive &);
dive(dive &&);
dive &operator=(const dive &);
timestamp_t endtime() const; /* maximum over divecomputers (with samples) */
duration_t totaltime() const; /* maximum over divecomputers (with samples) */
temperature_t dc_airtemp() const; /* average over divecomputers */
temperature_t dc_watertemp() const; /* average over divecomputers */
bool is_planned() const;
bool is_logged() const;
};
/* For the top-level list: an entry is either a dive or a trip */
@ -137,9 +146,6 @@ extern std::string get_dive_location(const struct dive *dive);
extern unsigned int number_of_computers(const struct dive *dive);
extern struct divecomputer *get_dive_dc(struct dive *dive, int nr);
extern const struct divecomputer *get_dive_dc(const struct dive *dive, int nr);
extern timestamp_t dive_endtime(const struct dive *dive);
extern temperature_t dc_airtemp(const struct dive *dive);
extern temperature_t dc_watertemp(const struct dive *dive);
extern void set_git_prefs(const char *prefs);
@ -222,9 +228,6 @@ extern void invalidate_dive_cache(struct dive *dc);
extern int total_weight(const struct dive *);
extern bool is_planned(const struct dive *dive);
extern bool is_logged(const struct dive *dive);
/* Get gasmix at a given time */
extern struct gasmix get_gasmix_at_time(const struct dive &dive, const struct divecomputer &dc, duration_t time);

View file

@ -57,8 +57,6 @@ extern int get_depth_at_time(const struct divecomputer *dc, unsigned int time);
extern struct sample *prepare_sample(struct divecomputer *dc);
extern void append_sample(const struct sample &sample, struct divecomputer *dc);
extern void fixup_dc_duration(struct divecomputer &dc);
extern unsigned int dc_airtemp(const struct divecomputer *dc);
extern unsigned int dc_watertemp(const struct divecomputer *dc);
extern int add_event_to_dc(struct divecomputer *dc, struct event ev); // event structure is consumed, returns index of inserted event
extern struct event *add_event(struct divecomputer *dc, unsigned int time, int type, int flags, int value, const std::string &name);
extern struct event remove_event_from_dc(struct divecomputer *dc, int idx);

View file

@ -251,7 +251,7 @@ static int calculate_cns(struct dive *dive)
#endif
continue;
}
if (!pdive || pdive->when >= dive->when || dive_endtime(pdive) + 12 * 60 * 60 < last_starttime) {
if (!pdive || pdive->when >= dive->when || pdive->endtime() + 12 * 60 * 60 < last_starttime) {
#if DECO_CALC_DEBUG & 2
printf("No\n");
#endif
@ -306,7 +306,7 @@ static int calculate_cns(struct dive *dive)
#endif
last_starttime = pdive->when;
last_endtime = dive_endtime(pdive);
last_endtime = pdive->endtime();
}
/* CNS reduced with 90min halftime during surface interval */
@ -478,7 +478,7 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
#endif
continue;
}
if (!pdive || pdive->when >= dive->when || dive_endtime(pdive) + 48 * 60 * 60 < last_starttime) {
if (!pdive || pdive->when >= dive->when || pdive->endtime() + 48 * 60 * 60 < last_starttime) {
#if DECO_CALC_DEBUG & 2
printf("No\n");
#endif
@ -550,7 +550,7 @@ int init_decompression(struct deco_state *ds, const struct dive *dive, bool in_p
add_dive_to_deco(ds, pdive, in_planner);
last_starttime = pdive->when;
last_endtime = dive_endtime(pdive);
last_endtime = pdive->endtime();
clear_vpmb_state(ds);
#if DECO_CALC_DEBUG & 2
printf("Tissues after added dive #%d:\n", pdive->number);
@ -796,7 +796,7 @@ static void merge_imported_dives(struct dive_table *table)
/* only try to merge overlapping dives - or if one of the dives has
* zero duration (that might be a gps marker from the webservice) */
if (prev->duration.seconds && dive->duration.seconds &&
dive_endtime(prev) < dive->when)
prev->endtime() < dive->when)
continue;
auto merged = try_to_merge(*prev, *dive, false);
@ -898,7 +898,7 @@ static bool merge_dive_tables(const std::vector<dive *> &dives_from, struct dive
* by is_same_dive() were already merged, and is_same_dive() should be
* transitive. But let's just go *completely* sure for the odd corner-case. */
if (j > 0 && (last_merged_into == std::string::npos || j > last_merged_into + 1) &&
dive_endtime(dives_to[j - 1]) > dive_to_add->when) {
dives_to[j - 1]->endtime() > dive_to_add->when) {
if (try_to_merge_into(*dive_to_add, *dives_to[j - 1], prefer_imported,
dives_to_add, dives_to_remove)) {
delete dive_to_add;
@ -911,7 +911,7 @@ static bool merge_dive_tables(const std::vector<dive *> &dives_from, struct dive
/* That didn't merge into the previous dive.
* Try to merge into next dive. */
if (j < dives_to.size() && (last_merged_into == std::string::npos || j > last_merged_into) &&
dive_endtime(dive_to_add) > dives_to[j]->when) {
dive_to_add->endtime() > dives_to[j]->when) {
if (try_to_merge_into(*dive_to_add, *dives_to[j], prefer_imported,
dives_to_add, dives_to_remove)) {
delete dive_to_add;
@ -1345,7 +1345,7 @@ timestamp_t get_surface_interval(timestamp_t when)
if (i < 0)
return -1;
prev_end = dive_endtime(divelog.dives->dives[i]);
prev_end = divelog.dives->dives[i]->endtime();
if (prev_end > when)
return 0;
return when - prev_end;

View file

@ -951,12 +951,12 @@ static bool check_datetime_range(const filter_constraint &c, const struct dive *
// where the given timestamp is during that dive.
return time_during_dive_with_offset(d, c.data.timestamp_range.from, 0) != c.negate;
case FILTER_CONSTRAINT_LESS:
return (dive_endtime(d) <= c.data.timestamp_range.to) != c.negate;
return (d->endtime() <= c.data.timestamp_range.to) != c.negate;
case FILTER_CONSTRAINT_GREATER:
return (d->when >= c.data.timestamp_range.from) != c.negate;
case FILTER_CONSTRAINT_RANGE:
return (d->when >= c.data.timestamp_range.from &&
dive_endtime(d) <= c.data.timestamp_range.to) != c.negate;
d->endtime() <= c.data.timestamp_range.to) != c.negate;
}
return false;
}
@ -971,14 +971,14 @@ static bool check_time_of_day_internal(const dive *d, enum filter_constraint_ran
// where the given timestamp is during that dive. Note: this will fail for dives
// that run past midnight. We might want to special case that.
return (seconds_since_midnight(d->when) <= from &&
seconds_since_midnight(dive_endtime(d)) >= from) != negate;
seconds_since_midnight(d->endtime()) >= from) != negate;
case FILTER_CONSTRAINT_LESS:
return (seconds_since_midnight(dive_endtime(d)) <= to) != negate;
return (seconds_since_midnight(d->endtime()) <= to) != negate;
case FILTER_CONSTRAINT_GREATER:
return (seconds_since_midnight(d->when) >= from) != negate;
case FILTER_CONSTRAINT_RANGE:
return (seconds_since_midnight(d->when) >= from &&
seconds_since_midnight(dive_endtime(d)) <= to) != negate;
seconds_since_midnight(d->endtime()) <= to) != negate;
}
return false;
}
@ -1066,9 +1066,9 @@ bool filter_constraint_match_dive(const filter_constraint &c, const struct dive
case FILTER_CONSTRAINT_SAC:
return check_numerical_range_non_zero(c, d->sac);
case FILTER_CONSTRAINT_LOGGED:
return is_logged(d) != c.negate;
return d->is_logged() != c.negate;
case FILTER_CONSTRAINT_PLANNED:
return is_planned(d) != c.negate;
return d->is_planned() != c.negate;
case FILTER_CONSTRAINT_DIVE_MODE:
return check_multiple_choice(c, (int)d->dcs[0].divemode); // should we be smarter and check all DCs?
case FILTER_CONSTRAINT_TAGS:

View file

@ -32,7 +32,7 @@ int get_picture_idx(const picture_table &t, const std::string &filename)
/* Return distance of timestamp to time of dive. Result is always positive, 0 means during dive. */
static timestamp_t time_from_dive(const struct dive *d, timestamp_t timestamp)
{
timestamp_t end_time = dive_endtime(d);
timestamp_t end_time = d->endtime();
if (timestamp < d->when)
return d->when - timestamp;
else if (timestamp > end_time)

View file

@ -175,9 +175,9 @@ static void save_weightsystem_info(struct membuffer *b, const struct dive *dive)
static void save_dive_temperature(struct membuffer *b, struct dive *dive)
{
if (dive->airtemp.mkelvin != dc_airtemp(dive).mkelvin)
if (dive->airtemp.mkelvin != dive->dc_airtemp().mkelvin)
put_temperature(b, dive->airtemp, "airtemp ", "°C\n");
if (dive->watertemp.mkelvin != dc_watertemp(dive).mkelvin)
if (dive->watertemp.mkelvin != dive->dc_watertemp().mkelvin)
put_temperature(b, dive->watertemp, "watertemp ", "°C\n");
}

View file

@ -116,13 +116,13 @@ static void save_dive_temperature(struct membuffer *b, struct dive *dive)
{
if (!dive->airtemp.mkelvin && !dive->watertemp.mkelvin)
return;
if (dive->airtemp.mkelvin == dc_airtemp(dive).mkelvin && dive->watertemp.mkelvin == dc_watertemp(dive).mkelvin)
if (dive->airtemp.mkelvin == dive->dc_airtemp().mkelvin && dive->watertemp.mkelvin == dive->dc_watertemp().mkelvin)
return;
put_string(b, " <divetemperature");
if (dive->airtemp.mkelvin != dc_airtemp(dive).mkelvin)
if (dive->airtemp.mkelvin != dive->dc_airtemp().mkelvin)
put_temperature(b, dive->airtemp, " air='", " C'");
if (dive->watertemp.mkelvin != dc_watertemp(dive).mkelvin)
if (dive->watertemp.mkelvin != dive->dc_watertemp().mkelvin)
put_temperature(b, dive->watertemp, " water='", " C'");
put_string(b, "/>\n");
}

View file

@ -47,7 +47,7 @@ static timestamp_t trip_enddate(const struct dive_trip &trip)
{
if (trip.dives.empty())
return 0;
return dive_endtime(trip.dives.back());
return trip.dives.back()->endtime();
}
/* check if we have a trip right before / after this dive */

View file

@ -548,12 +548,12 @@ static bool can_merge(const struct dive *a, const struct dive *b, enum asked_use
if (a->when > b->when)
return false;
/* Don't merge dives if there's more than half an hour between them */
if (dive_endtime(a) + 30 * 60 < b->when) {
if (a->endtime() + 30 * 60 < b->when) {
if (*have_asked == NOTYET) {
if (QMessageBox::warning(MainWindow::instance(),
MainWindow::tr("Warning"),
MainWindow::tr("Trying to merge dives with %1min interval in between").arg(
(b->when - dive_endtime(a)) / 60),
(b->when - a->endtime()) / 60),
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel) {
*have_asked = DONTMERGE;
return false;

View file

@ -282,7 +282,7 @@ void LocationInformationWidget::on_GPSbutton_clicked()
ImportGPS GPSDialog(this, fileName, &ui); // Create a GPS import QDialog
GPSDialog.coords.start_dive = current_dive->when; // initialise
GPSDialog.coords.end_dive = dive_endtime(current_dive);
GPSDialog.coords.end_dive = current_dive->endtime();
if (getCoordsFromGPXFile(&GPSDialog.coords, fileName) == 0) { // Get coordinates from GPS file
GPSDialog.updateUI(); // If successful, put results in Dialog
if (!GPSDialog.exec()) // and show QDialog

View file

@ -104,7 +104,7 @@ void DivePlannerPointsModel::setupStartTime()
startTime = QDateTime::currentDateTimeUtc().addSecs(3600 + gettimezoneoffset());
if (divelog.dives->nr > 0) {
struct dive *d = get_dive(divelog.dives->nr - 1);
time_t ends = dive_endtime(d);
time_t ends = d->endtime();
time_t diff = ends - dateTimeToTimestamp(startTime);
if (diff > 0)
startTime = startTime.addSecs(diff + 3600);

View file

@ -145,7 +145,7 @@ static const QString icon_names[4] = {
static int countPhotos(const struct dive *d)
{ // Determine whether dive has pictures, and whether they were taken during or before/after dive.
const int bufperiod = 120; // A 2-min buffer period. Photos within 2 min of dive are assumed as
int diveTotaltime = dive_endtime(d) - d->when; // taken during the dive, not before/after.
int diveTotaltime = d->totaltime().seconds; // taken during the dive, not before/after.
int pic_offset, icon_index = 0;
for (auto &picture: d->pictures) { // Step through each of the pictures for this dive:
pic_offset = picture.offset.seconds;