core: move dive-site functions into class

In analogy to the previous commit for dive-site-table.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-11 15:01:37 +02:00 committed by bstoeger
parent 76c52c87a3
commit 2de6f69c19
20 changed files with 69 additions and 71 deletions

View file

@ -325,9 +325,9 @@ std::vector<const dive_site *> getDiveSitesToExport(bool selectedOnly)
res.reserve(divelog.sites->size());
for (const auto &ds: *divelog.sites) {
if (dive_site_is_empty(ds.get()))
if (ds->is_empty())
continue;
if (selectedOnly && !is_dive_site_selected(*ds))
if (selectedOnly && !ds->is_selected())
continue;
res.push_back(ds.get());
}

View file

@ -69,7 +69,7 @@ dive *DiveListBase::addDive(DiveToAdd &d)
if (d.trip)
add_dive_to_trip(d.dive.get(), d.trip);
if (d.site) {
add_dive_to_dive_site(d.dive.get(), d.site);
d.site->add_dive(d.dive.get());
diveSiteCountChanged(d.site);
}
dive *res = d.dive.release(); // Give up ownership of dive

View file

@ -344,7 +344,7 @@ void MergeDiveSites::redo()
// the dives in the sitesToAdd vector.
for (const std::unique_ptr<dive_site> &site: sitesToAdd) {
for (dive *d: site->dives) {
add_dive_to_dive_site(d, ds);
ds->add_dive(d);
divesChanged.push_back(d);
}
}
@ -385,7 +385,7 @@ ApplyGPSFixes::ApplyGPSFixes(const std::vector<DiveAndLocation> &fixes)
} else {
ds = divelog.sites->create(dl.name.toStdString());
ds->location = dl.location;
add_dive_to_dive_site(dl.d, ds);
ds->add_dive(dl.d);
dl.d->dive_site = nullptr; // This will be set on redo()
sitesToAdd.emplace_back(ds);
}

View file

@ -346,7 +346,7 @@ QString EditDepth::fieldName() const
void EditDiveSite::set(struct dive *d, struct dive_site *dive_site) const
{
unregister_dive_from_dive_site(d);
add_dive_to_dive_site(d, dive_site);
dive_site->add_dive(d);
}
struct dive_site *EditDiveSite::data(struct dive *d) const
@ -1478,7 +1478,7 @@ void EditDive::exchangeDives()
std::swap(*newDive, *oldDive);
fulltext_register(oldDive);
if (newDiveSite)
add_dive_to_dive_site(oldDive, newDiveSite);
newDiveSite->add_dive(oldDive);
newDiveSite = oldDiveSite; // remember the previous dive site
invalidate_dive_cache(oldDive);

View file

@ -200,7 +200,7 @@ void AddPictures::swapDiveSites()
unregister_dive_from_dive_site(entry.d); // the dive-site pointer in the dive is now NULL
std::swap(ds, entry.ds);
if (ds)
add_dive_to_dive_site(entry.d, ds);
ds->add_dive(entry.d);
emit diveListNotifier.divesChanged(QVector<dive *>{ entry.d }, DiveField::DIVESITE);
}

View file

@ -214,7 +214,7 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
struct dive_site *ds = log->sites->get_by_name(buffer2);
if (!ds)
ds = log->sites->create(buffer2);
add_dive_to_dive_site(dt_dive, ds);
ds->add_dive(dt_dive);
}
free(locality);
locality = NULL;

View file

