mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
core: add CRTP base class to unit types
The goal here is to add general addition and scalar multiplication functions to the unit types. Thereto, we need a CRTP (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern) base class. However, this breaks compound initialization, so we have to use named initializers: weight_t { 2000 } -> weight_t { .grams = 2000 } The good thing is that this is exactly how these classes were supposed to be used: make the unit explicit! Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
696ba61eef
commit
12ca172a9e
26 changed files with 127 additions and 138 deletions
|
@ -790,10 +790,6 @@ void PasteDives::redo()
|
|||
// ***** ReplanDive *****
|
||||
ReplanDive::ReplanDive(dive *source) : d(current_dive),
|
||||
when(0),
|
||||
maxdepth({0}),
|
||||
meandepth({0}),
|
||||
surface_pressure({0}),
|
||||
duration({0}),
|
||||
salinity(0)
|
||||
{
|
||||
if (!d)
|
||||
|
@ -870,11 +866,7 @@ QString editProfileTypeToString(EditProfileType type, int count)
|
|||
}
|
||||
|
||||
EditProfile::EditProfile(const dive *source, int dcNr, EditProfileType type, int count) : d(current_dive),
|
||||
dcNr(dcNr),
|
||||
maxdepth({0}),
|
||||
meandepth({0}),
|
||||
dcmaxdepth({0}),
|
||||
duration({0})
|
||||
dcNr(dcNr)
|
||||
{
|
||||
const struct divecomputer *sdc = source->get_dc(dcNr);
|
||||
if (!sdc)
|
||||
|
|
|
@ -618,7 +618,7 @@ static void wlog_compl_parser(std::string &wl_mem, struct dive *dt_dive, int dco
|
|||
*/
|
||||
tmp = (int) two_bytes_to_int(runner[pos_weight + 1], runner[pos_weight]);
|
||||
if (tmp != 0x7fff) {
|
||||
weightsystem_t ws = { {tmp * 10}, translate("gettextFromC", "unknown"), false };
|
||||
weightsystem_t ws = { {.grams = tmp * 10}, translate("gettextFromC", "unknown"), false };
|
||||
dt_dive->weightsystems.push_back(std::move(ws));
|
||||
}
|
||||
|
||||
|
|
|
@ -2248,7 +2248,7 @@ duration_t dive::totaltime() const
|
|||
time = dc_time;
|
||||
}
|
||||
}
|
||||
return { time };
|
||||
return { .seconds = time };
|
||||
}
|
||||
|
||||
timestamp_t dive::endtime() const
|
||||
|
@ -2367,7 +2367,7 @@ bool dive::cache_is_valid() const
|
|||
pressure_t dive::get_surface_pressure() const
|
||||
{
|
||||
return surface_pressure.mbar > 0 ? surface_pressure
|
||||
: pressure_t { SURFACE_PRESSURE };
|
||||
: pressure_t { .mbar = SURFACE_PRESSURE };
|
||||
}
|
||||
|
||||
/* This returns the conversion factor that you need to multiply
|
||||
|
@ -2459,13 +2459,13 @@ int dive::mbar_to_depth(int mbar) const
|
|||
depth_t dive::gas_mod(struct gasmix mix, pressure_t po2_limit, int roundto) const
|
||||
{
|
||||
double depth = (double) mbar_to_depth(po2_limit.mbar * 1000 / get_o2(mix));
|
||||
return depth_t { (int)lrint(depth / roundto) * roundto };
|
||||
return depth_t { .mm = (int)lrint(depth / roundto) * roundto };
|
||||
}
|
||||
|
||||
/* Maximum narcotic depth rounded to multiples of roundto mm */
|
||||
depth_t dive::gas_mnd(struct gasmix mix, depth_t end, int roundto) const
|
||||
{
|
||||
pressure_t ppo2n2 { depth_to_mbar(end.mm) };
|
||||
pressure_t ppo2n2 { .mbar = depth_to_mbar(end.mm) };
|
||||
|
||||
int maxambient = prefs.o2narcotic ?
|
||||
(int)lrint(ppo2n2.mbar / (1 - get_he(mix) / 1000.0))
|
||||
|
@ -2475,7 +2475,7 @@ depth_t dive::gas_mnd(struct gasmix mix, depth_t end, int roundto) const
|
|||
:
|
||||
// Actually: Infinity
|
||||
1000000;
|
||||
return depth_t { (int)lrint(((double)mbar_to_depth(maxambient)) / roundto) * roundto };
|
||||
return depth_t { .mm = (int)lrint(((double)mbar_to_depth(maxambient)) / roundto) * roundto };
|
||||
}
|
||||
|
||||
std::string dive::get_country() const
|
||||
|
@ -2677,7 +2677,7 @@ temperature_t dive::dc_watertemp() const
|
|||
}
|
||||
if (!nr)
|
||||
return temperature_t();
|
||||
return temperature_t{ static_cast<uint32_t>((sum + nr / 2) / nr) };
|
||||
return temperature_t{ .mkelvin = static_cast<uint32_t>((sum + nr / 2) / nr) };
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2695,7 +2695,7 @@ temperature_t dive::dc_airtemp() const
|
|||
}
|
||||
if (!nr)
|
||||
return temperature_t();
|
||||
return temperature_t{ static_cast<uint32_t>((sum + nr / 2) / nr) };
|
||||
return temperature_t{ .mkelvin = static_cast<uint32_t>((sum + nr / 2) / nr) };
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2782,5 +2782,5 @@ weight_t dive::total_weight() const
|
|||
// TODO: implement addition for units.h types
|
||||
return std::accumulate(weightsystems.begin(), weightsystems.end(), weight_t(),
|
||||
[] (weight_t w, const weightsystem_t &ws)
|
||||
{ return weight_t{ w.grams + ws.weight.grams }; });
|
||||
{ return weight_t{ .grams = w.grams + ws.weight.grams }; });
|
||||
}
|
||||
|
|
|
@ -112,9 +112,9 @@ void set_tank_info_data(std::vector<tank_info> &table, const std::string &name,
|
|||
std::pair<volume_t, pressure_t> extract_tank_info(const struct tank_info &info)
|
||||
{
|
||||
pressure_t working_pressure {
|
||||
static_cast<int32_t>(info.bar != 0 ? info.bar * 1000 : psi_to_mbar(info.psi))
|
||||
.mbar = static_cast<int32_t>(info.bar != 0 ? info.bar * 1000 : psi_to_mbar(info.psi))
|
||||
};
|
||||
volume_t size { 0 };
|
||||
volume_t size;
|
||||
if (info.ml != 0)
|
||||
size.mliter = info.ml;
|
||||
else if (working_pressure.mbar != 0)
|
||||
|
@ -128,7 +128,7 @@ std::pair<volume_t, pressure_t> get_tank_info_data(const std::vector<tank_info>
|
|||
auto it = std::find_if(table.begin(), table.end(), [&name](const tank_info &info)
|
||||
{ return info.name == name; });
|
||||
return it != table.end() ? extract_tank_info(*it)
|
||||
: std::make_pair(volume_t{0}, pressure_t{0});
|
||||
: std::make_pair(volume_t(), pressure_t());
|
||||
}
|
||||
|
||||
void add_cylinder_description(const cylinder_type_t &type)
|
||||
|
@ -182,7 +182,7 @@ volume_t cylinder_t::gas_volume(pressure_t p) const
|
|||
{
|
||||
double bar = p.mbar / 1000.0;
|
||||
double z_factor = gas_compressibility_factor(gasmix, bar);
|
||||
return volume_t { static_cast<int>(lrint(type.size.mliter * bar_to_atm(bar) / z_factor)) };
|
||||
return volume_t { .mliter = static_cast<int>(lrint(type.size.mliter * bar_to_atm(bar) / z_factor)) };
|
||||
}
|
||||
|
||||
int find_best_gasmix_match(struct gasmix mix, const struct cylinder_table &cylinders)
|
||||
|
|
|
@ -16,8 +16,8 @@ struct gasmix {
|
|||
fraction_t he;
|
||||
std::string name() const;
|
||||
};
|
||||
static const struct gasmix gasmix_invalid = { { -1 }, { -1 } };
|
||||
static const struct gasmix gasmix_air = { { 0 }, { 0 } };
|
||||
static const struct gasmix gasmix_invalid = { { .permille = -1 }, { .permille = -1 } };
|
||||
static const struct gasmix gasmix_air = { { .permille = 0 }, { .permille = 0 } };
|
||||
|
||||
enum gastype {
|
||||
GASTYPE_AIR,
|
||||
|
|
|
@ -217,7 +217,7 @@ Thumbnailer::Thumbnail Thumbnailer::getVideoThumbnailFromStream(QDataStream &str
|
|||
// is not repeated ad-nauseum for broken images.
|
||||
if (numPics == 0 && prefs.extract_video_thumbnails) {
|
||||
QMetaObject::invokeMethod(VideoFrameExtractor::instance(), "extract", Qt::AutoConnection,
|
||||
Q_ARG(QString, filename), Q_ARG(QString, filename), Q_ARG(duration_t, duration_t{(int32_t)duration}));
|
||||
Q_ARG(QString, filename), Q_ARG(QString, filename), Q_ARG(duration_t, duration_t{ .seconds = (int32_t)duration}));
|
||||
}
|
||||
|
||||
// Currently, we support only one picture
|
||||
|
@ -231,7 +231,7 @@ Thumbnailer::Thumbnail Thumbnailer::getVideoThumbnailFromStream(QDataStream &str
|
|||
res = videoImage; // No picture -> show dummy-icon
|
||||
else
|
||||
markVideoThumbnail(res); // We got an image -> place our video marker on top of it
|
||||
return { res, MEDIATYPE_VIDEO, { (int32_t)duration } };
|
||||
return { res, MEDIATYPE_VIDEO, { .seconds = (int32_t)duration } };
|
||||
}
|
||||
|
||||
// Fetch a thumbnail from cache.
|
||||
|
|
|
@ -309,7 +309,7 @@ static int divinglog_dive(void *param, int, char **data, char **)
|
|||
state->cur_dive->watertemp.mkelvin = C_to_mkelvin(atol(data[9]));
|
||||
|
||||
if (data[10]) {
|
||||
weightsystem_t ws = { { atoi(data[10]) * 1000 }, translate("gettextFromC", "unknown"), false };
|
||||
weightsystem_t ws = { { .grams = atoi(data[10]) * 1000 }, translate("gettextFromC", "unknown"), false };
|
||||
state->cur_dive->weightsystems.push_back(std::move(ws));
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,7 @@ static dc_status_t parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_
|
|||
}
|
||||
}
|
||||
bool no_volume = true;
|
||||
struct gasmix bottom_gas = { {1000}, {0} }; /* Default to pure O2, or air if there are no mixes defined */
|
||||
struct gasmix bottom_gas = { { .permille = 1000}, {} }; /* Default to pure O2, or air if there are no mixes defined */
|
||||
if (ngases == 0) {
|
||||
bottom_gas = gasmix_air;
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ preferences::preferences() :
|
|||
ascratestops(9000 / 60),
|
||||
ascrate50(9000 / 60),
|
||||
ascrate75(9000 / 60),
|
||||
bestmixend({ 30000 }),
|
||||
bestmixend({ .mm = 30'000 }),
|
||||
bottompo2(1400),
|
||||
bottomsac(20000),
|
||||
decopo2(1600),
|
||||
|
|
|
@ -1504,8 +1504,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){ last_pressures[cylinder_index] }).mliter -
|
||||
cyl->gas_volume((pressure_t){ next_pressure }).mliter;
|
||||
volumes_used[cylinder_index] += cyl->gas_volume((pressure_t){ .mbar = last_pressures[cylinder_index] }).mliter -
|
||||
cyl->gas_volume((pressure_t){ .mbar = next_pressure }).mliter;
|
||||
}
|
||||
|
||||
// check if the gas in this cylinder is being used
|
||||
|
|
|
@ -786,33 +786,6 @@ int parseTemperatureToMkelvin(const QString &text)
|
|||
return mkelvin;
|
||||
}
|
||||
|
||||
int parseWeightToGrams(const QString &text)
|
||||
{
|
||||
int grams;
|
||||
QString numOnly = text;
|
||||
numOnly.replace(",", ".").remove(QRegularExpression("[^0-9.]"));
|
||||
if (numOnly.isEmpty())
|
||||
return 0;
|
||||
double number = numOnly.toDouble();
|
||||
if (text.contains(gettextFromC::tr("kg"), Qt::CaseInsensitive)) {
|
||||
grams = lrint(number * 1000);
|
||||
} else if (text.contains(gettextFromC::tr("lbs"), Qt::CaseInsensitive)) {
|
||||
grams = lbs_to_grams(number);
|
||||
} else {
|
||||
switch (prefs.units.weight) {
|
||||
case units::KG:
|
||||
grams = lrint(number * 1000);
|
||||
break;
|
||||
case units::LBS:
|
||||
grams = lbs_to_grams(number);
|
||||
break;
|
||||
default:
|
||||
grams = 0;
|
||||
}
|
||||
}
|
||||
return grams;
|
||||
}
|
||||
|
||||
int parsePressureToMbar(const QString &text)
|
||||
{
|
||||
int mbar;
|
||||
|
|
|
@ -69,7 +69,6 @@ timestamp_t dateTimeToTimestamp(const QDateTime &t);
|
|||
int parseDurationToSeconds(const QString &text);
|
||||
int parseLengthToMm(const QString &text);
|
||||
int parseTemperatureToMkelvin(const QString &text);
|
||||
int parseWeightToGrams(const QString &text);
|
||||
int parsePressureToMbar(const QString &text);
|
||||
int parseGasMixO2(const QString &text);
|
||||
int parseGasMixHE(const QString &text);
|
||||
|
|
|
@ -12,7 +12,7 @@ struct sample // BASE TYPE BYTES UNITS RANGE
|
|||
{ // --------- ----- ----- ----- -----------
|
||||
duration_t time; // int32_t 4 seconds (0-34 yrs) elapsed dive time up to this sample
|
||||
duration_t stoptime; // int32_t 4 seconds (0-34 yrs) time duration of next deco stop
|
||||
duration_t ndl = { -1 }; // int32_t 4 seconds (-1 no val, 0-34 yrs) time duration before no-deco limit
|
||||
duration_t ndl = { .seconds = -1 };// int32_t 4 seconds (-1 no val, 0-34 yrs) time duration before no-deco limit
|
||||
duration_t tts; // int32_t 4 seconds (0-34 yrs) time duration to reach the surface
|
||||
duration_t rbt; // int32_t 4 seconds (0-34 yrs) remaining bottom time
|
||||
depth_t depth; // int32_t 4 mm (0-2000 km) dive depth of this sample
|
||||
|
@ -21,7 +21,7 @@ struct sample // BASE TYPE BYTES UNITS RANGE
|
|||
pressure_t pressure[MAX_SENSORS]; // int32_t 2x4 mbar (0-2 Mbar) cylinder pressures (main and CCR o2)
|
||||
o2pressure_t setpoint; // uint16_t 2 mbar (0-65 bar) O2 partial pressure (will be setpoint)
|
||||
o2pressure_t o2sensor[MAX_O2_SENSORS];// uint16_t 6x2 mbar (0-65 bar) Up to 6 PO2 sensor values (rebreather)
|
||||
bearing_t bearing = { -1 }; // int16_t 2 degrees (-1 no val, 0-360 deg) compass bearing
|
||||
bearing_t bearing = { .degrees = -1 };// int16_t 2 degrees (-1 no val, 0-360 deg) compass bearing
|
||||
int16_t sensor[MAX_SENSORS] = {}; // int16_t 2x2 sensorID (0-16k) ID of cylinder pressure sensor
|
||||
uint16_t cns = 0; // uint16_t 2 % (0-64k %) cns% accumulated
|
||||
uint8_t heartbeat = 0; // uint8_t 1 beats/m (0-255) heart rate measurement
|
||||
|
|
|
@ -275,9 +275,9 @@ static std::pair<volume_t, volume_t> get_gas_parts(struct gasmix mix, volume_t v
|
|||
if (gasmix_is_air(mix))
|
||||
return { volume_t() , volume_t() };
|
||||
|
||||
volume_t air = { (int)lrint(((double)vol.mliter * get_n2(mix)) / (1000 - o2_in_topup)) };
|
||||
volume_t he = { (int)lrint(((double)vol.mliter * get_he(mix)) / 1000.0) };
|
||||
volume_t o2 = { vol.mliter - he.mliter - air.mliter };
|
||||
volume_t air { .mliter = (int)lrint(((double)vol.mliter * get_n2(mix)) / (1000 - o2_in_topup)) };
|
||||
volume_t he { .mliter = (int)lrint(((double)vol.mliter * get_he(mix)) / 1000.0) };
|
||||
volume_t o2 { .mliter = vol.mliter - he.mliter - air.mliter };
|
||||
return std::make_pair(o2, he);
|
||||
}
|
||||
|
||||
|
|
34
core/units.h
34
core/units.h
|
@ -67,62 +67,66 @@
|
|||
*/
|
||||
using timestamp_t = int64_t;
|
||||
|
||||
struct duration_t
|
||||
template <typename T>
|
||||
struct unit_base {
|
||||
};
|
||||
|
||||
struct duration_t : public unit_base<duration_t>
|
||||
{
|
||||
int32_t seconds = 0; // durations up to 34 yrs
|
||||
};
|
||||
|
||||
struct offset_t
|
||||
struct offset_t : public unit_base<offset_t>
|
||||
{
|
||||
int32_t seconds = 0; // offsets up to +/- 34 yrs
|
||||
};
|
||||
|
||||
struct depth_t // depth to 2000 km
|
||||
struct depth_t : public unit_base<depth_t> // depth to 2000 km
|
||||
{
|
||||
int32_t mm = 0;
|
||||
};
|
||||
|
||||
struct pressure_t
|
||||
struct pressure_t : public unit_base<pressure_t>
|
||||
{
|
||||
int32_t mbar = 0; // pressure up to 2000 bar
|
||||
};
|
||||
|
||||
struct o2pressure_t
|
||||
struct o2pressure_t : public unit_base<o2pressure_t>
|
||||
{
|
||||
uint16_t mbar = 0;
|
||||
};
|
||||
|
||||
struct bearing_t
|
||||
struct bearing_t : public unit_base<bearing_t>
|
||||
{
|
||||
int16_t degrees = 0;
|
||||
};
|
||||
|
||||
struct temperature_t
|
||||
struct temperature_t : public unit_base<temperature_t>
|
||||
{
|
||||
uint32_t mkelvin = 0; // up to 4 MK (temperatures in K are always positive)
|
||||
};
|
||||
|
||||
struct temperature_sum_t
|
||||
struct temperature_sum_t : public unit_base<temperature_sum_t>
|
||||
{
|
||||
uint64_t mkelvin = 0; // up to 18446744073 MK (temperatures in K are always positive)
|
||||
};
|
||||
|
||||
struct volume_t
|
||||
struct volume_t : public unit_base<volume_t>
|
||||
{
|
||||
int mliter = 0;
|
||||
};
|
||||
|
||||
struct fraction_t
|
||||
struct fraction_t : public unit_base<fraction_t>
|
||||
{
|
||||
int permille = 0;
|
||||
};
|
||||
|
||||
struct weight_t
|
||||
struct weight_t : public unit_base<weight_t>
|
||||
{
|
||||
int grams = 0;
|
||||
};
|
||||
|
||||
struct degrees_t
|
||||
struct degrees_t : public unit_base<degrees_t>
|
||||
{
|
||||
int udeg = 0;
|
||||
};
|
||||
|
@ -152,8 +156,8 @@ static inline bool operator!=(const location_t &a, const location_t &b)
|
|||
static inline location_t create_location(double lat, double lon)
|
||||
{
|
||||
location_t location = {
|
||||
{ (int) lrint(lat * 1000000) },
|
||||
{ (int) lrint(lon * 1000000) }
|
||||
{ .udeg = (int) lrint(lat * 1000000) },
|
||||
{ .udeg = (int) lrint(lon * 1000000) }
|
||||
};
|
||||
return location;
|
||||
}
|
||||
|
@ -255,7 +259,7 @@ static inline double mbar_to_atm(int mbar)
|
|||
|
||||
static inline double mbar_to_PSI(int mbar)
|
||||
{
|
||||
pressure_t p = { mbar };
|
||||
pressure_t p = { .mbar = mbar };
|
||||
return to_PSI(p);
|
||||
}
|
||||
|
||||
|
|
|
@ -596,7 +596,7 @@ void DiveListView::mergeDives()
|
|||
void DiveListView::splitDives()
|
||||
{
|
||||
for (struct dive *d: getDiveSelection())
|
||||
Command::splitDives(d, duration_t{-1});
|
||||
Command::splitDives(d, duration_t{ .seconds = -1});
|
||||
}
|
||||
|
||||
void DiveListView::addDivesToTrip()
|
||||
|
|
|
@ -62,7 +62,8 @@ RenumberDialog::RenumberDialog(bool selectedOnlyIn, QWidget *parent) : QDialog(p
|
|||
void SetpointDialog::buttonClicked(QAbstractButton *button)
|
||||
{
|
||||
if (ui.buttonBox->buttonRole(button) == QDialogButtonBox::AcceptRole)
|
||||
Command::addEventSetpointChange(d, dcNr, time, pressure_t { (int)(1000.0 * ui.spinbox->value()) });
|
||||
Command::addEventSetpointChange(d, dcNr, time,
|
||||
pressure_t { .mbar = (int)(1000.0 * ui.spinbox->value()) });
|
||||
}
|
||||
|
||||
SetpointDialog::SetpointDialog(struct dive *dIn, int dcNrIn, int seconds) : QDialog(MainWindow::instance()),
|
||||
|
|
|
@ -1162,6 +1162,29 @@ bool QMLManager::checkDepth(dive *d, QString depth)
|
|||
return false;
|
||||
}
|
||||
|
||||
static weight_t parseWeight(const QString &text)
|
||||
{
|
||||
QString numOnly = text;
|
||||
numOnly.replace(",", ".").remove(QRegularExpression("[^0-9.]"));
|
||||
if (numOnly.isEmpty())
|
||||
return {};
|
||||
double number = numOnly.toDouble();
|
||||
if (text.contains(gettextFromC::tr("kg"), Qt::CaseInsensitive)) {
|
||||
return { .grams = static_cast<int>(lrint(number * 1000)) };
|
||||
} else if (text.contains(gettextFromC::tr("lbs"), Qt::CaseInsensitive)) {
|
||||
return { .grams = lbs_to_grams(number) };
|
||||
} else {
|
||||
switch (prefs.units.weight) {
|
||||
case units::KG:
|
||||
return { .grams = static_cast<int>(lrint(number * 1000)) };
|
||||
case units::LBS:
|
||||
return { .grams = lbs_to_grams(number) };
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update the dive and return the notes field, stripped of the HTML junk
|
||||
void QMLManager::commitChanges(QString diveId, QString number, QString date, QString location, QString gps, QString duration, QString depth,
|
||||
QString airtemp, QString watertemp, QString suit, QString buddy, QString diveGuide, QString tags, QString weight, QString notes,
|
||||
|
@ -1228,10 +1251,10 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt
|
|||
// not sure what we'd do if there was more than one weight system
|
||||
// defined - for now just ignore that case
|
||||
if (d->weightsystems.size() == 0) {
|
||||
weightsystem_t ws = { { parseWeightToGrams(weight) } , tr("weight").toStdString(), false };
|
||||
weightsystem_t ws = { parseWeight(weight), tr("weight").toStdString(), false };
|
||||
d->weightsystems.add(0, std::move(ws));
|
||||
} else if (d->weightsystems.size() == 1) {
|
||||
d->weightsystems[0].weight.grams = parseWeightToGrams(weight);
|
||||
d->weightsystems[0].weight = parseWeight(weight);
|
||||
}
|
||||
}
|
||||
// start and end pressures
|
||||
|
|
|
@ -551,7 +551,7 @@ void ProfileScene::plotDive(const struct dive *dIn, int dcIn, DivePlannerPointsM
|
|||
// while all other items are up there on the constructor.
|
||||
qDeleteAll(eventItems);
|
||||
eventItems.clear();
|
||||
struct gasmix lastgasmix = d->get_gasmix_at_time(*currentdc, duration_t{1});
|
||||
struct gasmix lastgasmix = d->get_gasmix_at_time(*currentdc, duration_t{ .seconds = 1 });
|
||||
|
||||
for (auto [idx, event]: enumerated_range(currentdc->events)) {
|
||||
// if print mode is selected only draw headings, SP change, gas events or bookmark event
|
||||
|
|
|
@ -753,7 +753,7 @@ void ProfileWidget2::splitDive(int seconds)
|
|||
{
|
||||
if (!d)
|
||||
return;
|
||||
Command::splitDives(mutable_dive(), duration_t{ seconds });
|
||||
Command::splitDives(mutable_dive(), duration_t{ .seconds = seconds });
|
||||
}
|
||||
|
||||
void ProfileWidget2::addGasSwitch(int tank, int seconds)
|
||||
|
@ -1103,7 +1103,6 @@ void ProfileWidget2::updateThumbnail(QString filenameIn, QImage thumbnail, durat
|
|||
|
||||
// Create a PictureEntry object and add its thumbnail to the scene if profile pictures are shown.
|
||||
ProfileWidget2::PictureEntry::PictureEntry(offset_t offsetIn, const std::string &filenameIn, ProfileWidget2 *profile, bool synchronous) : offset(offsetIn),
|
||||
duration(duration_t {0}),
|
||||
filename(filenameIn),
|
||||
thumbnail(new DivePictureItem)
|
||||
{
|
||||
|
@ -1289,7 +1288,7 @@ void ProfileWidget2::dropEvent(QDropEvent *event)
|
|||
QString filename;
|
||||
dataStream >> filename;
|
||||
QPointF mappedPos = mapToScene(event->pos());
|
||||
offset_t offset { (int32_t)lrint(profileScene->timeAxis->valueAt(mappedPos)) };
|
||||
offset_t offset { .seconds = (int32_t)lrint(profileScene->timeAxis->valueAt(mappedPos)) };
|
||||
Command::setPictureOffset(mutable_dive(), filename, offset);
|
||||
|
||||
if (event->source() == this) {
|
||||
|
|
|
@ -86,7 +86,7 @@ static QVariant gas_usage_tooltip(const cylinder_t *cyl)
|
|||
volume_t start = cyl->gas_volume(startp);
|
||||
volume_t end = cyl->gas_volume(endp);
|
||||
// TOOO: implement comparison and subtraction on units.h types.
|
||||
volume_t used = (end.mliter && start.mliter > end.mliter) ? volume_t { start.mliter - end.mliter } : volume_t();
|
||||
volume_t used = (end.mliter && start.mliter > end.mliter) ? volume_t { .mliter = start.mliter - end.mliter } : volume_t();
|
||||
|
||||
if (!used.mliter)
|
||||
return gas_wp_tooltip(cyl);
|
||||
|
|
|
@ -303,7 +303,6 @@ bool GPSLocationInformationModel::filterAcceptsRow(int sourceRow, const QModelIn
|
|||
|
||||
GPSLocationInformationModel::GPSLocationInformationModel(QObject *parent) : QSortFilterProxyModel(parent),
|
||||
ignoreDs(nullptr),
|
||||
location({{0},{0}}),
|
||||
distance(0)
|
||||
{
|
||||
setSourceModel(LocationInformationModel::instance());
|
||||
|
|
|
@ -15,8 +15,7 @@
|
|||
|
||||
PictureEntry::PictureEntry(dive *dIn, const picture &p) : d(dIn),
|
||||
filename(p.filename),
|
||||
offsetSeconds(p.offset.seconds),
|
||||
length({ 0 })
|
||||
offsetSeconds(p.offset.seconds)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -1001,7 +1001,7 @@ void smartrak_import(const char *file, struct divelog *log)
|
|||
|
||||
/* No DC related data */
|
||||
smtkdive->visibility = strtod((char *)col[coln(VISIBILITY)]->bind_ptr, NULL) > 25 ? 5 : lrint(strtod((char *)col[13]->bind_ptr, NULL) / 5);
|
||||
weightsystem_t ws = { {(int)lrint(strtod((char *)col[coln(WEIGHT)]->bind_ptr, NULL) * 1000)}, std::string(), false };
|
||||
weightsystem_t ws = { { .grams = (int)lrint(strtod((char *)col[coln(WEIGHT)]->bind_ptr, NULL) * 1000)}, std::string(), false };
|
||||
smtkdive->weightsystems.push_back(std::move(ws));
|
||||
smtkdive->suit = get(suit_list, atoi((char *)col[coln(SUITIDX)]->bind_ptr) - 1);
|
||||
smtk_build_location(mdb_clon, (char *)col[coln(SITEIDX)]->bind_ptr, &smtkdive->dive_site, log);
|
||||
|
|
|
@ -47,10 +47,10 @@ diveplan setupPlan()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix bottomgas = {{150}, {450}};
|
||||
struct gasmix ean36 = {{360}, {0}};
|
||||
struct gasmix oxygen = {{1000}, {0}};
|
||||
pressure_t po2 = {1600};
|
||||
struct gasmix bottomgas = {{.permille = 150}, {.permille = 450}};
|
||||
struct gasmix ean36 = {{.permille = 360}, {}};
|
||||
struct gasmix oxygen = {{.permille = 1000}, {}};
|
||||
pressure_t po2 = {.mbar = 1600};
|
||||
// Note: we add the highest-index cylinder first, because
|
||||
// pointers to cylinders are not stable when reallocating.
|
||||
// For testing OK - don't do this in actual code!
|
||||
|
@ -82,10 +82,10 @@ diveplan setupPlanVpmb45m30mTx()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix bottomgas = {{210}, {350}};
|
||||
struct gasmix ean50 = {{500}, {0}};
|
||||
struct gasmix oxygen = {{1000}, {0}};
|
||||
pressure_t po2 = {1600};
|
||||
struct gasmix bottomgas = {{.permille = 210}, {.permille = 350}};
|
||||
struct gasmix ean50 = {{.permille = 500}, {}};
|
||||
struct gasmix oxygen = {{.permille = 1000}, {}};
|
||||
pressure_t po2 = {.mbar = 1600};
|
||||
// Note: we add the highest-index cylinder first, because
|
||||
// pointers to cylinders are not stable when reallocating.
|
||||
// For testing OK - don't do this in actual code!
|
||||
|
@ -117,10 +117,10 @@ diveplan setupPlanVpmb60m10mTx()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix bottomgas = {{180}, {450}};
|
||||
struct gasmix tx50_15 = {{500}, {150}};
|
||||
struct gasmix oxygen = {{1000}, {0}};
|
||||
pressure_t po2 = {1600};
|
||||
struct gasmix bottomgas = {{.permille = 180}, {.permille = 450}};
|
||||
struct gasmix tx50_15 = {{.permille = 500}, {.permille = 150}};
|
||||
struct gasmix oxygen = {{.permille = 1000}, {}};
|
||||
pressure_t po2 = {.mbar = 1600};
|
||||
// Note: we add the highest-index cylinder first, because
|
||||
// pointers to cylinders are not stable when reallocating.
|
||||
// For testing OK - don't do this in actual code!
|
||||
|
@ -150,7 +150,7 @@ diveplan setupPlanVpmb60m30minAir()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix bottomgas = {{210}, {0}};
|
||||
struct gasmix bottomgas = {{.permille = 210}, {}};
|
||||
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
|
||||
cyl0->gasmix = bottomgas;
|
||||
cyl0->type.size.mliter = 100000;
|
||||
|
@ -172,9 +172,9 @@ diveplan setupPlanVpmb60m30minEan50()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix bottomgas = {{210}, {0}};
|
||||
struct gasmix ean50 = {{500}, {0}};
|
||||
pressure_t po2 = {1600};
|
||||
struct gasmix bottomgas = {{.permille = 210}, {}};
|
||||
struct gasmix ean50 = {{.permille = 500}, {}};
|
||||
pressure_t po2 = {.mbar = 1600};
|
||||
// Note: we add the highest-index cylinder first, because
|
||||
// pointers to cylinders are not stable when reallocating.
|
||||
// For testing OK - don't do this in actual code!
|
||||
|
@ -202,9 +202,9 @@ diveplan setupPlanVpmb60m30minTx()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix bottomgas = {{180}, {450}};
|
||||
struct gasmix ean50 = {{500}, {0}};
|
||||
pressure_t po2 = {1600};
|
||||
struct gasmix bottomgas = {{.permille = 180}, {.permille = 450}};
|
||||
struct gasmix ean50 = {{.permille = 500}, {}};
|
||||
pressure_t po2 = {.mbar = 1600};
|
||||
// Note: we add the highest-index cylinder first, because
|
||||
// pointers to cylinders are not stable when reallocating.
|
||||
// For testing OK - don't do this in actual code!
|
||||
|
@ -232,7 +232,7 @@ diveplan setupPlanVpmbMultiLevelAir()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix bottomgas = {{210}, {0}};
|
||||
struct gasmix bottomgas = {{.permille = 210}, {}};
|
||||
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
|
||||
cyl0->gasmix = bottomgas;
|
||||
cyl0->type.size.mliter = 200000;
|
||||
|
@ -256,10 +256,10 @@ diveplan setupPlanVpmb100m60min()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix bottomgas = {{180}, {450}};
|
||||
struct gasmix ean50 = {{500}, {0}};
|
||||
struct gasmix oxygen = {{1000}, {0}};
|
||||
pressure_t po2 = {1600};
|
||||
struct gasmix bottomgas = {{.permille = 180}, {.permille = 450}};
|
||||
struct gasmix ean50 = {{.permille = 500}, {}};
|
||||
struct gasmix oxygen = {{.permille = 1000}, {}};
|
||||
pressure_t po2 = {.mbar = 1600};
|
||||
// Note: we add the highest-index cylinder first, because
|
||||
// pointers to cylinders are not stable when reallocating.
|
||||
// For testing OK - don't do this in actual code!
|
||||
|
@ -290,10 +290,10 @@ diveplan setupPlanVpmb100m10min()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix bottomgas = {{180}, {450}};
|
||||
struct gasmix ean50 = {{500}, {0}};
|
||||
struct gasmix oxygen = {{1000}, {0}};
|
||||
pressure_t po2 = {1600};
|
||||
struct gasmix bottomgas = {{.permille = 180}, {.permille = 450}};
|
||||
struct gasmix ean50 = {{.permille = 500}, {}};
|
||||
struct gasmix oxygen = {{.permille = 1000}, {}};
|
||||
pressure_t po2 = {.mbar = 1600};
|
||||
// Note: we add the highest-index cylinder first, because
|
||||
// pointers to cylinders are not stable when reallocating.
|
||||
// For testing OK - don't do this in actual code!
|
||||
|
@ -324,7 +324,7 @@ diveplan setupPlanVpmb30m20min()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix bottomgas = {{210}, {0}};
|
||||
struct gasmix bottomgas = {{.permille = 210}, {}};
|
||||
cylinder_t *cyl0 = dive.get_or_create_cylinder(0);
|
||||
cyl0->gasmix = bottomgas;
|
||||
cyl0->type.size.mliter = 36000;
|
||||
|
@ -346,11 +346,11 @@ diveplan setupPlanVpmb100mTo70m30min()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix bottomgas = {{120}, {650}};
|
||||
struct gasmix tx21_35 = {{210}, {350}};
|
||||
struct gasmix ean50 = {{500}, {0}};
|
||||
struct gasmix oxygen = {{1000}, {0}};
|
||||
pressure_t po2 = {1600};
|
||||
struct gasmix bottomgas = {{.permille = 120}, {.permille = 650}};
|
||||
struct gasmix tx21_35 = {{.permille = 210}, {.permille = 350}};
|
||||
struct gasmix ean50 = {{.permille = 500}, {}};
|
||||
struct gasmix oxygen = {{.permille = 1000}, {}};
|
||||
pressure_t po2 = {.mbar = 1600};
|
||||
// Note: we add the highest-index cylinder first, because
|
||||
// pointers to cylinders are not stable when reallocating.
|
||||
// For testing OK - don't do this in actual code!
|
||||
|
@ -388,8 +388,8 @@ diveplan setupPlanSeveralGases()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
struct gasmix ean36 = {{360}, {0}};
|
||||
struct gasmix tx11_50 = {{110}, {500}};
|
||||
struct gasmix ean36 = {{.permille = 360}, {}};
|
||||
struct gasmix tx11_50 = {{.permille = 110}, {.permille = 500}};
|
||||
|
||||
// Note: we add the highest-index cylinder first, because
|
||||
// pointers to cylinders are not stable when reallocating.
|
||||
|
@ -420,10 +420,10 @@ diveplan setupPlanCcr()
|
|||
dp.bottomsac = prefs.bottomsac;
|
||||
dp.decosac = prefs.decosac;
|
||||
|
||||
pressure_t po2 = {1600};
|
||||
struct gasmix diluent = {{200}, {210}};
|
||||
struct gasmix ean53 = {{530}, {0}};
|
||||
struct gasmix tx19_33 = {{190}, {330}};
|
||||
pressure_t po2 = {.mbar = 1600};
|
||||
struct gasmix diluent = {{.permille = 200}, {.permille = 210}};
|
||||
struct gasmix ean53 = {{.permille = 530}, {}};
|
||||
struct gasmix tx19_33 = {{.permille = 190}, {.permille = 330}};
|
||||
// Note: we add the highest-index cylinder first, because
|
||||
// pointers to cylinders are not stable when reallocating.
|
||||
// For testing OK - don't do this in actual code!
|
||||
|
@ -754,7 +754,7 @@ void TestPlan::testMultipleGases()
|
|||
save_dive(stdout, dive, false);
|
||||
#endif
|
||||
|
||||
gasmix gas = dive.get_gasmix_at_time(dive.dcs[0], {20 * 60 + 1});
|
||||
gasmix gas = dive.get_gasmix_at_time(dive.dcs[0], {.seconds = 20 * 60 + 1});
|
||||
QCOMPARE(get_o2(gas), 110);
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 2480u, 2480u));
|
||||
}
|
||||
|
@ -934,17 +934,17 @@ void TestPlan::testCcrBailoutGasSelection()
|
|||
#endif
|
||||
|
||||
// check diluent used
|
||||
cylinder_t *cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { 20 * 60 - 1 }));
|
||||
cylinder_t *cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { .seconds = 20 * 60 - 1 }));
|
||||
QCOMPARE(cylinder->cylinder_use, DILUENT);
|
||||
QCOMPARE(get_o2(cylinder->gasmix), 200);
|
||||
|
||||
// check deep bailout used
|
||||
cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { 20 * 60 + 1 }));
|
||||
cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { .seconds = 20 * 60 + 1 }));
|
||||
QCOMPARE(cylinder->cylinder_use, OC_GAS);
|
||||
QCOMPARE(get_o2(cylinder->gasmix), 190);
|
||||
|
||||
// check shallow bailout used
|
||||
cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { 30 * 60 }));
|
||||
cylinder = dive.get_cylinder(get_cylinderid_at_time(&dive, &dive.dcs[0], { .seconds = 30 * 60 }));
|
||||
QCOMPARE(cylinder->cylinder_use, OC_GAS);
|
||||
QCOMPARE(get_o2(cylinder->gasmix), 530);
|
||||
|
||||
|
|
|
@ -11,14 +11,14 @@ void TestUnitConversion::testUnitConversions()
|
|||
QCOMPARE(nearly_equal(cuft_to_l(1), 28.316847), true);
|
||||
QCOMPARE(nearly_equal(mm_to_feet(1000), 3.280840), true);
|
||||
QCOMPARE(feet_to_mm(1), 305L);
|
||||
QCOMPARE(to_feet((depth_t){1000}), 3);
|
||||
QCOMPARE(to_feet(depth_t{ .mm = 1'000}), 3);
|
||||
QCOMPARE(nearly_equal(mkelvin_to_C(647000), 373.85), true);
|
||||
QCOMPARE(nearly_equal(mkelvin_to_F(647000), 704.93), true);
|
||||
QCOMPARE(F_to_mkelvin(704.93), 647000UL);
|
||||
QCOMPARE(C_to_mkelvin(373.85), 647000UL);
|
||||
QCOMPARE(nearly_equal(psi_to_bar(14.6959488), 1.01325), true);
|
||||
QCOMPARE(psi_to_mbar(14.6959488), 1013L);
|
||||
QCOMPARE(nearly_equal(to_PSI((pressure_t){1013}), 14.6923228594), true);
|
||||
QCOMPARE(nearly_equal(to_PSI(pressure_t{ .mbar = 1013}), 14.6923228594), true);
|
||||
QCOMPARE(nearly_equal(bar_to_atm(1.013), 1.0), true);
|
||||
QCOMPARE(nearly_equal(mbar_to_atm(1013), 1.0), true);
|
||||
QCOMPARE(nearly_equal(mbar_to_PSI(1013), 14.6923228594), true);
|
||||
|
|
Loading…
Add table
Reference in a new issue