Skip to content

Commit

Permalink
core: turn C dive-table into an owning table
Browse files Browse the repository at this point in the history
This is a humongous commit, because it touches all parts of the
code. It removes the last user of our horrible TABLE macros, which
simulate std::vector<> in a very clumsy way.

Signed-off-by: Berthold Stoeger <[email protected]>
  • Loading branch information
bstoeger committed Aug 13, 2024
1 parent f00c30a commit b95ac3f
Show file tree
Hide file tree
Showing 73 changed files with 1,031 additions and 1,231 deletions.
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ColumnLimit: 0
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
ForEachMacros: [ 'for_each_dive', 'for_each_line' ]
ForEachMacros: [ 'for_each_line' ]
IndentFunctionDeclarationAfterType: false #personal taste, good for long methods
IndentWidth: 8
MaxEmptyLinesToKeep: 2
Expand Down
3 changes: 3 additions & 0 deletions Subsurface-mobile.pro
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ HEADERS += \
core/picture.h \
core/planner.h \
core/divesite.h \
core/divesitetable.h \
core/checkcloudconnection.h \
core/cochran.h \
core/color.h \
Expand Down Expand Up @@ -246,6 +247,8 @@ HEADERS += \
core/subsurfacestartup.h \
core/subsurfacesysinfo.h \
core/taxonomy.h \
core/trip.h \
core/triptable.h \
core/uemis.h \
core/webservice.h \
core/windowtitleupdate.h \
Expand Down
31 changes: 12 additions & 19 deletions backend-shared/exportfuncs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ static constexpr int profileScale = 4;
static constexpr int profileWidth = 800 * profileScale;
static constexpr int profileHeight = 600 * profileScale;

static void exportProfile(ProfileScene *profile, const struct dive *dive, const QString &filename)
static void exportProfile(ProfileScene &profile, const struct dive &dive, const QString &filename)
{
QImage image = QImage(QSize(profileWidth, profileHeight), QImage::Format_RGB32);
QPainter paint;
paint.begin(&image);
profile->draw(&paint, QRect(0, 0, profileWidth, profileHeight), dive, 0, nullptr, false);
profile.draw(&paint, QRect(0, 0, profileWidth, profileHeight), &dive, 0, nullptr, false);
image.save(filename);
}

Expand All @@ -57,25 +57,23 @@ static std::unique_ptr<ProfileScene> getPrintProfile()