@ -324,7 +324,7 @@ void selective_copy_dive(const struct dive *s, struct dive *d, struct dive_compo
d->visibility = s->visibility;
if (what.divesite) {
unregister_dive_from_dive_site(d);
add_dive_to_dive_site(d, s->dive_site);
s->dive_site->add_dive(d);
}
if (what.tags)
d->tag_list = taglist_copy(s->tag_list);
@ -2360,7 +2360,7 @@ struct dive *try_to_merge(struct dive *a, struct dive *b, bool prefer_downloaded
return NULL;
res = merge_dives(a, b, 0, prefer_downloaded, NULL, &site);
res->dive_site = site; /* Caller has to call add_dive_to_dive_site()! */
res->dive_site = site; /* Caller has to call site->add_dive()! */
return res;
}
@ -2656,7 +2656,7 @@ struct dive *merge_dives(const struct dive *a, const struct dive *b, int offset,
res->cns = res->maxcns = 0;
/* we take the first dive site, unless it's empty */
*site = a->dive_site && !dive_site_is_empty(a->dive_site) ? a->dive_site : b->dive_site;
*site = a->dive_site && !a->dive_site->is_empty() ? a->dive_site : b->dive_site;
if (!dive_site_has_gps_location(*site) && dive_site_has_gps_location(b->dive_site)) {
/* we picked the first dive site and that didn't have GPS data, but the new dive has
* GPS data (that could be a download from a GPS enabled dive computer).

View file

@ -810,7 +810,7 @@ static void merge_imported_dives(struct dive_table *table)
ds = merged->dive_site;
if (ds) {
merged->dive_site = NULL;
add_dive_to_dive_site(merged, ds);
ds->add_dive(merged);
}
unregister_dive_from_dive_site(prev);
unregister_dive_from_dive_site(dive);
@ -969,7 +969,8 @@ void add_imported_dives(struct divelog *import_log, int flags)
d->divetrip = NULL;
d->dive_site = NULL;
add_dive_to_trip(d, trip);
add_dive_to_dive_site(d, site);
if (site)
site->add_dive(d);
}
/* Remove old dives */

View file

@ -137,14 +137,14 @@ dive_site *dive_site_table::alloc_or_get(uint32_t uuid)
return register_site(std::make_unique<dive_site>(uuid)).ptr;
}
size_t nr_of_dives_at_dive_site(const dive_site &ds)
size_t dive_site::nr_of_dives() const
{
return ds.dives.size();
return dives.size();
}
bool is_dive_site_selected(const struct dive_site &ds)
bool dive_site::is_selected() const
{
return any_of(ds.dives.begin(), ds.dives.end(),
return any_of(dives.begin(), dives.end(),
[](dive *dive) { return dive->selected; });
}
@ -161,13 +161,12 @@ dive_site *dive_site_table::create(const std::string &name, const location_t *lo
}
/* if all fields are empty, the dive site is pointless */
bool dive_site_is_empty(struct dive_site *ds)
bool dive_site::is_empty() const
{
return !ds ||
(ds->name.empty() &&
ds->description.empty() &&
ds->notes.empty() &&
!has_location(&ds->location));
return name.empty() &&
description.empty() &&
notes.empty() &&
!has_location(&location);
}
static void merge_string(std::string &a, const std::string &b)
@ -206,15 +205,15 @@ struct dive_site *get_same_dive_site(const struct dive_site &site)
[site](const auto &ds) { return same(*ds, site); });
}
void merge_dive_site(struct dive_site *a, struct dive_site *b)
void dive_site::merge(dive_site &b)
{
if (!has_location(&a->location)) a->location = b->location;
merge_string(a->name, b->name);
merge_string(a->notes, b->notes);
merge_string(a->description, b->description);
if (!has_location(&location)) location = b.location;
merge_string(name, b.name);
merge_string(notes, b.notes);
merge_string(description, b.description);
if (a->taxonomy.empty())
a->taxonomy = std::move(b->taxonomy);
if (taxonomy.empty())
taxonomy = std::move(b.taxonomy);
}
dive_site *dive_site_table::find_or_create(const std::string &name)
@ -228,7 +227,7 @@ dive_site *dive_site_table::find_or_create(const std::string &name)
void dive_site_table::purge_empty()
{
for (const auto &ds: *this) {
if (!dive_site_is_empty(ds.get()))
if (!ds->is_empty())
continue;
while (!ds->dives.empty()) {
struct dive *d = ds->dives.back();
@ -242,24 +241,20 @@ void dive_site_table::purge_empty()
}
}
void add_dive_to_dive_site(struct dive *d, struct dive_site *ds)
void dive_site::add_dive(struct dive *d)
{
if (!d) {
report_info("Warning: add_dive_to_dive_site called with NULL dive");
report_info("Warning: dive_site::add_dive() called with NULL dive");
return;
}
if (!ds) {
report_info("Warning: add_dive_to_dive_site called with NULL dive site");
return;
}
if (d->dive_site == ds)
if (d->dive_site == this)
return;
if (d->dive_site) {
report_info("Warning: adding dive that already belongs to a dive site to a different site");
unregister_dive_from_dive_site(d);
}
ds->dives.push_back(d);
d->dive_site = ds;
dives.push_back(d);
d->dive_site = this;
}
struct dive_site *unregister_dive_from_dive_site(struct dive *d)

View file

@ -19,11 +19,18 @@ struct dive_site
std::string description;
std::string notes;
taxonomy_data taxonomy;
dive_site();
dive_site(const std::string &name);
dive_site(const std::string &name, const location_t *loc);
dive_site(uint32_t uuid);
~dive_site();
size_t nr_of_dives() const;
bool is_selected() const;
bool is_empty() const;
void merge(struct dive_site &b); // Note: b is consumed
void add_dive(struct dive *d);
};
inline int divesite_comp_uuid(const dive_site &ds1, const dive_site &ds2)
@ -48,14 +55,9 @@ public:
void purge_empty();
};
size_t nr_of_dives_at_dive_site(const struct dive_site &ds);
bool is_dive_site_selected(const struct dive_site &ds);
struct dive_site *get_same_dive_site(const struct dive_site &);
bool dive_site_is_empty(struct dive_site *ds);
void merge_dive_site(struct dive_site *a, struct dive_site *b);
unsigned int get_distance(const location_t *loc1, const location_t *loc2);
void add_dive_to_dive_site(struct dive *d, struct dive_site *ds);
struct dive_site *unregister_dive_from_dive_site(struct dive *d);
struct dive_site *get_same_dive_site(const struct dive_site &); // accesses global dive list
std::string constructLocationTags(const taxonomy_data &taxonomy, bool for_maintab);
/* Make pointer-to-dive_site a "Qt metatype" so that we can pass it through QVariants */

