core: use std::vector<> to store divecomputer samples

This is a hairy one, because the sample code is rather tricky.

There was a pattern of looping through pairs of adjacent samples,
for interpolation purposes. Add an range adapter to generalize
such loops.

Removes the finish_sample() function: The code would call
prepare_sample() to start parsing of samples and then
finish_sample() to actuall add it. I.e. a kind of commit().

Since, with one exception, all users of prepare_sample()
called finish_sample() in all code paths, we might just add
the sample in the first place. The exception was sample_end()
in parse.cpp. This brings a small change: samples are now
added, even if they could only be parsed partially. I doubt
that this makes any difference, since it will only happen
for broken divelogs anyway.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-05-19 12:38:38 +02:00 committed by bstoeger
parent bc761344d4
commit f120fecccb
28 changed files with 588 additions and 715 deletions

View file

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

View file

@ -138,14 +138,14 @@ void DivePlannerPointsModel::loadFromDive(dive *dIn, int dcNrIn)
bool hasMarkedSamples = false;
if (dc->samples)
hasMarkedSamples = dc->sample[0].manually_entered;
if (!dc->samples.empty())
hasMarkedSamples = dc->samples[0].manually_entered;
else
fake_dc(dc);
// if this dive has more than 100 samples (so it is probably a logged dive),
// average samples so we end up with a total of 100 samples.
int plansamples = dc->samples <= 100 ? dc->samples : 100;
int plansamples = std::min(static_cast<int>(dc->samples.size()), 100);
int j = 0;
int cylinderid = 0;
@ -153,12 +153,12 @@ void DivePlannerPointsModel::loadFromDive(dive *dIn, int dcNrIn)
for (int i = 0; i < plansamples - 1; i++) {
if (dc->last_manual_time.seconds && dc->last_manual_time.seconds > 120 && lasttime.seconds >= dc->last_manual_time.seconds)
break;
while (j * plansamples <= i * dc->samples) {
const sample &s = dc->sample[j];
while (j * plansamples <= i * static_cast<int>(dc->samples.size())) {
const sample &s = dc->samples[j];
if (s.time.seconds != 0 && (!hasMarkedSamples || s.manually_entered)) {
depthsum += s.depth.mm;
if (j > 0)
last_sp = dc->sample[j-1].setpoint;
last_sp = dc->samples[j-1].setpoint;
++samplecount;
newtime = s.time;
}