void exportProfile(QString filename, bool selected_only, ExportCallback &cb)
{
struct dive *dive;
int i;
int count = 0;
if (!filename.endsWith(".png", Qt::CaseInsensitive))
filename = filename.append(".png");
QFileInfo fi(filename);

int todo = selected_only ? amount_selected : divelog.dives->nr;
int todo = selected_only ? amount_selected : static_cast<int>(divelog.dives.size());
int done = 0;
auto profile = getPrintProfile();
for_each_dive (i, dive) {
for (auto &dive: divelog.dives) {
if (cb.canceled())
return;
if (selected_only && !dive->selected)
continue;
cb.setProgress(done++ * 1000 / todo);
QString fn = count ? fi.path() + QDir::separator() + fi.completeBaseName().append(QString("-%1.").arg(count)) + fi.suffix()
: filename;
exportProfile(profile.get(), dive, fn);
exportProfile(*profile, *dive, fn);
++count;
}
}
Expand All @@ -84,11 +82,9 @@ void export_TeX(const char *filename, bool selected_only, bool plain, ExportCall
{
FILE *f;
QDir texdir = QFileInfo(filename).dir();
struct dive *dive;
const struct units *units = get_units();
const char *unit;
const char *ssrf;
int i;
bool need_pagebreak = false;

membuffer buf;
Expand Down Expand Up @@ -133,24 +129,24 @@ void export_TeX(const char *filename, bool selected_only, bool plain, ExportCall

put_format(&buf, "\n%%%%%%%%%% Begin Dive Data: %%%%%%%%%%\n");

int todo = selected_only ? amount_selected : divelog.dives->nr;
int todo = selected_only ? amount_selected : static_cast<int>(divelog.dives.size());
int done = 0;
auto profile = getPrintProfile();
for_each_dive (i, dive) {
for (auto &dive: divelog.dives) {
if (cb.canceled())
return;
if (selected_only && !dive->selected)
continue;
cb.setProgress(done++ * 1000 / todo);
exportProfile(profile.get(), dive, texdir.filePath(QString("profile%1.png").arg(dive->number)));
exportProfile(*profile, *dive, texdir.filePath(QString("profile%1.png").arg(dive->number)));
struct tm tm;
utc_mkdate(dive->when, &tm);

std::string country;
dive_site *site = dive->dive_site;
if (site)
country = taxonomy_get_country(site->taxonomy);
pressure_t delta_p = {.mbar = 0};
pressure_t delta_p;

QString star = "*";
QString viz = star.repeated(dive->visibility);
Expand Down Expand Up @@ -201,9 +197,8 @@ void export_TeX(const char *filename, bool selected_only, bool plain, ExportCall
// Print cylinder data
put_format(&buf, "\n%% Gas use information:\n");
int qty_cyl = 0;
for (int i = 0; i < static_cast<int>(dive->cylinders.size()); i++){
const cylinder_t &cyl = dive->cylinders[i];
if (is_cylinder_used(dive, i) || (prefs.include_unused_tanks && !cyl.type.description.empty())){
for (auto [i, cyl]: enumerated_range(dive->cylinders)) {
if (is_cylinder_used(dive.get(), i) || (prefs.include_unused_tanks && !cyl.type.description.empty())){
put_format(&buf, "\\def\\%scyl%cdescription{%s}\n", ssrf, 'a' + i, cyl.type.description.c_str());
put_format(&buf, "\\def\\%scyl%cgasname{%s}\n", ssrf, 'a' + i, gasname(cyl.gasmix));
put_format(&buf, "\\def\\%scyl%cmixO2{%.1f\\%%}\n", ssrf, 'a' + i, get_o2(cyl.gasmix)/10.0);
Expand Down Expand Up @@ -270,13 +265,11 @@ void export_TeX(const char *filename, bool selected_only, bool plain, ExportCall
void export_depths(const char *filename, bool selected_only)
{
FILE *f;
struct dive *dive;
int i;
const char *unit = NULL;

membuffer buf;

for_each_dive (i, dive) {
for (auto &dive: divelog.dives) {
if (selected_only && !dive->selected)
continue;

Expand Down
2 changes: 1 addition & 1 deletion commands/command_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ QString diveNumberOrDate(struct dive *d)
QString getListOfDives(const std::vector<struct dive*> &dives)
{
QString listOfDives;
if ((int)dives.size() == divelog.dives->nr)
if (dives.size() == divelog.dives.size())
return Base::tr("all dives");
int i = 0;
for (dive *d: dives) {
Expand Down
75 changes: 33 additions & 42 deletions commands/command_divelist.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ DiveToAdd DiveListBase::removeDive(struct dive *d, std::vector<std::unique_ptr<d
tripsToAdd.push_back(std::move(trip)); // Take ownership of trip
}

int idx = get_divenr(d);
if (idx < 0)
size_t idx = divelog.dives.get_idx(d);
if (idx == std::string::npos)
qWarning("Deletion of unknown dive!");

DiveFilter::instance()->diveRemoved(d);

res.dive.reset(unregister_dive(idx)); // Remove dive from backend
res.dive = divelog.dives.unregister_dive(idx); // Remove dive from backend

return res;
}
Expand Down Expand Up @@ -88,7 +88,7 @@ void processByTrip(std::vector<std::pair<dive_trip *, dive *>> &dives, Function
// Sort lexicographically by trip then according to the dive_less_than() function.
std::sort(dives.begin(), dives.end(),
[](const std::pair<dive_trip *, dive *> &e1, const std::pair<dive_trip *, dive *> &e2)
{ return e1.first == e2.first ? dive_less_than(e1.second, e2.second) : e1.first < e2.first; });
{ return e1.first == e2.first ? dive_less_than(*e1.second, *e2.second) : e1.first < e2.first; });

// Then, process the dives in batches by trip
size_t i, j; // Begin and end of batch
Expand Down Expand Up @@ -124,7 +124,8 @@ DivesAndTripsToAdd DiveListBase::removeDives(DivesAndSitesToRemove &divesAndSite
// Make sure that the dive list is sorted. The added dives will be sent in a signal
// and the recipients assume that the dives are sorted the same way as they are
// in the core list.
std::sort(divesAndSitesToDelete.dives.begin(), divesAndSitesToDelete.dives.end(), dive_less_than);
std::sort(divesAndSitesToDelete.dives.begin(), divesAndSitesToDelete.dives.end(),
[](const dive *d1, const dive *d2) { return dive_less_than(*d1, *d2); });

for (dive *d: divesAndSitesToDelete.dives)
divesToAdd.push_back(removeDive(d, tripsToAdd));
Expand Down Expand Up @@ -177,7 +178,7 @@ DivesAndSitesToRemove DiveListBase::addDives(DivesAndTripsToAdd &toAdd)
// in the core list.
std::sort(toAdd.dives.begin(), toAdd.dives.end(),
[](const DiveToAdd &d, const DiveToAdd &d2)
{ return dive_less_than(d.dive.get(), d2.dive.get()); });
{ return dive_less_than(*d.dive, *d2.dive); });

// Now, add the dives
// Note: the idiomatic STL-way would be std::transform, but let's use a loop since
Expand Down Expand Up @@ -411,12 +412,12 @@ AddDive::AddDive(dive *d, bool autogroup, bool newNumber)
divePtr->divetrip = nullptr;
divePtr->dive_site = nullptr;
if (!trip && autogroup) {
auto [t, allocated] = get_trip_for_new_dive(divePtr.get());
auto [t, allocated] = get_trip_for_new_dive(divelog, divePtr.get());
trip = t;
allocTrip = std::move(allocated);
}

int idx = dive_table_get_insertion_index(divelog.dives.get(), divePtr.get());
int idx = divelog.dives.get_insertion_index(divePtr.get());
if (newNumber)
divePtr->number = get_dive_nr_at_idx(idx);

Expand Down Expand Up @@ -455,18 +456,16 @@ void AddDive::undoit()

ImportDives::ImportDives(struct divelog *log, int flags, const QString &source)
{
setText(Command::Base::tr("import %n dive(s) from %1", "", log->dives->nr).arg(source));
setText(Command::Base::tr("import %n dive(s) from %1", "", log->dives.size()).arg(source));

// this only matters if undoit were called before redoit
currentDive = nullptr;

struct dive_table dives_to_add = empty_dive_table;
struct dive_table dives_to_remove = empty_dive_table;
struct trip_table trips_to_add;
dive_site_table sites_to_add;
process_imported_dives(log, flags,
&dives_to_add, &dives_to_remove, trips_to_add,
sites_to_add, devicesToAddAndRemove);
auto [dives_to_add, dives_to_remove, trips_to_add, sites_to_add, devices_to_add] =
process_imported_dives(*log, flags);

// Add devices to devicesToAddAndRemove structure
devicesToAddAndRemove = std::move(devices_to_add);

// Add trips to the divesToAdd.trips structure
divesToAdd.trips.reserve(trips_to_add.size());
Expand All @@ -477,9 +476,8 @@ ImportDives::ImportDives(struct divelog *log, int flags, const QString &source)
divesToAdd.sites = std::move(sites_to_add);

// Add dives to the divesToAdd.dives structure
divesToAdd.dives.reserve(dives_to_add.nr);
for (int i = 0; i < dives_to_add.nr; ++i) {
std::unique_ptr<dive> divePtr(dives_to_add.dives[i]);
divesToAdd.dives.reserve(dives_to_add.size());
for (auto &divePtr: dives_to_add) {
divePtr->selected = false; // See above in AddDive::AddDive()
dive_trip *trip = divePtr->divetrip;
divePtr->divetrip = nullptr; // See above in AddDive::AddDive()
Expand All @@ -490,9 +488,7 @@ ImportDives::ImportDives(struct divelog *log, int flags, const QString &source)
}

// Add dive to be deleted to the divesToRemove structure
divesAndSitesToRemove.dives.reserve(dives_to_remove.nr);
for (int i = 0; i < dives_to_remove.nr; ++i)
divesAndSitesToRemove.dives.push_back(dives_to_remove.dives[i]);
divesAndSitesToRemove.dives = std::move(dives_to_remove);

// When encountering filter presets with equal names, check whether they are
// the same. If they are, ignore them.
Expand All @@ -504,9 +500,6 @@ ImportDives::ImportDives(struct divelog *log, int flags, const QString &source)
continue;
filterPresetsToAdd.emplace_back(preset.name, preset.data);
}

free(dives_to_add.dives);
free(dives_to_remove.dives);
}

bool ImportDives::workToBeDone()
Expand Down Expand Up @@ -628,7 +621,7 @@ void ShiftTime::redoit()
}

// Changing times may have unsorted the dive and trip tables
sort_dive_table(divelog.dives.get());
divelog.dives.sort();
divelog.trips->sort();
for (dive_trip *trip: trips)
trip->sort_dives();
Expand Down Expand Up @@ -735,11 +728,9 @@ RemoveAutogenTrips::RemoveAutogenTrips()
{
setText(Command::Base::tr("remove autogenerated trips"));
// TODO: don't touch core-innards directly
int i;
struct dive *dive;
for_each_dive(i, dive) {
if (dive->divetrip && dive->divetrip->autogen)
divesToMove.divesToMove.push_back( {dive, nullptr} );
for (auto &d: divelog.dives) {
if (d->divetrip && d->divetrip->autogen)
divesToMove.divesToMove.push_back( {d.get(), nullptr} );
}
}

Expand Down Expand Up @@ -767,12 +758,12 @@ AutogroupDives::AutogroupDives()
{
setText(Command::Base::tr("autogroup dives"));

for (auto &entry: get_dives_to_autogroup(divelog.dives.get())) {
for (auto &entry: get_dives_to_autogroup(divelog.dives)) {
// If this is an allocated trip, take ownership
if (entry.created_trip)
divesToMove.tripsToAdd.push_back(std::move(entry.created_trip));
for (int i = entry.from; i < entry.to; ++i)
divesToMove.divesToMove.push_back( { divelog.dives->dives[i], entry.trip } );
for (auto it = divelog.dives.begin() + entry.from; it != divelog.dives.begin() + entry.to; ++it)
divesToMove.divesToMove.push_back( { it->get(), entry.trip } );
}
}

Expand Down Expand Up @@ -960,17 +951,18 @@ MergeDives::MergeDives(const QVector <dive *> &dives)
// We will only renumber the remaining dives if the joined dives are consecutive.
// Otherwise all bets are off concerning what the user wanted and doing nothing seems
// like the best option.
int idx = get_divenr(dives[0]);
int num = dives.count();
if (idx < 0 || idx + num > divelog.dives->nr) {
size_t idx = divelog.dives.get_idx(dives[0]);
size_t num = dives.count();
if (idx == std::string::npos) {
// It was the callers responsibility to pass only known dives.
// Something is seriously wrong - give up.
qWarning("Merging unknown dives");
return;
}
// std::equal compares two ranges. The parameters are (begin_range1, end_range1, begin_range2).
// Here, we can compare C-arrays, because QVector guarantees contiguous storage.
if (std::equal(&dives[0], &dives[0] + num, &divelog.dives->dives[idx]) &&
if (std::equal(&dives[0], &dives[0] + num, divelog.dives.begin() + idx, [](dive *d1,
const std::unique_ptr<dive> &d2) { return d1 == d2.get(); }) &&
dives[0]->number && dives.last()->number && dives[0]->number < dives.last()->number) {
// We have a consecutive set of dives. Rename all following dives according to the
// number of erased dives. This considers that there might be missing numbers.
Expand All @@ -986,15 +978,14 @@ MergeDives::MergeDives(const QVector <dive *> &dives)
// consecutive, and the difference will be 1, so the
// above example is not supposed to be normal.
int diff = dives.last()->number - dives[0]->number;
divesToRenumber.reserve(divelog.dives->nr - idx - num);
int previousnr = dives[0]->number;
for (int i = idx + num; i < divelog.dives->nr; ++i) {
int newnr = divelog.dives->dives[i]->number - diff;
for (size_t i = idx + num; i < divelog.dives.size(); ++i) {
int newnr = divelog.dives[i]->number - diff;

// Stop renumbering if stuff isn't in order (see also core/divelist.c)
if (newnr <= previousnr)
break;
divesToRenumber.append(QPair<dive *,int>(divelog.dives->dives[i], newnr));
divesToRenumber.append(QPair<dive *,int>(divelog.dives[i].get(), newnr));
previousnr = newnr;
}
}
Expand Down
8 changes: 3 additions & 5 deletions commands/command_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,9 @@ static std::vector<dive *> getDives(bool currentDiveOnly)
: std::vector<dive *> { };

std::vector<dive *> res;
struct dive *d;
int i;
for_each_dive (i, d) {
for (auto &d: divelog.dives) {
if (d->selected)
res.push_back(d);
res.push_back(d.get());
}
return res;
}
Expand Down Expand Up @@ -1443,7 +1441,7 @@ void EditDive::exchangeDives()
QVector<dive *> dives = { oldDive };
timestamp_t delta = oldDive->when - newDive->when;
if (delta != 0) {
sort_dive_table(divelog.dives.get());
divelog.dives.sort();
divelog.trips->sort();
if (newDive->divetrip != oldDive->divetrip)
qWarning("Command::EditDive::redo(): This command does not support moving between trips!");
Expand Down
2 changes: 2 additions & 0 deletions core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ set(SUBSURFACE_CORE_LIB_SRCS
divelogexportlogic.h
divesite.cpp
divesite.h
divesitetable.h
divesitehelpers.cpp
divesitehelpers.h
downloadfromdcthread.cpp
Expand Down Expand Up @@ -179,6 +180,7 @@ set(SUBSURFACE_CORE_LIB_SRCS
time.cpp
trip.cpp
trip.h
triptable.h
uemis-downloader.cpp
uemis.cpp
uemis.h
Expand Down
Loading

0 comments on commit b95ac3f

Please sign in to comment.