View file

@ -181,7 +181,7 @@ static int cobalt_dive(void *param, int, char **data, char **)
if (location && location_site) {
std::string tmp = std::string(location) + " / " + location_site;
add_dive_to_dive_site(state->cur_dive, state->log->sites->find_or_create(tmp));
state->log->sites->find_or_create(tmp)->add_dive(state->cur_dive);
}
free(location);
free(location_site);

View file

@ -276,7 +276,7 @@ static int divinglog_dive(void *param, int, char **data, char **)
state->cur_dive->when = (time_t)(atol(data[1]));
if (data[2])
add_dive_to_dive_site(state->cur_dive, state->log->sites->find_or_create(std::string(data[2])));
state->log->sites->find_or_create(std::string(data[2]))->add_dive(state->cur_dive);
if (data[3])
utf8_string(data[3], &state->cur_dive->buddy);

View file

@ -636,7 +636,7 @@ static void parse_string_field(device_data_t *devdata, struct dive *dive, dc_fie
if (location.lat.udeg && location.lon.udeg) {
unregister_dive_from_dive_site(dive);
add_dive_to_dive_site(dive, devdata->log->sites->create(std::string(str->value), &location));
devdata->log->sites->create(std::string(str->value), &location)->add_dive(dive);
}
}
}

View file

