core: move get_dive_dc() to struct dive

Feels natural in a C++ code base.

This removes a nullptr-check so some care has to be taken.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-06-30 20:38:12 +02:00 committed by bstoeger
parent 731052c776
commit f1f082d86a
15 changed files with 59 additions and 55 deletions

View file

@ -434,13 +434,13 @@ EditMode::EditMode(int indexIn, int newValue, bool currentDiveOnly)
void EditMode::set(struct dive *d, int i) const
{
get_dive_dc(d, index)->divemode = (enum divemode_t)i;
update_setpoint_events(d, get_dive_dc(d, index));
d->get_dc(index)->divemode = (enum divemode_t)i;
update_setpoint_events(d, d->get_dc(index));
}
int EditMode::data(struct dive *d) const
{
return get_dive_dc(d, index)->divemode;
return d->get_dc(index)->divemode;
}
QString EditMode::fieldName() const
@ -862,7 +862,7 @@ EditProfile::EditProfile(const dive *source, int dcNr, EditProfileType type, int
dcmaxdepth({0}),
duration({0})
{
const struct divecomputer *sdc = get_dive_dc(source, dcNr);
const struct divecomputer *sdc = source->get_dc(dcNr);
if (!sdc)
d = nullptr; // Signal that we refuse to do anything.
if (!d)
@ -890,7 +890,7 @@ bool EditProfile::workToBeDone()
void EditProfile::undo()
{
struct divecomputer *sdc = get_dive_dc(d, dcNr);
struct divecomputer *sdc = d->get_dc(dcNr);
if (!sdc)
return;
std::swap(sdc->samples, dc.samples);
@ -1286,7 +1286,7 @@ void EditCylinder::undo()
}
EditSensors::EditSensors(int toCylinderIn, int fromCylinderIn, int dcNr)
: d(current_dive), dc(get_dive_dc(d, dcNr)), toCylinder(toCylinderIn), fromCylinder(fromCylinderIn)
: d(current_dive), dc(d->get_dc(dcNr)), toCylinder(toCylinderIn), fromCylinder(fromCylinderIn)
{
if (!d || !dc)
return;

View file

@ -48,13 +48,13 @@ bool AddEventBase::workToBeDone()
void AddEventBase::redoit()
{
struct divecomputer *dc = get_dive_dc(d, dcNr);
struct divecomputer *dc = d->get_dc(dcNr);
idx = add_event_to_dc(dc, ev); // return ownership to backend
}
void AddEventBase::undoit()
{
struct divecomputer *dc = get_dive_dc(d, dcNr);
struct divecomputer *dc = d->get_dc(dcNr);
ev = remove_event_from_dc(dc, idx);
}
@ -80,13 +80,13 @@ AddEventSetpointChange::AddEventSetpointChange(struct dive *d, int dcNr, int sec
void AddEventSetpointChange::undoit()
{
AddEventBase::undoit();
std::swap(get_dive_dc(d, dcNr)->divemode, divemode);
std::swap(d->get_dc(dcNr)->divemode, divemode);
}
void AddEventSetpointChange::redoit()
{
AddEventBase::redoit();
std::swap(get_dive_dc(d, dcNr)->divemode, divemode);
std::swap(d->get_dc(dcNr)->divemode, divemode);
}
RenameEvent::RenameEvent(struct dive *d, int dcNr, int idx, const std::string name) : EventBase(d, dcNr),
@ -103,7 +103,7 @@ bool RenameEvent::workToBeDone()
void RenameEvent::redoit()
{
struct divecomputer *dc = get_dive_dc(d, dcNr);
struct divecomputer *dc = d->get_dc(dcNr);
event *ev = get_event(dc, idx);
if (ev)
std::swap(ev->name, name);
@ -118,7 +118,7 @@ void RenameEvent::undoit()
RemoveEvent::RemoveEvent(struct dive *d, int dcNr, int idx) : EventBase(d, dcNr),
idx(idx), cylinder(-1)
{
struct divecomputer *dc = get_dive_dc(d, dcNr);
struct divecomputer *dc = d->get_dc(dcNr);
event *ev = get_event(dc, idx);
if (ev && (ev->type == SAMPLE_EVENT_GASCHANGE2 || ev->type == SAMPLE_EVENT_GASCHANGE))
cylinder = ev->gas.index;
@ -132,13 +132,13 @@ bool RemoveEvent::workToBeDone()
void RemoveEvent::redoit()
{
struct divecomputer *dc = get_dive_dc(d, dcNr);
struct divecomputer *dc = d->get_dc(dcNr);
ev = remove_event_from_dc(dc, idx);
}
void RemoveEvent::undoit()
{
struct divecomputer *dc = get_dive_dc(d, dcNr);
struct divecomputer *dc = d->get_dc(dcNr);
idx = add_event_to_dc(dc, std::move(ev));
}
@ -160,7 +160,7 @@ AddGasSwitch::AddGasSwitch(struct dive *d, int dcNr, int seconds, int tank) : Ev
// If there is a gas change at this time stamp, remove it before adding the new one.
// There shouldn't be more than one gas change per time stamp. Just in case we'll
// support that anyway.
struct divecomputer *dc = get_dive_dc(d, dcNr);
struct divecomputer *dc = d->get_dc(dcNr);
// Note that we remove events in reverse order so that the indexes don't change
// meaning while removing. This should be an extremely rare case anyway.
@ -186,7 +186,7 @@ void AddGasSwitch::redoit()
std::vector<int> newEventsToRemove;
newEventsToAdd.reserve(eventsToRemove.size());
newEventsToRemove.reserve(eventsToAdd.size());
struct divecomputer *dc = get_dive_dc(d, dcNr);
struct divecomputer *dc = d->get_dc(dcNr);
for (int idx: eventsToRemove)
newEventsToAdd.push_back(remove_event_from_dc(dc, idx));

View file

@ -246,7 +246,7 @@ void copy_events_until(const struct dive *sd, struct dive *dd, int dcNr, int tim
return;
const struct divecomputer *s = &sd->dcs[0];
struct divecomputer *d = get_dive_dc(dd, dcNr);
struct divecomputer *d = dd->get_dc(dcNr);
if (!s || !d)
return;
@ -2513,17 +2513,17 @@ int dive::number_of_computers() const
return static_cast<int>(dcs.size());
}
struct divecomputer *get_dive_dc(struct dive *dive, int nr)
struct divecomputer *dive::get_dc(int nr)
{
if (!dive || dive->dcs.empty())
if (dcs.empty()) // Can't happen!
return NULL;
nr = std::max(0, nr);
return &dive->dcs[static_cast<size_t>(nr) % dive->dcs.size()];
return &dcs[static_cast<size_t>(nr) % dcs.size()];
}
const struct divecomputer *get_dive_dc(const struct dive *dive, int nr)
const struct divecomputer *dive::get_dc(int nr) const
{
return get_dive_dc((struct dive *)dive, nr);
return const_cast<dive &>(*this).get_dc(nr);
}
bool dive::dive_has_gps_location() const

View file

@ -82,6 +82,9 @@ struct dive {
void invalidate_cache();
bool cache_is_valid() const;
struct divecomputer *get_dc(int nr);
const struct divecomputer *get_dc(int nr) const;
void clear();
int number_of_computers() const;
void fixup_no_cylinder(); /* to fix cylinders, we need the divelist (to calculate cns) */
@ -162,8 +165,6 @@ extern fraction_t best_he(depth_t depth, const struct dive *dive, bool o2narcoti
extern std::string get_dive_country(const struct dive *dive);
extern std::string get_dive_location(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 std::unique_ptr<dive> clone_make_first_dc(const struct dive &d, int dc_number);

View file

@ -667,7 +667,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
int laststoptime = timestep;
bool o2breaking = false;
int decostopcounter = 0;
struct divecomputer *dc = get_dive_dc(dive, dcNr);
struct divecomputer *dc = dive->get_dc(dcNr);
enum divemode_t divemode = dc->divemode;
set_gf(diveplan->gflow, diveplan->gfhigh);

View file

@ -52,7 +52,7 @@ DivePlannerWidget::DivePlannerWidget(dive &planned_dive, int dcNr, PlannerWidget
view->setColumnHidden(CylindersModel::SENSORS, true);
view->setItemDelegateForColumn(CylindersModel::TYPE, new TankInfoDelegate(this));
auto tankUseDelegate = new TankUseDelegate(this);
tankUseDelegate->setCurrentDC(get_dive_dc(&planned_dive, dcNr));
tankUseDelegate->setCurrentDC(planned_dive.get_dc(dcNr));
view->setItemDelegateForColumn(CylindersModel::USE, tankUseDelegate);
connect(ui.cylinderTableWidget, &TableView::addButtonClicked, plannerModel, &DivePlannerPointsModel::addCylinder_clicked);
connect(ui.tableWidget, &TableView::addButtonClicked, plannerModel, &DivePlannerPointsModel::addDefaultStop);
@ -563,7 +563,7 @@ int PlannerWidgets::getDcNr()
divemode_t PlannerWidgets::getRebreatherMode() const
{
return get_dive_dc(planned_dive.get(), dcNr)->divemode;
return planned_dive->get_dc(dcNr)->divemode;
}
void PlannerWidgets::preparePlanDive(const dive *currentDive, int currentDcNr)
@ -575,8 +575,8 @@ void PlannerWidgets::preparePlanDive(const dive *currentDive, int currentDcNr)
// plan the dive in the same mode as the currently selected one
if (currentDive) {
plannerSettingsWidget.setDiveMode(get_dive_dc(currentDive, currentDcNr)->divemode);
plannerSettingsWidget.setBailoutVisibility(get_dive_dc(currentDive, currentDcNr)->divemode);
plannerSettingsWidget.setDiveMode(currentDive->get_dc(currentDcNr)->divemode);
plannerSettingsWidget.setBailoutVisibility(currentDive->get_dc(currentDcNr)->divemode);
if (currentDive->salinity)
plannerWidget.setSalinity(currentDive->salinity);
else // No salinity means salt water

View file

@ -663,7 +663,7 @@ void MainWindow::on_actionReplanDive_triggered()
if (!plannerStateClean() || !current_dive || !userMayChangeAppState())
return;
const struct divecomputer *dc = get_dive_dc(current_dive, profile->dc);
const struct divecomputer *dc = current_dive->get_dc(profile->dc);
if (!(is_dc_planner(dc) || is_dc_manually_added_dive(dc))) {
if (QMessageBox::warning(this, tr("Warning"), tr("Trying to replan a dive profile that has not been manually added."),
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Cancel)

View file

@ -167,7 +167,7 @@ void ProfileWidget::setDive(const struct dive *d, int dcNr)
{
stack->setCurrentIndex(1); // show profile
bool freeDiveMode = get_dive_dc(d, dcNr)->divemode == FREEDIVE;
bool freeDiveMode = d->get_dc(dcNr)->divemode == FREEDIVE;
ui.profCalcCeiling->setDisabled(freeDiveMode);
ui.profCalcCeiling->setDisabled(freeDiveMode);
ui.profCalcAllTissues ->setDisabled(freeDiveMode);
@ -219,7 +219,7 @@ void ProfileWidget::plotDive(dive *dIn, int dcIn)
// or already editing the dive, switch to edit mode.
if (d && !editedDive &&
DivePlannerPointsModel::instance()->currentMode() == DivePlannerPointsModel::NOTHING) {
struct divecomputer *comp = get_dive_dc(d, dc);
struct divecomputer *comp = d->get_dc(dc);
if (comp && is_dc_manually_added_dive(comp) && !comp->samples.empty() && comp->samples.size() <= 50)
editDive();
}
@ -346,7 +346,7 @@ void ProfileWidget::exitEditMode()
// Update depths of edited dive
static void calcDepth(dive &d, int dcNr)
{
d.maxdepth.mm = get_dive_dc(&d, dcNr)->maxdepth.mm = 0;
d.maxdepth.mm = d.get_dc(dcNr)->maxdepth.mm = 0;
divelog.dives.fixup_dive(d);
}

View file

@ -138,7 +138,7 @@ void TabDiveEquipment::toggleTriggeredColumn()
void TabDiveEquipment::updateData(const std::vector<dive *> &, dive *currentDive, int currentDC)
{
divecomputer *dc = get_dive_dc(currentDive, currentDC);
divecomputer *dc = currentDive->get_dc(currentDC);
cylindersModel->updateDive(currentDive, currentDC);
weightModel->updateDive(currentDive);

View file

@ -21,9 +21,8 @@ TabDiveExtraInfo::~TabDiveExtraInfo()
void TabDiveExtraInfo::updateData(const std::vector<dive *> &, dive *currentDive, int currentDC)
{
const struct divecomputer *currentdc = get_dive_dc(currentDive, currentDC);
if (currentdc)
extraDataModel->updateDiveComputer(currentdc);
if (currentDive)
extraDataModel->updateDiveComputer(currentDive->get_dc(currentDC));
ui->extraData->setVisible(false); // This will cause the resize to include rows outside the current viewport
ui->extraData->resizeColumnsToContents();

View file

@ -188,5 +188,5 @@ bool MainTab::includesCurrentDive(const QVector<dive *> &dives) const
divecomputer *MainTab::getCurrentDC() const
{
return get_dive_dc(currentDive, currentDC);
return currentDive ? currentDive->get_dc(currentDC) : nullptr;
}

View file

@ -213,9 +213,9 @@ static bool ppGraphsEnabled(const struct divecomputer *dc, bool simplified)
// Update visibility of non-interactive chart features according to preferences
void ProfileScene::updateVisibility(bool diveHasHeartBeat, bool simplified)
{
const struct divecomputer *currentdc = get_dive_dc(d, dc);
if (!currentdc)
if (!d)
return;
const struct divecomputer *currentdc = d->get_dc(dc);
bool ppGraphs = ppGraphsEnabled(currentdc, simplified);
diveCeiling->setVisible(prefs.calcceiling);
@ -291,9 +291,9 @@ struct VerticalAxisLayout {
void ProfileScene::updateAxes(bool diveHasHeartBeat, bool simplified)
{
const struct divecomputer *currentdc = get_dive_dc(d, dc);
if (!currentdc)
if (!d)
return;
const struct divecomputer *currentdc = d->get_dc(dc);
// Calculate left and right border needed for the axes and other chart items.
double leftBorder = profileYAxis->width();
@ -428,7 +428,7 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM
decoModelParameters->set(QString("GF %1/%2").arg(diveplan.gflow).arg(diveplan.gfhigh), getColor(PRESSURE_TEXT));
}
const struct divecomputer *currentdc = get_dive_dc(d, dc);
const struct divecomputer *currentdc = d->get_dc(dc);
if (!currentdc || currentdc->samples.empty()) {
clear();
return;

View file

@ -532,7 +532,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
// figure out if we are ontop of the dive computer name in the profile
QGraphicsItem *sceneItem = itemAt(mapFromGlobal(event->globalPos()));
if (isDiveTextItem(sceneItem, profileScene->diveComputerText)) {
const struct divecomputer *currentdc = get_dive_dc(d, dc);
const struct divecomputer *currentdc = d->get_dc(dc);
if (!currentdc->deviceid && dc == 0 && d->number_of_computers() == 1)
// nothing to do, can't rename, delete or reorder
return;
@ -576,7 +576,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
m.addAction(tr("Add bookmark"), [this, seconds]() { addBookmark(seconds); });
m.addAction(tr("Split dive into two"), [this, seconds]() { splitDive(seconds); });
divemode_loop loop(*get_dive_dc(d, dc));
divemode_loop loop(*d->get_dc(dc));
divemode_t divemode = loop.next(seconds);
QMenu *changeMode = m.addMenu(tr("Change divemode"));
if (divemode != OC)
@ -644,7 +644,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
}
m2->addAction(tr("All event types"), this, &ProfileWidget2::unhideEventTypes);
}
const struct divecomputer *currentdc = get_dive_dc(d, dc);
const struct divecomputer *currentdc = d->get_dc(dc);
if (currentdc && std::any_of(currentdc->events.begin(), currentdc->events.end(),
[] (auto &ev) { return ev.hidden; }))
m.addAction(tr("Unhide individually hidden events of this dive"), this, &ProfileWidget2::unhideEvents);
@ -671,10 +671,10 @@ void ProfileWidget2::makeFirstDC()
void ProfileWidget2::renameCurrentDC()
{
bool ok;
struct divecomputer *currentdc = get_dive_dc(mutable_dive(), dc);
if (!currentdc)
if (!d)
return;
bool ok;
struct divecomputer *currentdc = mutable_dive()->get_dc(dc);
QString newName = QInputDialog::getText(this, tr("Edit nickname"),
tr("Set new nickname for %1 (serial %2):").arg(QString::fromStdString(currentdc->model)).
arg(QString::fromStdString(currentdc->serial)),
@ -685,7 +685,9 @@ void ProfileWidget2::renameCurrentDC()
void ProfileWidget2::hideEvent(DiveEventItem *item)
{
struct divecomputer *currentdc = get_dive_dc(mutable_dive(), dc);
if (!d)
return;
struct divecomputer *currentdc = mutable_dive()->get_dc(dc);
int idx = item->idx;
if (!currentdc || idx < 0 || static_cast<size_t>(idx) >= currentdc->events.size())
return;
@ -704,7 +706,9 @@ void ProfileWidget2::hideEventType(DiveEventItem *item)
void ProfileWidget2::unhideEvents()
{
struct divecomputer *currentdc = get_dive_dc(mutable_dive(), dc);
if (!d)
return;
struct divecomputer *currentdc = mutable_dive()->get_dc(dc);
if (!currentdc)
return;
for (auto &ev: currentdc->events)

View file

@ -242,7 +242,7 @@ QVariant CylindersModel::data(const QModelIndex &index, int role) const
return static_cast<int>(cyl->type.size.mliter);
case SENSORS: {
std::vector<int16_t> sensors;
const struct divecomputer *currentdc = get_dive_dc(d, dcNr);
const struct divecomputer *currentdc = d->get_dc(dcNr);
for (const auto &sample: currentdc->samples) {
for (int s = 0; s < MAX_SENSORS; ++s) {
if (sample.pressure[s].mbar) {

View file

@ -119,7 +119,7 @@ void DivePlannerPointsModel::loadFromDive(dive *dIn, int dcNrIn)
int depthsum = 0;
int samplecount = 0;
o2pressure_t last_sp;
struct divecomputer *dc = get_dive_dc(d, dcNr);
struct divecomputer *dc = d->get_dc(dcNr);
cylinders.updateDive(d, dcNr);
duration_t lasttime;
duration_t lastrecordedtime;
@ -539,7 +539,7 @@ int DivePlannerPointsModel::gfLow() const
void DivePlannerPointsModel::setRebreatherMode(int mode)
{
get_dive_dc(d, dcNr)->divemode = (divemode_t) mode;
d->get_dc(dcNr)->divemode = (divemode_t) mode;
for (int i = 0; i < rowCount(); i++) {
divepoints[i].setpoint = mode == CCR ? prefs.defaultsetpoint : 0;
divepoints[i].divemode = (enum divemode_t) mode;
@ -820,7 +820,7 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, int cylinderid_
}
}
if (divemode == UNDEF_COMP_TYPE)
divemode = get_dive_dc(d, dcNr)->divemode;
divemode = d->get_dc(dcNr)->divemode;
// add the new stop
beginInsertRows(QModelIndex(), row, row);