general: simplify a few unit manipulations

Now that we have defined addition and subtraction on unit
classes, let's use them in a few examples.

Yes, some of these are a bit pointless, because they are
of the kind
        a.mbar - b.mbar => (a-b).mbar

However, these probably should be further simplified
by storing the result in a unit type.

This commit is mostly a proof-of-concept.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
Berthold Stoeger 2024-09-02 20:42:05 +02:00 committed by bstoeger
parent 729cc16fc5
commit 110e64bc66
14 changed files with 59 additions and 68 deletions

View file

@ -204,7 +204,7 @@ void export_TeX(const char *filename, bool selected_only, bool plain, ExportCall
put_format(&buf, "\\def\\%scyl%cmixO2{%.1f\\%%}\n", ssrf, 'a' + i, get_o2(cyl.gasmix)/10.0);
put_format(&buf, "\\def\\%scyl%cmixHe{%.1f\\%%}\n", ssrf, 'a' + i, get_he(cyl.gasmix)/10.0);
put_format(&buf, "\\def\\%scyl%cmixN2{%.1f\\%%}\n", ssrf, 'a' + i, (100.0 - (get_o2(cyl.gasmix)/10.0) - (get_he(cyl.gasmix)/10.0)));
delta_p.mbar += cyl.start.mbar - cyl.end.mbar;
delta_p += cyl.start - cyl.end;
put_format(&buf, "\\def\\%scyl%cstartpress{%.1f\\%spressureunit}\n", ssrf, 'a' + i, get_pressure_units(cyl.start.mbar, &unit)/1.0, ssrf);
put_format(&buf, "\\def\\%scyl%cendpress{%.1f\\%spressureunit}\n", ssrf, 'a' + i, get_pressure_units(cyl.end.mbar, &unit)/1.0, ssrf);
qty_cyl += 1;

View file

@ -1260,8 +1260,8 @@ EditCylinder::EditCylinder(int index, cylinder_t cylIn, EditCylinderType typeIn,
cyl[i].cylinder_use = cylIn.cylinder_use;
break;
case EditCylinderType::PRESSURE:
cyl[i].start.mbar = cylIn.start.mbar;
cyl[i].end.mbar = cylIn.end.mbar;
cyl[i].start = cylIn.start;
cyl[i].end = cylIn.end;
break;
case EditCylinderType::GASMIX:
cyl[i].gasmix = cylIn.gasmix;

View file

@ -469,7 +469,7 @@ static void update_min_max_temperatures(struct dive &dive, temperature_t tempera
*/
static int same_rounded_pressure(pressure_t a, pressure_t b)
{
return abs(a.mbar - b.mbar) <= 500;
return abs((a - b).mbar) <= 500;
}
static double calculate_depth_to_mbarf(int depth, pressure_t surface_pressure, int salinity);
@ -678,7 +678,7 @@ static void fixup_duration(struct dive &dive)
if (logged || !is_dc_planner(&dc))
duration.seconds = std::max(duration.seconds, dc.duration.seconds);
}
dive.duration.seconds = duration.seconds;
dive.duration = duration;
}
static void fixup_watertemp(struct dive &dive)
@ -724,7 +724,7 @@ static void fixup_dc_events(struct divecomputer &dc)
continue;
for (int idx2 = idx - 1; idx2 > 0; --idx2) {
const auto &prev = dc.events[idx2];
if (event.time.seconds - prev.time.seconds > 60)
if ((event.time - prev.time).seconds > 60)
break;
if (range_contains(to_delete, idx2))
continue;
@ -1115,12 +1115,12 @@ static void merge_one_sample(const struct sample &sample, struct divecomputer &d
/* Init a few values from prev sample to avoid useless info in XML */
surface.bearing.degrees = prev.bearing.degrees;
surface.ndl.seconds = prev.ndl.seconds;
surface.ndl = prev.ndl;
surface.time.seconds = last_time + 20;
append_sample(surface, &dc);
surface.time.seconds = sample.time.seconds - 20;
surface.time = sample.time - duration_t { .seconds = 20 };
append_sample(surface, &dc);
}
}
@ -1402,7 +1402,7 @@ static void sample_renumber(struct sample &s, const struct sample *prev, const i
s.pressure[j].mbar = 0;
} else {
s.sensor[j] = prev->sensor[j];
s.pressure[j].mbar = prev->pressure[j].mbar;
s.pressure[j] = prev->pressure[j];
}
} else {
s.sensor[j] = sensor;
@ -1547,9 +1547,9 @@ static pressure_t merge_pressures(pressure_t a, pressure_t sample_a, pressure_t
static void merge_one_cylinder(cylinder_t *a, const cylinder_t *b)
{
if (!a->type.size.mliter)
a->type.size.mliter = b->type.size.mliter;
a->type.size = b->type.size;
if (!a->type.workingpressure.mbar)
a->type.workingpressure.mbar = b->type.workingpressure.mbar;
a->type.workingpressure = b->type.workingpressure;
if (a->type.description.empty())
a->type.description = b->type.description;
@ -1562,8 +1562,8 @@ static void merge_one_cylinder(cylinder_t *a, const cylinder_t *b)
a->end = merge_pressures(a->end, a->sample_end, b->end, b->sample_end, true);
/* Really? */
a->gas_used.mliter += b->gas_used.mliter;
a->deco_gas_used.mliter += b->deco_gas_used.mliter;
a->gas_used += b->gas_used;
a->deco_gas_used += b->deco_gas_used;
a->bestmix_o2 = a->bestmix_o2 && b->bestmix_o2;
a->bestmix_he = a->bestmix_he && b->bestmix_he;
}
@ -1737,7 +1737,7 @@ static int compare_sample(const struct sample &s, const struct sample &a, const
int diff;
if (offset) {
unsigned int interval = b.time.seconds - a.time.seconds;
unsigned int interval = (b.time - a.time).seconds;
unsigned int depth_a = a.depth.mm;
unsigned int depth_b = b.depth.mm;

View file

@ -151,10 +151,9 @@ static int calculate_otu(const struct dive &dive)
double otu = 0.0;
const struct divecomputer *dc = &dive.dcs[0];
for (auto [psample, sample]: pairwise_range(dc->samples)) {
int t;
int po2i, po2f;
double pm;
t = sample.time.seconds - psample.time.seconds;
int t = (sample.time - psample.time).seconds;
// if there is sensor data use sensor[0]
if ((dc->divemode == CCR || dc->divemode == PSCR) && sample.o2sensor[0].mbar) {
po2i = psample.o2sensor[0].mbar;
@ -215,7 +214,7 @@ static double calculate_cns_dive(const struct dive &dive)
double rate;
/* Calculate the CNS for each sample in this dive and sum them */
for (auto [psample, sample]: pairwise_range(dc->samples)) {
int t = sample.time.seconds - psample.time.seconds;
int t = (sample.time - psample.time).seconds;
int po2 = get_sample_o2(dive, dc, sample, psample);
/* Don't increase CNS when po2 below 500 matm */
if (po2 <= 500)

View file

@ -110,7 +110,7 @@ static void exportHTMLstatistics(const QString filename, struct htmlExportSettin
out << "\"MAX_TEMP\":\"" << (s.max_temp.mkelvin == 0 ? 0 : get_temperature_string(s.max_temp)) << "\",";
out << "},";
total_stats.selection_size += s.selection_size;
total_stats.total_time.seconds += s.total_time.seconds;
total_stats.total_time += s.total_time;
}
exportHTMLstatisticsTotal(out, &total_stats);
}

View file

@ -93,16 +93,17 @@ static weight_t get_weight(const char *line)
static pressure_t get_airpressure(const char *line)
{
pressure_t p;
p.mbar = lrint(ascii_strtod(line, NULL));
return p;
return pressure_t { .mbar = static_cast<int32_t>(lrint(ascii_strtod(line, NULL))) };
}
static pressure_t get_pressure(const char *line)
{
pressure_t p;
p.mbar = lrint(1000 * ascii_strtod(line, NULL));
return p;
return pressure_t { .mbar = static_cast<int32_t>(lrint(1000 * ascii_strtod(line, NULL))) };
}
static o2pressure_t get_o2pressure(const char *line)
{
return o2pressure_t { .mbar = static_cast<uint16_t>(lrint(1000 * ascii_strtod(line, NULL))) };
}
static int get_salinity(const char *line)
@ -557,43 +558,35 @@ static void parse_sample_keyvalue(void *_sample, const char *key, const std::str
}
if (!strcmp(key, "po2")) {
pressure_t p = get_pressure(value.c_str());
sample->setpoint.mbar = p.mbar;
sample->setpoint = get_o2pressure(value.c_str());
return;
}
if (!strcmp(key, "sensor1")) {
pressure_t p = get_pressure(value.c_str());
sample->o2sensor[0].mbar = p.mbar;
sample->o2sensor[0] = get_o2pressure(value.c_str());
return;
}
if (!strcmp(key, "sensor2")) {
pressure_t p = get_pressure(value.c_str());
sample->o2sensor[1].mbar = p.mbar;
sample->o2sensor[1] = get_o2pressure(value.c_str());
return;
}
if (!strcmp(key, "sensor3")) {
pressure_t p = get_pressure(value.c_str());
sample->o2sensor[2].mbar = p.mbar;
sample->o2sensor[2] = get_o2pressure(value.c_str());
return;
}
if (!strcmp(key, "sensor4")) {
pressure_t p = get_pressure(value.c_str());
sample->o2sensor[3].mbar = p.mbar;
sample->o2sensor[3] = get_o2pressure(value.c_str());
return;
}
if (!strcmp(key, "sensor5")) {
pressure_t p = get_pressure(value.c_str());
sample->o2sensor[4].mbar = p.mbar;
sample->o2sensor[4] = get_o2pressure(value.c_str());
return;
}
if (!strcmp(key, "sensor6")) {
pressure_t p = get_pressure(value.c_str());
sample->o2sensor[5].mbar = p.mbar;
sample->o2sensor[5] = get_o2pressure(value.c_str());
return;
}
if (!strcmp(key, "o2pressure")) {
pressure_t p = get_pressure(value.c_str());
sample->pressure[1].mbar = p.mbar;
sample->pressure[1] = get_pressure(value.c_str());
return;
}
if (!strcmp(key, "heartbeat")) {

View file

@ -678,7 +678,7 @@ static void eventtime(const char *buffer, duration_t *duration, struct parser_st
{
sampletime(buffer, duration);
if (state->cur_sample)
duration->seconds += state->cur_sample->time.seconds;
*duration += state->cur_sample->time;
}
static void try_to_match_autogroup(const char *name, char *buf, struct parser_state *state)

View file

@ -185,12 +185,12 @@ static void update_cylinder_pressure(struct dive *d, int old_depth, int new_dept
return;
mean_depth.mm = (old_depth + new_depth) / 2;
gas_used.mliter = lrint(d->depth_to_atm(mean_depth.mm) * sac / 60 * duration * factor / 1000);
cyl->gas_used.mliter += gas_used.mliter;
cyl->gas_used += gas_used;
if (in_deco)
cyl->deco_gas_used.mliter += gas_used.mliter;
cyl->deco_gas_used += gas_used;
if (cyl->type.size.mliter) {
delta_p.mbar = lrint(gas_used.mliter * 1000.0 / cyl->type.size.mliter * gas_compressibility_factor(cyl->gasmix, cyl->end.mbar / 1000.0));
cyl->end.mbar -= delta_p.mbar;
cyl->end -= delta_p;
}
}

View file

@ -111,7 +111,7 @@ static int get_local_sac(struct plot_info &pi, int idx1, int idx2, struct dive *
struct plot_data &entry1 = pi.entry[idx1];
struct plot_data &entry2 = pi.entry[idx2];
int duration = entry2.sec - entry1.sec;
int depth, airuse;
int depth;
pressure_t a, b;
double atm;
@ -128,11 +128,10 @@ static int get_local_sac(struct plot_info &pi, int idx1, int idx2, struct dive *
cyl = dive->get_cylinder(index);
// TODO: Implement addition/subtraction on units.h types
airuse = cyl->gas_volume(a).mliter - cyl->gas_volume(b).mliter;
volume_t airuse = cyl->gas_volume(a) - cyl->gas_volume(b);
/* milliliters per minute */
return lrint(airuse / atm * 60 / duration);
return lrint(airuse.mliter / atm * 60 / duration);
}
static velocity_t velocity(int speed)
@ -471,7 +470,7 @@ static int sac_between(const struct dive *dive, const struct plot_info &pi, int
return 0;
/* Get airuse for the set of cylinders over the range */
int airuse = 0;
volume_t airuse;
for (int i = 0; i < pi.nr_cylinders; i++) {
pressure_t a, b;
@ -482,11 +481,11 @@ static int sac_between(const struct dive *dive, const struct plot_info &pi, int
b.mbar = get_plot_pressure(pi, last, i);
const cylinder_t *cyl = dive->get_cylinder(i);
// TODO: Implement addition/subtraction on units.h types
int cyluse = cyl->gas_volume(a).mliter - cyl->gas_volume(b).mliter;
if (cyluse > 0)
volume_t cyluse = cyl->gas_volume(a) - cyl->gas_volume(b);
if (cyluse.mliter > 0)
airuse += cyluse;
}
if (!airuse)
if (!airuse.mliter)
return 0;
/* Calculate depthpressure integrated over time */
@ -505,7 +504,7 @@ static int sac_between(const struct dive *dive, const struct plot_info &pi, int
pressuretime /= 60;
/* SAC = mliter per minute */
return lrint(airuse / pressuretime);
return lrint(airuse.mliter / pressuretime);
}
/* Is there pressure data for all gases? */
@ -1168,13 +1167,13 @@ static void fill_o2_values(const struct dive *dive, const struct divecomputer *d
if (dc->divemode == CCR || (dc->divemode == PSCR && dc->no_o2sensors)) {
if (i == 0) { // For 1st iteration, initialise the last_sensor values
for (j = 0; j < dc->no_o2sensors; j++)
last_sensor[j].mbar = entry.o2sensor[j].mbar;
last_sensor[j] = entry.o2sensor[j];
} else { // Now re-insert the missing oxygen pressure values
for (j = 0; j < dc->no_o2sensors; j++)
if (entry.o2sensor[j].mbar)
last_sensor[j].mbar = entry.o2sensor[j].mbar;
last_sensor[j] = entry.o2sensor[j];
else
entry.o2sensor[j].mbar = last_sensor[j].mbar;
entry.o2sensor[j] = last_sensor[j];
} // having initialised the empty o2 sensor values for this point on the profile,
amb_pressure.mbar = dive->depth_to_mbar(entry.depth);
o2pressure.mbar = calculate_ccr_po2(entry, dc); // ...calculate the po2 based on the sensor data
@ -1467,7 +1466,7 @@ std::vector<std::string> compare_samples(const struct dive *d, const struct plot
int last_sec = start.sec;
volume_t cylinder_volume = { .mliter = 0, };
volume_t cylinder_volume;
std::vector<int> start_pressures(pi.nr_cylinders, 0);
std::vector<int> last_pressures(pi.nr_cylinders, 0);
std::vector<int> bar_used(pi.nr_cylinders, 0);
@ -1504,8 +1503,8 @@ std::vector<std::string> compare_samples(const struct dive *d, const struct plot
const cylinder_t *cyl = d->get_cylinder(cylinder_index);
// TODO: Implement addition/subtraction on units.h types
volumes_used[cylinder_index] += cyl->gas_volume((pressure_t){ .mbar = last_pressures[cylinder_index] }).mliter -
cyl->gas_volume((pressure_t){ .mbar = next_pressure }).mliter;
volumes_used[cylinder_index] += (cyl->gas_volume((pressure_t){ .mbar = last_pressures[cylinder_index] }) -
cyl->gas_volume((pressure_t){ .mbar = next_pressure })).mliter;
}
// check if the gas in this cylinder is being used
@ -1561,7 +1560,7 @@ std::vector<std::string> compare_samples(const struct dive *d, const struct plot
if (cylinder_volume.mliter && cylinder_volume.mliter != cyl->type.size.mliter) {
cylindersizes_are_identical = false;
} else {
cylinder_volume.mliter = cyl->type.size.mliter;
cylinder_volume = cyl->type.size;
}
} else {
sac_is_determinable = false;

View file

@ -260,7 +260,7 @@ std::vector<volume_t> get_gas_used(struct dive *dive)
end = cyl.end.mbar ? cyl.end : cyl.sample_end;
// TODO: Implement addition/subtraction on units.h types
if (end.mbar && start.mbar > end.mbar)
gases[idx].mliter = cyl.gas_volume(start).mliter - cyl.gas_volume(end).mliter;
gases[idx] = cyl.gas_volume(start) - cyl.gas_volume(end);
else
gases[idx].mliter = 0;
}
@ -291,8 +291,8 @@ std::pair<volume_t, volume_t> selected_dives_gas_parts()
for (auto &gas: get_gas_used(d.get())) {
if (gas.mliter) {
auto [o2, he] = get_gas_parts(d->get_cylinder(j)->gasmix, gas, O2_IN_AIR);
o2_tot.mliter += o2.mliter;
he_tot.mliter += he.mliter;
o2_tot += o2;
he_tot += he;
}
j++;
}

View file

@ -353,7 +353,7 @@ void uemis::parse_divelog_binary(std::string_view base64, struct dive *dive)
u_sample++;
}
if (sample)
dive->dcs[0].duration.seconds = sample->time.seconds - 1;
dive->dcs[0].duration = sample->time - duration_t { .seconds = 1 };
/* get data from the footer */
add_extra_data(dc, "FW Version",

View file

@ -1133,7 +1133,7 @@ bool QMLManager::checkDuration(struct dive *d, QString duration)
} else if (m6.hasMatch()) {
m = m6.captured(1).toInt();
}
d->dcs[0].duration.seconds = d->duration.seconds = h * 3600 + m * 60 + s;
d->dcs[0].duration = d->duration = duration_t { .seconds = h * 3600 + m * 60 + s };
if (is_dc_manually_added_dive(&d->dcs[0]))
d->dcs[0].samples.clear();
else

View file

@ -1334,7 +1334,7 @@ void ProfileWidget2::pictureOffsetChanged(dive *dIn, QString filenameIn, offset_
auto newPos = std::find_if(pictures.begin(), pictures.end(), [offset, &filename](const PictureEntry &e)
{ return std::tie(e.offset.seconds, e.filename) > std::tie(offset.seconds, filename); });
// Set new offset
oldPos->offset.seconds = offset.seconds;
oldPos->offset = offset;
updateThumbnailXPos(*oldPos);
// Move image from old to new position

View file

@ -472,9 +472,9 @@ static bool is_same_cylinder(cylinder_t *cyl_a, cylinder_t *cyl_b)
static void merge_cylinder_type(cylinder_type_t *src, cylinder_type_t *dst)
{
if (!dst->size.mliter)
dst->size.mliter = src->size.mliter;
dst->size = src->size;
if (!dst->workingpressure.mbar)
dst->workingpressure.mbar = src->workingpressure.mbar;
dst->workingpressure = src->workingpressure;
if (dst->description.empty() || dst->description == "---") {
dst->description = std::move(src->description);
}