@ -190,7 +190,7 @@ static void parse_dives(int log_version, const unsigned char *buf, unsigned int
/* Store the location only if we have one */
if (!location.empty())
add_dive_to_dive_site(dive, sites.find_or_create(location));
sites.find_or_create(location)->add_dive(dive);
ptr += len + 4 + place_len;

View file

@ -178,7 +178,7 @@ static void parse_dive_gps(char *line, struct git_parser_state *state)
ds = state->log->sites->get_by_gps(&location);
if (!ds)
ds = state->log->sites->create(std::string(), &location);
add_dive_to_dive_site(state->active_dive, ds);
ds->add_dive(state->active_dive);
} else {
if (dive_site_has_gps_location(ds) && ds->location != location) {
std::string coords = printGPSCoordsC(&location);
@ -224,7 +224,7 @@ static void parse_dive_location(char *, struct git_parser_state *state)
ds = state->log->sites->get_by_name(name);
if (!ds)
ds = state->log->sites->create(name);
add_dive_to_dive_site(state->active_dive, ds);
ds->add_dive(state->active_dive);
} else {
// we already had a dive site linked to the dive
if (ds->name.empty()) {
@ -252,7 +252,7 @@ static void parse_dive_notes(char *, struct git_parser_state *state)
{ state->active_dive->notes = get_first_converted_string_c(state); }
static void parse_dive_divesiteid(char *line, struct git_parser_state *state)
{ add_dive_to_dive_site(state->active_dive, state->log->sites->get_by_uuid(get_hex(line))); }
{ state->log->sites->get_by_uuid(get_hex(line))->add_dive(state->active_dive); }
/*
* We can have multiple tags.

View file

@ -559,7 +559,7 @@ static void dive_site(const char *buffer, struct dive *d, struct parser_state *s
{
uint32_t uuid;
hex_value(buffer, &uuid);
add_dive_to_dive_site(d, state->log->sites->get_by_uuid(uuid));
state->log->sites->get_by_uuid(uuid)->add_dive(d);
}
static void get_notrip(const char *buffer, bool *notrip)
@ -980,7 +980,7 @@ static void divinglog_place(const char *place, struct dive *d, struct parser_sta
ds = state->log->sites->get_by_name(buffer);
if (!ds)
ds = state->log->sites->create(buffer);
add_dive_to_dive_site(d, ds);
ds->add_dive(d);
// TODO: capture the country / city info in the taxonomy instead
state->city.clear();
@ -1149,7 +1149,7 @@ static void gps_lat(const char *buffer, struct dive *dive, struct parser_state *
location.lat = parse_degrees(buffer, &end);
if (!ds) {
add_dive_to_dive_site(dive, state->log->sites->create(std::string(), &location));
state->log->sites->create(std::string(), &location)->add_dive(dive);
} else {
if (ds->location.lat.udeg && ds->location.lat.udeg != location.lat.udeg)
report_info("Oops, changing the latitude of existing dive site id %8x name %s; not good", ds->uuid,
@ -1166,7 +1166,7 @@ static void gps_long(const char *buffer, struct dive *dive, struct parser_state
location.lon = parse_degrees(buffer, &end);
if (!ds) {
add_dive_to_dive_site(dive, state->log->sites->create(std::string(), &location));
state->log->sites->create(std::string(), &location)->add_dive(dive);
} else {
if (ds->location.lon.udeg && ds->location.lon.udeg != location.lon.udeg)
report_info("Oops, changing the longitude of existing dive site id %8x name %s; not good", ds->uuid,
@ -1206,7 +1206,7 @@ static void gps_in_dive(const char *buffer, struct dive *dive, struct parser_sta
} else {
ds = state->log->sites->create(std::string(), &location);
}
add_dive_to_dive_site(dive, ds);
ds->add_dive(dive);
} else {
if (dive_site_has_gps_location(ds) &&
has_location(&location) && ds->location != location) {
@ -2225,7 +2225,7 @@ int parse_dlf_buffer(unsigned char *buffer, size_t size, struct divelog *log)
/* Measure GPS */
state.cur_location.lat.udeg = (int)((ptr[7] << 24) + (ptr[6] << 16) + (ptr[5] << 8) + (ptr[4] << 0));
state.cur_location.lon.udeg = (int)((ptr[11] << 24) + (ptr[10] << 16) + (ptr[9] << 8) + (ptr[8] << 0));
add_dive_to_dive_site(state.cur_dive, state.log->sites->create("DLF imported"s, &state.cur_location));
state.log->sites->create("DLF imported"s, &state.cur_location)->add_dive(state.cur_dive);
break;
default:
break;

View file

@ -200,7 +200,7 @@ void dive_site_end(struct parser_state *state)
return;
struct dive_site *ds = state->log->sites->alloc_or_get(state->cur_dive_site->uuid);
merge_dive_site(ds, state->cur_dive_site.get());
ds->merge(*state->cur_dive_site);
if (verbose > 3)
printf("completed dive site uuid %x8 name {%s}\n", ds->uuid, ds->name.c_str());
@ -484,11 +484,11 @@ void add_dive_site(const char *ds_name, struct dive *dive, struct parser_state *
struct dive_site *exact_match = state->log->sites->get_by_gps_and_name(trimmed, &ds->location);
if (exact_match) {
unregister_dive_from_dive_site(dive);
add_dive_to_dive_site(dive, exact_match);
exact_match->add_dive(dive);
} else {
struct dive_site *newds = state->log->sites->create(trimmed.c_str());
unregister_dive_from_dive_site(dive);
add_dive_to_dive_site(dive, newds);
newds->add_dive(dive);
if (has_location(&state->cur_location)) {
// we started this uuid with GPS data, so lets use those
newds->location = state->cur_location;
@ -501,10 +501,10 @@ void add_dive_site(const char *ds_name, struct dive *dive, struct parser_state *
} else if (dive->dive_site != ds) {
// add the existing dive site to the current dive
unregister_dive_from_dive_site(dive);
add_dive_to_dive_site(dive, ds);
ds->add_dive(dive);
}
} else {
add_dive_to_dive_site(dive, state->log->sites->create(trimmed));
state->log->sites->create(trimmed)->add_dive(dive);
}
}
}

View file

@ -703,10 +703,10 @@ static void save_dives_buffer(struct membuffer *b, bool select_only, bool anonym
put_format(b, "<divesites>\n");
for (const auto &ds: *divelog.sites) {
/* Don't export empty dive sites */
if (dive_site_is_empty(ds.get()))
if (ds->is_empty())
continue;
/* Only write used dive sites when exporting selected dives */
if (select_only && !is_dive_site_selected(*ds))
if (select_only && !ds->is_selected())
continue;
put_format(b, "<site uuid='%8x'", ds->uuid);

View file

@ -917,7 +917,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
if (from_chars(val, divespot_id).ec != std::errc::invalid_argument) {
struct dive_site *ds = devdata->log->sites->create("from Uemis"s);
unregister_dive_from_dive_site(dive);
add_dive_to_dive_site(dive, ds);
ds->add_dive(dive);
uemis_obj.mark_divelocation(dive->dc.diveid, divespot_id, ds);
}
#if UEMIS_DEBUG & 2
@ -1099,7 +1099,7 @@ static void get_uemis_divespot(device_data_t *devdata, const std::string &mountp
if (it != divespot_mapping.end()) {
struct dive_site *ds = it->second;
unregister_dive_from_dive_site(dive);
add_dive_to_dive_site(dive, ds);
ds->add_dive(dive);
} else if (nds && !nds->name.empty() && nds->name.find("from Uemis") != std::string::npos) {
if (load_uemis_divespot(mountpath, divespot_id)) {
/* get the divesite based on the diveid, this should give us
@ -1113,7 +1113,7 @@ static void get_uemis_divespot(device_data_t *devdata, const std::string &mountp
if (ods && nds->uuid != ods->uuid) {
/* if the uuid's are the same, the new site is a duplicate and can be deleted */
unregister_dive_from_dive_site(dive);
add_dive_to_dive_site(dive, ods);
ods->add_dive(dive);
devdata->log->sites->pull(nds);
}
divespot_mapping[divespot_id] = dive->dive_site;

View file

@ -480,7 +480,7 @@ void LocationFilterDelegate::paint(QPainter *painter, const QStyleOptionViewItem
} else {
int distanceMeters = get_distance(&ds->location, &currentLocation);
QString distance = distance_string(distanceMeters);
size_t nr = nr_of_dives_at_dive_site(*ds);
size_t nr = ds->nr_of_dives();
bottomText += tr(" (~%1 away").arg(distance);
bottomText += tr(", %n dive(s) here)", "", nr);
}