mirror of
https://github.com/subsurface/subsurface.git
synced 2024-11-27 20:58:47 +00:00
core: turn divecomputer list into std::vector<>
Since struct divecomputer is now fully C++ (i.e. cleans up after itself), we can simply turn the list of divecomputers into an std::vector<>. This makes the code quite a bit simpler, because the first divecomputer was actually a subobject. Yes, this makes the common case of a single divecomputer a little bit less efficient, but it really shouldn't matter. If it does, we can still write a special std::vector<>- like container that keeps the first element inline. This change makes pointers-to-divecomputers not stable. So always access the divecomputer via its index. As far as I can tell, most of the code already does this. Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This commit is contained in:
parent
e237f29fb2
commit
284582d2e8
54 changed files with 738 additions and 893 deletions
|
@ -10,7 +10,7 @@ ColumnLimit: 0
|
|||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 8
|
||||
ContinuationIndentWidth: 8
|
||||
ForEachMacros: [ 'for_each_dc', 'for_each_relevant_dc', 'for_each_dive', 'for_each_line' ]
|
||||
ForEachMacros: [ 'for_each_dive', 'for_each_line' ]
|
||||
IndentFunctionDeclarationAfterType: false #personal taste, good for long methods
|
||||
IndentWidth: 8
|
||||
MaxEmptyLinesToKeep: 2
|
||||
|
|
|
@ -179,7 +179,7 @@ void export_TeX(const char *filename, bool selected_only, bool plain, ExportCall
|
|||
put_format(&buf, "\\def\\%ssitename{%s}\n", ssrf, site ? site->name.c_str() : "");
|
||||
site ? put_format(&buf, "\\def\\%sgpslat{%f}\n", ssrf, site->location.lat.udeg / 1000000.0) : put_format(&buf, "\\def\\%sgpslat{}\n", ssrf);
|
||||
site ? put_format(&buf, "\\def\\%sgpslon{%f}\n", ssrf, site->location.lon.udeg / 1000000.0) : put_format(&buf, "\\def\\gpslon{}\n");
|
||||
put_format(&buf, "\\def\\%scomputer{%s}\n", ssrf, dive->dc.model.c_str());
|
||||
put_format(&buf, "\\def\\%scomputer{%s}\n", ssrf, dive->dcs[0].model.c_str());
|
||||
put_format(&buf, "\\def\\%scountry{%s}\n", ssrf, country.c_str());
|
||||
put_format(&buf, "\\def\\%stime{%u:%02u}\n", ssrf, FRACTION_TUPLE(dive->duration.seconds, 60));
|
||||
|
||||
|
@ -287,7 +287,7 @@ void export_depths(const char *filename, bool selected_only)
|
|||
|
||||
FOR_EACH_PICTURE (dive) {
|
||||
depth_t depth;
|
||||
for (auto &s: dive->dc.samples) {
|
||||
for (auto &s: dive->dcs[0].samples) {
|
||||
if ((int32_t)s.time.seconds > picture->offset.seconds)
|
||||
break;
|
||||
depth = s.depth;
|
||||
|
|
|
@ -404,7 +404,7 @@ AddDive::AddDive(dive *d, bool autogroup, bool newNumber)
|
|||
setText(Command::Base::tr("add dive"));
|
||||
// By convention, d is a pointer to "displayed dive" or a temporary variable and can be overwritten.
|
||||
d->maxdepth.mm = 0;
|
||||
d->dc.maxdepth.mm = 0;
|
||||
d->dcs[0].maxdepth.mm = 0;
|
||||
fixup_dive(d);
|
||||
|
||||
// this only matters if undoit were called before redoit
|
||||
|
@ -883,7 +883,7 @@ static std::array<dive *, 2> splitDiveComputer(const dive *d, int dc_num)
|
|||
{
|
||||
// Refuse to do anything if the dive has only one dive computer.
|
||||
// Yes, this should have been checked by the UI, but let's just make sure.
|
||||
if (!d->dc.next)
|
||||
if (d->dcs.size() <= 1)
|
||||
return { nullptr, nullptr};
|
||||
|
||||
dive *new1, *new2;
|
||||
|
|
|
@ -306,11 +306,11 @@ QString EditAtmPress::fieldName() const
|
|||
// ***** Duration *****
|
||||
void EditDuration::set(struct dive *d, int value) const
|
||||
{
|
||||
d->dc.duration.seconds = value;
|
||||
d->duration = d->dc.duration;
|
||||
d->dc.meandepth.mm = 0;
|
||||
d->dc.samples.clear();
|
||||
fake_dc(&d->dc);
|
||||
d->dcs[0].duration.seconds = value;
|
||||
d->duration = d->dcs[0].duration;
|
||||
d->dcs[0].meandepth.mm = 0;
|
||||
d->dcs[0].samples.clear();
|
||||
fake_dc(&d->dcs[0]);
|
||||
}
|
||||
|
||||
int EditDuration::data(struct dive *d) const
|
||||
|
@ -326,11 +326,11 @@ QString EditDuration::fieldName() const
|
|||
// ***** Depth *****
|
||||
void EditDepth::set(struct dive *d, int value) const
|
||||
{
|
||||
d->dc.maxdepth.mm = value;
|
||||
d->maxdepth = d->dc.maxdepth;
|
||||
d->dc.meandepth.mm = 0;
|
||||
d->dc.samples.clear();
|
||||
fake_dc(&d->dc);
|
||||
d->dcs[0].maxdepth.mm = value;
|
||||
d->maxdepth = d->dcs[0].maxdepth;
|
||||
d->dcs[0].meandepth.mm = 0;
|
||||
d->dcs[0].samples.clear();
|
||||
fake_dc(&d->dcs[0]);
|
||||
}
|
||||
|
||||
int EditDepth::data(struct dive *d) const
|
||||
|
@ -808,7 +808,7 @@ ReplanDive::ReplanDive(dive *source) : d(current_dive),
|
|||
return;
|
||||
|
||||
// Fix source. Things might be inconsistent after modifying the profile.
|
||||
source->maxdepth.mm = source->dc.maxdepth.mm = 0;
|
||||
source->maxdepth.mm = source->dcs[0].maxdepth.mm = 0;
|
||||
fixup_dive(source);
|
||||
|
||||
when = source->when;
|
||||
|
@ -821,7 +821,7 @@ ReplanDive::ReplanDive(dive *source) : d(current_dive),
|
|||
|
||||
// This resets the dive computers and cylinders of the source dive, avoiding deep copies.
|
||||
std::swap(source->cylinders, cylinders);
|
||||
std::swap(source->dc, dc);
|
||||
std::swap(source->dcs[0], dc);
|
||||
|
||||
setText(Command::Base::tr("Replan dive"));
|
||||
}
|
||||
|
@ -829,7 +829,6 @@ ReplanDive::ReplanDive(dive *source) : d(current_dive),
|
|||
ReplanDive::~ReplanDive()
|
||||
{
|
||||
clear_cylinder_table(&cylinders);
|
||||
free_dive_dcs(&dc);
|
||||
free(notes);
|
||||
}
|
||||
|
||||
|
@ -844,7 +843,7 @@ void ReplanDive::undo()
|
|||
std::swap(d->maxdepth, maxdepth);
|
||||
std::swap(d->meandepth, meandepth);
|
||||
std::swap(d->cylinders, cylinders);
|
||||
std::swap(d->dc, dc);
|
||||
std::swap(d->dcs[0], dc);
|
||||
std::swap(d->notes, notes);
|
||||
std::swap(d->surface_pressure, surface_pressure);
|
||||
std::swap(d->duration, duration);
|
||||
|
@ -887,7 +886,7 @@ EditProfile::EditProfile(const dive *source, int dcNr, EditProfileType type, int
|
|||
dcmaxdepth({0}),
|
||||
duration({0})
|
||||
{
|
||||
const struct divecomputer *sdc = get_dive_dc_const(source, dcNr);
|
||||
const struct divecomputer *sdc = get_dive_dc(source, dcNr);
|
||||
if (!sdc)
|
||||
d = nullptr; // Signal that we refuse to do anything.
|
||||
if (!d)
|
||||
|
@ -906,7 +905,6 @@ EditProfile::EditProfile(const dive *source, int dcNr, EditProfileType type, int
|
|||
|
||||
EditProfile::~EditProfile()
|
||||
{
|
||||
free_dive_dcs(&dc);
|
||||
}
|
||||
|
||||
bool EditProfile::workToBeDone()
|
||||
|
@ -1423,7 +1421,7 @@ EditDive::EditDive(dive *oldDiveIn, dive *newDiveIn, dive_site *createDs, dive_s
|
|||
changedFields |= DiveField::SUIT;
|
||||
if (taglist_get_tagstring(oldDive->tag_list) != taglist_get_tagstring(newDive->tag_list)) // This is cheating. Do we have a taglist comparison function?
|
||||
changedFields |= DiveField::TAGS;
|
||||
if (oldDive->dc.divemode != newDive->dc.divemode)
|
||||
if (oldDive->dcs[0].divemode != newDive->dcs[0].divemode)
|
||||
changedFields |= DiveField::MODE;
|
||||
if (!same_string(oldDive->notes, newDive->notes))
|
||||
changedFields |= DiveField::NOTES;
|
||||
|
|
|
@ -444,7 +444,7 @@ static void cochran_parse_samples(struct dive *dive, const unsigned char *log,
|
|||
unsigned int ndl = 0;
|
||||
unsigned int in_deco = 0, deco_ceiling = 0, deco_time = 0;
|
||||
|
||||
struct divecomputer *dc = &dive->dc;
|
||||
struct divecomputer *dc = &dive->dcs[0];
|
||||
struct sample *sample;
|
||||
|
||||
// Initialize stat variables
|
||||
|
@ -664,7 +664,7 @@ static void cochran_parse_dive(const unsigned char *decode, unsigned mod,
|
|||
#endif
|
||||
|
||||
auto dive = std::make_unique<struct dive>();
|
||||
dc = &dive->dc;
|
||||
dc = &dive->dcs[0];
|
||||
|
||||
unsigned char *log = (buf + 0x4914);
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
|
|||
* Next, Time in minutes since 00:00
|
||||
*/
|
||||
read_bytes(2);
|
||||
dt_dive->dc.when = dt_dive->when = (timestamp_t)date_time_to_ssrfc(tmp_4bytes, tmp_2bytes);
|
||||
dt_dive->dcs[0].when = dt_dive->when = (timestamp_t)date_time_to_ssrfc(tmp_4bytes, tmp_2bytes);
|
||||
|
||||
/*
|
||||
* Now, Locality, 1st byte is long of string, rest is string
|
||||
|
@ -239,19 +239,19 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
|
|||
read_bytes(1);
|
||||
switch (tmp_1byte) {
|
||||
case 1:
|
||||
dt_dive->dc.surface_pressure.mbar = 1013;
|
||||
dt_dive->dcs[0].surface_pressure.mbar = 1013;
|
||||
break;
|
||||
case 2:
|
||||
dt_dive->dc.surface_pressure.mbar = 932;
|
||||
dt_dive->dcs[0].surface_pressure.mbar = 932;
|
||||
break;
|
||||
case 3:
|
||||
dt_dive->dc.surface_pressure.mbar = 828;
|
||||
dt_dive->dcs[0].surface_pressure.mbar = 828;
|
||||
break;
|
||||
case 4:
|
||||
dt_dive->dc.surface_pressure.mbar = 735;
|
||||
dt_dive->dcs[0].surface_pressure.mbar = 735;
|
||||
break;
|
||||
default:
|
||||
dt_dive->dc.surface_pressure.mbar = 1013;
|
||||
dt_dive->dcs[0].surface_pressure.mbar = 1013;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -259,7 +259,7 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
|
|||
*/
|
||||
read_bytes(2);
|
||||
if (tmp_2bytes != 0x7FFF)
|
||||
dt_dive->dc.surfacetime.seconds = (uint32_t) tmp_2bytes * 60;
|
||||
dt_dive->dcs[0].surfacetime.seconds = (uint32_t) tmp_2bytes * 60;
|
||||
|
||||
/*
|
||||
* Weather, values table, 0 to 6
|
||||
|
@ -296,7 +296,7 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
|
|||
*/
|
||||
read_bytes(2);
|
||||
if (tmp_2bytes != 0x7FFF)
|
||||
dt_dive->dc.airtemp.mkelvin = C_to_mkelvin((double)(tmp_2bytes / 100));
|
||||
dt_dive->dcs[0].airtemp.mkelvin = C_to_mkelvin((double)(tmp_2bytes / 100));
|
||||
|
||||
/*
|
||||
* Dive suit, values table, 0 to 6
|
||||
|
@ -349,14 +349,14 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
|
|||
*/
|
||||
read_bytes(2);
|
||||
if (tmp_2bytes != 0x7FFF)
|
||||
dt_dive->maxdepth.mm = dt_dive->dc.maxdepth.mm = (int32_t)tmp_2bytes * 10;
|
||||
dt_dive->maxdepth.mm = dt_dive->dcs[0].maxdepth.mm = (int32_t)tmp_2bytes * 10;
|
||||
|
||||
/*
|
||||
* Dive time in minutes.
|
||||
*/
|
||||
read_bytes(2);
|
||||
if (tmp_2bytes != 0x7FFF)
|
||||
dt_dive->duration.seconds = dt_dive->dc.duration.seconds = (uint32_t)tmp_2bytes * 60;
|
||||
dt_dive->duration.seconds = dt_dive->dcs[0].duration.seconds = (uint32_t)tmp_2bytes * 60;
|
||||
|
||||
/*
|
||||
* Minimum water temperature in C*100. If unknown, set it to 0K which
|
||||
|
@ -364,7 +364,7 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
|
|||
*/
|
||||
read_bytes(2);
|
||||
if (tmp_2bytes != 0x7fff)
|
||||
dt_dive->watertemp.mkelvin = dt_dive->dc.watertemp.mkelvin = C_to_mkelvin((double)(tmp_2bytes / 100));
|
||||
dt_dive->watertemp.mkelvin = dt_dive->dcs[0].watertemp.mkelvin = C_to_mkelvin((double)(tmp_2bytes / 100));
|
||||
else
|
||||
dt_dive->watertemp.mkelvin = 0;
|
||||
|
||||
|
@ -404,7 +404,7 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
|
|||
if (bit_set(tmp_1byte, 1)) {
|
||||
taglist_add_tag(&dt_dive->tag_list, strdup("rebreather"));
|
||||
is_SCR = 1;
|
||||
dt_dive->dc.divemode = PSCR;
|
||||
dt_dive->dcs[0].divemode = PSCR;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -519,7 +519,7 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
|
|||
libdc_model = dtrak_prepare_data(tmp_1byte, devdata);
|
||||
if (!libdc_model)
|
||||
report_error(translate("gettextFromC", "[Warning] Manual dive # %d\n"), dt_dive->number);
|
||||
dt_dive->dc.model = copy_string(devdata.model.c_str());
|
||||
dt_dive->dcs[0].model = copy_string(devdata.model.c_str());
|
||||
|
||||
/*
|
||||
* Air usage, unknown use. Probably allows or deny manually entering gas
|
||||
|
@ -561,10 +561,9 @@ static char *dt_dive_parser(unsigned char *runner, struct dive *dt_dive, struct
|
|||
* Initialize some dive data not supported by Datatrak/WLog
|
||||
*/
|
||||
if (!libdc_model)
|
||||
dt_dive->dc.deviceid = 0;
|
||||
dt_dive->dcs[0].deviceid = 0;
|
||||
else
|
||||
dt_dive->dc.deviceid = 0xffffffff;
|
||||
dt_dive->dc.next = NULL;
|
||||
dt_dive->dcs[0].deviceid = 0xffffffff;
|
||||
if (!is_SCR && dt_dive->cylinders.nr > 0) {
|
||||
get_cylinder(dt_dive, 0)->end.mbar = get_cylinder(dt_dive, 0)->start.mbar -
|
||||
((get_cylinder(dt_dive, 0)->gas_used.mliter / get_cylinder(dt_dive, 0)->type.size.mliter) * 1000);
|
||||
|
|
|
@ -124,9 +124,8 @@ void clear_device_table(struct device_table *device_table)
|
|||
bool device_used_by_selected_dive(const struct device *dev)
|
||||
{
|
||||
for (dive *d: getDiveSelection()) {
|
||||
struct divecomputer *dc;
|
||||
for_each_dc (d, dc) {
|
||||
if (dc->deviceid == dev->deviceId)
|
||||
for (auto &dc: d->dcs) {
|
||||
if (dc.deviceid == dev->deviceId)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
578
core/dive.cpp
578
core/dive.cpp
File diff suppressed because it is too large
Load diff
14
core/dive.h
14
core/dive.h
|
@ -10,6 +10,7 @@
|
|||
#include "picture.h" // TODO: remove
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
extern int last_xml_version;
|
||||
|
||||
|
@ -22,6 +23,7 @@ struct dive_trip;
|
|||
struct full_text_cache;
|
||||
struct event;
|
||||
struct trip_table;
|
||||
|
||||
struct dive {
|
||||
struct dive_trip *divetrip = nullptr;
|
||||
timestamp_t when = 0;
|
||||
|
@ -45,7 +47,7 @@ struct dive {
|
|||
int user_salinity = 0; // water density reflecting a user-specified type
|
||||
|
||||
struct tag_entry *tag_list = nullptr;
|
||||
struct divecomputer dc;
|
||||
std::vector<divecomputer> dcs; // Attn: pointers to divecomputers are not stable!
|
||||
int id = 0; // unique ID for this dive
|
||||
struct picture_table pictures = { };
|
||||
unsigned char git_id[20] = {};
|
||||
|
@ -117,8 +119,10 @@ extern std::string get_dive_country(const struct dive *dive);
|
|||
extern std::string get_dive_location(const struct dive *dive);
|
||||
extern unsigned int number_of_computers(const struct dive *dive);
|
||||
extern struct divecomputer *get_dive_dc(struct dive *dive, int nr);
|
||||
extern const struct divecomputer *get_dive_dc_const(const struct dive *dive, int nr);
|
||||
extern const struct divecomputer *get_dive_dc(const struct dive *dive, int nr);
|
||||
extern timestamp_t dive_endtime(const struct dive *dive);
|
||||
extern temperature_t dc_airtemp(const struct dive *dive);
|
||||
extern temperature_t dc_watertemp(const struct dive *dive);
|
||||
|
||||
extern void set_git_prefs(const char *prefs);
|
||||
|
||||
|
@ -136,12 +140,6 @@ void split_divecomputer(const struct dive *src, int num, struct dive **out1, str
|
|||
#define for_each_dive(_i, _x) \
|
||||
for ((_i) = 0; ((_x) = get_dive(_i)) != NULL; (_i)++)
|
||||
|
||||
#define for_each_dc(_dive, _dc) \
|
||||
for (_dc = &_dive->dc; _dc; _dc = _dc->next)
|
||||
|
||||
#define for_each_relevant_dc(_dive, _dc) \
|
||||
for (_dc = &_dive->dc; _dc; _dc = _dc->next) if (!is_logged(_dive) || !is_dc_planner(_dc))
|
||||
|
||||
extern struct dive *get_dive_by_uniq_id(int id);
|
||||
extern int get_idx_by_uniq_id(int id);
|
||||
extern bool dive_site_has_gps_location(const struct dive_site *ds);
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
divecomputer::divecomputer() = default;
|
||||
divecomputer::~divecomputer() = default;
|
||||
divecomputer::divecomputer(const divecomputer &) = default;
|
||||
divecomputer::divecomputer(divecomputer &&) = default;
|
||||
divecomputer &divecomputer::operator=(const divecomputer &) = default;
|
||||
|
||||
|
@ -229,18 +230,6 @@ int get_depth_at_time(const struct divecomputer *dc, unsigned int time)
|
|||
return depth;
|
||||
}
|
||||
|
||||
static void free_dc(struct divecomputer *dc)
|
||||
{
|
||||
delete dc;
|
||||
}
|
||||
|
||||
/* The first divecomputer is embedded in the dive structure. Ignore it.
|
||||
* For all remainding dcs in the list, free data and structures. */
|
||||
void free_dive_dcs(struct divecomputer *dc)
|
||||
{
|
||||
STRUCTURED_LIST_FREE(struct divecomputer, dc->next, free_dc);
|
||||
}
|
||||
|
||||
struct sample *prepare_sample(struct divecomputer *dc)
|
||||
{
|
||||
if (dc) {
|
||||
|
@ -274,12 +263,12 @@ void append_sample(const struct sample &sample, struct divecomputer *dc)
|
|||
*
|
||||
* This ignores any surface time in the middle of the dive.
|
||||
*/
|
||||
void fixup_dc_duration(struct divecomputer *dc)
|
||||
void fixup_dc_duration(struct divecomputer &dc)
|
||||
{
|
||||
int duration = 0;
|
||||
int lasttime = 0, lastdepth = 0, depthtime = 0;
|
||||
|
||||
for (const auto &sample: dc->samples) {
|
||||
for (const auto &sample: dc.samples) {
|
||||
int time = sample.time.seconds;
|
||||
int depth = sample.depth.mm;
|
||||
|
||||
|
@ -292,48 +281,11 @@ void fixup_dc_duration(struct divecomputer *dc)
|
|||
lasttime = time;
|
||||
}
|
||||
if (duration) {
|
||||
dc->duration.seconds = duration;
|
||||
dc->meandepth.mm = (depthtime + duration / 2) / duration;
|
||||
dc.duration.seconds = duration;
|
||||
dc.meandepth.mm = (depthtime + duration / 2) / duration;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* What do the dive computers say the water temperature is?
|
||||
* (not in the samples, but as dc property for dcs that support that)
|
||||
*/
|
||||
unsigned int dc_watertemp(const struct divecomputer *dc)
|
||||
{
|
||||
int sum = 0, nr = 0;
|
||||
|
||||
do {
|
||||
if (dc->watertemp.mkelvin) {
|
||||
sum += dc->watertemp.mkelvin;
|
||||
nr++;
|
||||
}
|
||||
} while ((dc = dc->next) != NULL);
|
||||
if (!nr)
|
||||
return 0;
|
||||
return (sum + nr / 2) / nr;
|
||||
}
|
||||
|
||||
/*
|
||||
* What do the dive computers say the air temperature is?
|
||||
*/
|
||||
unsigned int dc_airtemp(const struct divecomputer *dc)
|
||||
{
|
||||
int sum = 0, nr = 0;
|
||||
|
||||
do {
|
||||
if (dc->airtemp.mkelvin) {
|
||||
sum += dc->airtemp.mkelvin;
|
||||
nr++;
|
||||
}
|
||||
} while ((dc = dc->next) != NULL);
|
||||
if (!nr)
|
||||
return 0;
|
||||
return (sum + nr / 2) / nr;
|
||||
}
|
||||
|
||||
static bool operator<(const event &ev1, const event &ev2)
|
||||
{
|
||||
if (ev1.time.seconds < ev2.time.seconds)
|
||||
|
@ -399,27 +351,27 @@ void add_extra_data(struct divecomputer *dc, const std::string &key, const std::
|
|||
* positive for "same dive" and negative for "definitely
|
||||
* not the same dive"
|
||||
*/
|
||||
int match_one_dc(const struct divecomputer *a, const struct divecomputer *b)
|
||||
int match_one_dc(const struct divecomputer &a, const struct divecomputer &b)
|
||||
{
|
||||
/* Not same model? Don't know if matching.. */
|
||||
if (a->model.empty() || b->model.empty())
|
||||
if (a.model.empty() || b.model.empty())
|
||||
return 0;
|
||||
if (strcasecmp(a->model.c_str(), b->model.c_str()))
|
||||
if (strcasecmp(a.model.c_str(), b.model.c_str()))
|
||||
return 0;
|
||||
|
||||
/* Different device ID's? Don't know */
|
||||
if (a->deviceid != b->deviceid)
|
||||
if (a.deviceid != b.deviceid)
|
||||
return 0;
|
||||
|
||||
/* Do we have dive IDs? */
|
||||
if (!a->diveid || !b->diveid)
|
||||
if (!a.diveid || !b.diveid)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* If they have different dive ID's on the same
|
||||
* dive computer, that's a definite "same or not"
|
||||
*/
|
||||
return a->diveid == b->diveid && a->when == b->when ? 1 : -1;
|
||||
return a.diveid == b.diveid && a.when == b.when ? 1 : -1;
|
||||
}
|
||||
|
||||
static const char *planner_dc_name = "planned dive";
|
||||
|
|
|
@ -43,10 +43,10 @@ struct divecomputer {
|
|||
std::vector<struct sample> samples;
|
||||
std::vector<struct event> events;
|
||||
std::vector<struct extra_data> extra_data;
|
||||
struct divecomputer *next = nullptr;
|
||||
|
||||
divecomputer();
|
||||
~divecomputer();
|
||||
divecomputer(const divecomputer &);
|
||||
divecomputer(divecomputer &&);
|
||||
divecomputer &operator=(const divecomputer &);
|
||||
};
|
||||
|
@ -54,10 +54,9 @@ struct divecomputer {
|
|||
extern void fake_dc(struct divecomputer *dc);
|
||||
extern void free_dc_contents(struct divecomputer *dc);
|
||||
extern int get_depth_at_time(const struct divecomputer *dc, unsigned int time);
|
||||
extern void free_dive_dcs(struct divecomputer *dc);
|
||||
extern struct sample *prepare_sample(struct divecomputer *dc);
|
||||
extern void append_sample(const struct sample &sample, struct divecomputer *dc);
|
||||
extern void fixup_dc_duration(struct divecomputer *dc);
|
||||
extern void fixup_dc_duration(struct divecomputer &dc);
|
||||
extern unsigned int dc_airtemp(const struct divecomputer *dc);
|
||||
extern unsigned int dc_watertemp(const struct divecomputer *dc);
|
||||
extern int add_event_to_dc(struct divecomputer *dc, struct event ev); // event structure is consumed, returns index of inserted event
|
||||
|
@ -73,6 +72,6 @@ extern bool is_dc_manually_added_dive(const struct divecomputer *dc);
|
|||
extern void make_manually_added_dive_dc(struct divecomputer *dc);
|
||||
|
||||
/* Check if two dive computer entries are the exact same dive (-1=no/0=maybe/1=yes) */
|
||||
extern int match_one_dc(const struct divecomputer *a, const struct divecomputer *b);
|
||||
extern int match_one_dc(const struct divecomputer &a, const struct divecomputer &b);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -118,7 +118,7 @@ static int get_sample_o2(const struct dive *dive, const struct divecomputer *dc,
|
|||
static int calculate_otu(const struct dive *dive)
|
||||
{
|
||||
double otu = 0.0;
|
||||
const struct divecomputer *dc = &dive->dc;
|
||||
const struct divecomputer *dc = &dive->dcs[0];
|
||||
for (auto [psample, sample]: pairwise_range(dc->samples)) {
|
||||
int t;
|
||||
int po2i, po2f;
|
||||
|
@ -179,7 +179,7 @@ static int calculate_otu(const struct dive *dive)
|
|||
to the end of the segment, assuming a constant rate of change in po2 (i.e. depth) with time. */
|
||||
static double calculate_cns_dive(const struct dive *dive)
|
||||
{
|
||||
const struct divecomputer *dc = &dive->dc;
|
||||
const struct divecomputer *dc = &dive->dcs[0];
|
||||
double cns = 0.0;
|
||||
double rate;
|
||||
/* Calculate the CNS for each sample in this dive and sum them */
|
||||
|
@ -334,7 +334,7 @@ static double calculate_airuse(const struct dive *dive)
|
|||
int airuse = 0;
|
||||
|
||||
// SAC for a CCR dive does not make sense.
|
||||
if (dive->dc.divemode == CCR)
|
||||
if (dive->dcs[0].divemode == CCR)
|
||||
return 0.0;
|
||||
|
||||
for (int i = 0; i < dive->cylinders.nr; i++) {
|
||||
|
@ -362,7 +362,7 @@ static double calculate_airuse(const struct dive *dive)
|
|||
/* this only uses the first divecomputer to calculate the SAC rate */
|
||||
static int calculate_sac(const struct dive *dive)
|
||||
{
|
||||
const struct divecomputer *dc = &dive->dc;
|
||||
const struct divecomputer *dc = &dive->dcs[0];
|
||||
double airuse, pressure, sac;
|
||||
int duration, meandepth;
|
||||
|
||||
|
@ -389,10 +389,10 @@ static int calculate_sac(const struct dive *dive)
|
|||
/* for now we do this based on the first divecomputer */
|
||||
static void add_dive_to_deco(struct deco_state *ds, struct dive *dive, bool in_planner)
|
||||
{
|
||||
struct divecomputer *dc = &dive->dc;
|
||||
struct divecomputer *dc = &dive->dcs[0];
|
||||
|
||||
gasmix_loop loop(*dive, dive->dc);
|
||||
divemode_loop loop_d(dive->dc);
|
||||
gasmix_loop loop(*dive, dive->dcs[0]);
|
||||
divemode_loop loop_d(dive->dcs[0]);
|
||||
for (auto [psample, sample]: pairwise_range(dc->samples)) {
|
||||
int t0 = psample.time.seconds;
|
||||
int t1 = sample.time.seconds;
|
||||
|
@ -601,19 +601,21 @@ void update_cylinder_related_info(struct dive *dive)
|
|||
}
|
||||
}
|
||||
|
||||
/* Compare a list of dive computers by model name */
|
||||
static int comp_dc(const struct divecomputer *dc1, const struct divecomputer *dc2)
|
||||
/* Compare list of dive computers by model name */
|
||||
static int comp_dc(const struct dive *d1, const struct dive *d2)
|
||||
{
|
||||
int cmp;
|
||||
while (dc1 || dc2) {
|
||||
if (!dc1)
|
||||
auto it1 = d1->dcs.begin();
|
||||
auto it2 = d2->dcs.begin();
|
||||
while (it1 != d1->dcs.end() || it2 != d2->dcs.end()) {
|
||||
if (it1 == d1->dcs.end())
|
||||
return -1;
|
||||
if (!dc2)
|
||||
if (it2 == d2->dcs.end())
|
||||
return 1;
|
||||
if ((cmp = dc1->model.compare(dc2->model)) != 0)
|
||||
int cmp = it1->model.compare(it2->model);
|
||||
if (cmp != 0)
|
||||
return cmp;
|
||||
dc1 = dc1->next;
|
||||
dc2 = dc2->next;
|
||||
++it1;
|
||||
++it2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -656,7 +658,7 @@ int comp_dives(const struct dive *a, const struct dive *b)
|
|||
return -1;
|
||||
if (a->number > b->number)
|
||||
return 1;
|
||||
if ((cmp = comp_dc(&a->dc, &b->dc)) != 0)
|
||||
if ((cmp = comp_dc(a, b)) != 0)
|
||||
return cmp;
|
||||
if (a->id < b->id)
|
||||
return -1;
|
||||
|
@ -1375,15 +1377,13 @@ bool has_dive(unsigned int deviceid, unsigned int diveid)
|
|||
struct dive *dive;
|
||||
|
||||
for_each_dive (i, dive) {
|
||||
struct divecomputer *dc;
|
||||
|
||||
for_each_dc (dive, dc) {
|
||||
if (dc->deviceid != deviceid)
|
||||
continue;
|
||||
if (dc->diveid != diveid)
|
||||
continue;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
for (auto &dc: dive->dcs) {
|
||||
if (dc.deviceid != deviceid)
|
||||
continue;
|
||||
if (dc.diveid != diveid)
|
||||
continue;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -1077,7 +1077,7 @@ bool filter_constraint_match_dive(const filter_constraint &c, const struct dive
|
|||
case FILTER_CONSTRAINT_PLANNED:
|
||||
return is_planned(d) != c.negate;
|
||||
case FILTER_CONSTRAINT_DIVE_MODE:
|
||||
return check_multiple_choice(c, (int)d->dc.divemode); // should we be smarter and check all DCs?
|
||||
return check_multiple_choice(c, (int)d->dcs[0].divemode); // should we be smarter and check all DCs?
|
||||
case FILTER_CONSTRAINT_TAGS:
|
||||
return has_tags(c, d);
|
||||
case FILTER_CONSTRAINT_PEOPLE:
|
||||
|
|
|
@ -118,13 +118,13 @@ static int cobalt_dive(void *param, int, char **data, char **)
|
|||
|
||||
/* Cobalt stores the pressures, not the depth */
|
||||
if (data[6])
|
||||
state->cur_dive->dc.maxdepth.mm = atoi(data[6]);
|
||||
state->cur_dive->dcs[0].maxdepth.mm = atoi(data[6]);
|
||||
|
||||
if (data[7])
|
||||
state->cur_dive->dc.duration.seconds = atoi(data[7]);
|
||||
state->cur_dive->dcs[0].duration.seconds = atoi(data[7]);
|
||||
|
||||
if (data[8])
|
||||
state->cur_dive->dc.surface_pressure.mbar = atoi(data[8]);
|
||||
state->cur_dive->dcs[0].surface_pressure.mbar = atoi(data[8]);
|
||||
/*
|
||||
* TODO: the deviceid hash should be calculated here.
|
||||
*/
|
||||
|
@ -140,8 +140,8 @@ static int cobalt_dive(void *param, int, char **data, char **)
|
|||
settings_end(state);
|
||||
|
||||
if (data[9]) {
|
||||
state->cur_dive->dc.deviceid = atoi(data[9]);
|
||||
state->cur_dive->dc.model = "Cobalt import";
|
||||
state->cur_dive->dcs[0].deviceid = atoi(data[9]);
|
||||
state->cur_dive->dcs[0].model = "Cobalt import";
|
||||
}
|
||||
|
||||
snprintf(get_buffer, sizeof(get_buffer) - 1, get_cylinder_template, state->cur_dive->number);
|
||||
|
|
|
@ -418,7 +418,7 @@ int try_to_open_csv(std::string &mem, enum csv_format type, struct divelog *log)
|
|||
auto dive = std::make_unique<struct dive>();
|
||||
dive->when = date;
|
||||
dive->number = atoi(header[1]);
|
||||
dc = &dive->dc;
|
||||
dc = &dive->dcs[0];
|
||||
|
||||
time = 0;
|
||||
for (;;) {
|
||||
|
@ -511,11 +511,11 @@ int parse_txt_file(const char *filename, const char *csv, struct divelog *log)
|
|||
|
||||
auto dive = std::make_unique<struct dive>();
|
||||
dive->when = utc_mktime(&cur_tm);;
|
||||
dive->dc.model = "Poseidon MkVI Discovery";
|
||||
dive->dcs[0].model = "Poseidon MkVI Discovery";
|
||||
value = parse_mkvi_value(memtxt.data(), "Rig Serial number");
|
||||
dive->dc.deviceid = atoi(value.c_str());
|
||||
dive->dc.divemode = CCR;
|
||||
dive->dc.no_o2sensors = 2;
|
||||
dive->dcs[0].deviceid = atoi(value.c_str());
|
||||
dive->dcs[0].divemode = CCR;
|
||||
dive->dcs[0].no_o2sensors = 2;
|
||||
|
||||
cyl.cylinder_use = OXYGEN;
|
||||
cyl.type.size.mliter = 3000;
|
||||
|
@ -547,9 +547,9 @@ int parse_txt_file(const char *filename, const char *csv, struct divelog *log)
|
|||
std::string value = parse_mkvi_value(lineptr, key.c_str());
|
||||
if (value.empty())
|
||||
break;
|
||||
add_extra_data(&dive->dc, key, value);
|
||||
add_extra_data(&dive->dcs[0], key, value);
|
||||
}
|
||||
dc = &dive->dc;
|
||||
dc = &dive->dcs[0];
|
||||
|
||||
/*
|
||||
* Read samples from the CSV file. A sample contains all the lines with same timestamp. The CSV file has
|
||||
|
|
|
@ -212,8 +212,8 @@ static int divinglog_profile(void *param, int, char **data, char **)
|
|||
* Count the number of o2 sensors
|
||||
*/
|
||||
|
||||
if (!state->cur_dive->dc.no_o2sensors && (state->cur_sample->o2sensor[0].mbar || state->cur_sample->o2sensor[1].mbar || state->cur_sample->o2sensor[2].mbar)) {
|
||||
state->cur_dive->dc.no_o2sensors = state->cur_sample->o2sensor[0].mbar ? 1 : 0 +
|
||||
if (!state->cur_dive->dcs[0].no_o2sensors && (state->cur_sample->o2sensor[0].mbar || state->cur_sample->o2sensor[1].mbar || state->cur_sample->o2sensor[2].mbar)) {
|
||||
state->cur_dive->dcs[0].no_o2sensors = state->cur_sample->o2sensor[0].mbar ? 1 : 0 +
|
||||
state->cur_sample->o2sensor[1].mbar ? 1 : 0 +
|
||||
state->cur_sample->o2sensor[2].mbar ? 1 : 0;
|
||||
}
|
||||
|
@ -285,10 +285,10 @@ static int divinglog_dive(void *param, int, char **data, char **)
|
|||
utf8_string(data[4], &state->cur_dive->notes);
|
||||
|
||||
if (data[5])
|
||||
state->cur_dive->dc.maxdepth.mm = lrint(permissive_strtod(data[5], NULL) * 1000);
|
||||
state->cur_dive->dcs[0].maxdepth.mm = lrint(permissive_strtod(data[5], NULL) * 1000);
|
||||
|
||||
if (data[6])
|
||||
state->cur_dive->dc.duration.seconds = atoi(data[6]) * 60;
|
||||
state->cur_dive->dcs[0].duration.seconds = atoi(data[6]) * 60;
|
||||
|
||||
if (data[7])
|
||||
utf8_string(data[7], &state->cur_dive->diveguide);
|
||||
|
@ -330,7 +330,7 @@ static int divinglog_dive(void *param, int, char **data, char **)
|
|||
dc_settings_start(state);
|
||||
|
||||
if (data[12]) {
|
||||
state->cur_dive->dc.model = data[12];
|
||||
state->cur_dive->dcs[0].model = data[12];
|
||||
} else {
|
||||
state->cur_settings.dc.model = "Divinglog import";
|
||||
}
|
||||
|
@ -355,10 +355,10 @@ static int divinglog_dive(void *param, int, char **data, char **)
|
|||
case '0':
|
||||
break;
|
||||
case '1':
|
||||
state->cur_dive->dc.divemode = PSCR;
|
||||
state->cur_dive->dcs[0].divemode = PSCR;
|
||||
break;
|
||||
case '2':
|
||||
state->cur_dive->dc.divemode = CCR;
|
||||
state->cur_dive->dcs[0].divemode = CCR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -367,9 +367,9 @@ static int divinglog_dive(void *param, int, char **data, char **)
|
|||
settings_end(state);
|
||||
|
||||
if (data[12]) {
|
||||
state->cur_dive->dc.model = data[12];
|
||||
state->cur_dive->dcs[0].model = data[12];
|
||||
} else {
|
||||
state->cur_dive->dc.model = "Divinglog import";
|
||||
state->cur_dive->dcs[0].model = "Divinglog import";
|
||||
}
|
||||
|
||||
snprintf(get_buffer, sizeof(get_buffer) - 1, get_profile_template, diveid);
|
||||
|
|
|
@ -132,14 +132,14 @@ static int seac_dive(void *param, int, char **data, char **)
|
|||
if (data[6]) {
|
||||
switch (atoi(data[6])) {
|
||||
case 1:
|
||||
state->cur_dive->dc.divemode = OC;
|
||||
state->cur_dive->dcs[0].divemode = OC;
|
||||
break;
|
||||
// Gauge Mode
|
||||
case 2:
|
||||
state->cur_dive->dc.divemode = UNDEF_COMP_TYPE;
|
||||
state->cur_dive->dcs[0].divemode = UNDEF_COMP_TYPE;
|
||||
break;
|
||||
case 3:
|
||||
state->cur_dive->dc.divemode = FREEDIVE;
|
||||
state->cur_dive->dcs[0].divemode = FREEDIVE;
|
||||
break;
|
||||
default:
|
||||
if (verbose) {
|
||||
|
@ -155,7 +155,7 @@ static int seac_dive(void *param, int, char **data, char **)
|
|||
|
||||
// 10 = dive duration
|
||||
if (data[10]) {
|
||||
state->cur_dive->dc.duration.seconds = atoi(data[10]);
|
||||
state->cur_dive->dcs[0].duration.seconds = atoi(data[10]);
|
||||
}
|
||||
|
||||
// 8 = water_type
|
||||
|
@ -181,7 +181,7 @@ static int seac_dive(void *param, int, char **data, char **)
|
|||
|
||||
|
||||
if (data[11]) {
|
||||
state->cur_dive->dc.maxdepth.mm = 10 * atoi(data[11]);
|
||||
state->cur_dive->dcs[0].maxdepth.mm = 10 * atoi(data[11]);
|
||||
}
|
||||
|
||||
// Create sql_stmt type to query DB
|
||||
|
@ -205,20 +205,20 @@ static int seac_dive(void *param, int, char **data, char **)
|
|||
settings_start(state);
|
||||
dc_settings_start(state);
|
||||
|
||||
utf8_string_std(data[1], &state->cur_dive->dc.serial);
|
||||
utf8_string_std(data[12],&state->cur_dive->dc.fw_version);
|
||||
state->cur_dive->dc.model = strdup("Seac Action");
|
||||
utf8_string_std(data[1], &state->cur_dive->dcs[0].serial);
|
||||
utf8_string_std(data[12],&state->cur_dive->dcs[0].fw_version);
|
||||
state->cur_dive->dcs[0].model = "Seac Action";
|
||||
|
||||
state->cur_dive->dc.deviceid = calculate_string_hash(data[1]);
|
||||
state->cur_dive->dcs[0].deviceid = calculate_string_hash(data[1]);
|
||||
|
||||
add_extra_data(&state->cur_dive->dc, "GF-Lo", (const char*)sqlite3_column_text(sqlstmt, 9));
|
||||
add_extra_data(&state->cur_dive->dc, "GF-Hi", (const char*)sqlite3_column_text(sqlstmt, 10));
|
||||
add_extra_data(&state->cur_dive->dcs[0], "GF-Lo", (const char*)sqlite3_column_text(sqlstmt, 9));
|
||||
add_extra_data(&state->cur_dive->dcs[0], "GF-Hi", (const char*)sqlite3_column_text(sqlstmt, 10));
|
||||
|
||||
dc_settings_end(state);
|
||||
settings_end(state);
|
||||
|
||||
if (data[11]) {
|
||||
state->cur_dive->dc.maxdepth.mm = 10 * atoi(data[11]);
|
||||
state->cur_dive->dcs[0].maxdepth.mm = 10 * atoi(data[11]);
|
||||
}
|
||||
|
||||
curcyl->gasmix.o2.permille = 10 * sqlite3_column_int(sqlstmt, 4);
|
||||
|
|
|
@ -214,7 +214,7 @@ static int shearwater_mode(void *param, int, char **data, char **)
|
|||
struct parser_state *state = (struct parser_state *)param;
|
||||
|
||||
if (data[0])
|
||||
state->cur_dive->dc.divemode = atoi(data[0]) == 0 ? CCR : OC;
|
||||
state->cur_dive->dcs[0].divemode = atoi(data[0]) == 0 ? CCR : OC;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -249,13 +249,13 @@ static int shearwater_dive(void *param, int, char **data, char **)
|
|||
|
||||
/* TODO: verify that metric calculation is correct */
|
||||
if (data[6])
|
||||
state->cur_dive->dc.maxdepth.mm = state->metric ? lrint(permissive_strtod(data[6], NULL) * 1000) : feet_to_mm(permissive_strtod(data[6], NULL));
|
||||
state->cur_dive->dcs[0].maxdepth.mm = state->metric ? lrint(permissive_strtod(data[6], NULL) * 1000) : feet_to_mm(permissive_strtod(data[6], NULL));
|
||||
|
||||
if (data[7])
|
||||
state->cur_dive->dc.duration.seconds = atoi(data[7]) * 60;
|
||||
state->cur_dive->dcs[0].duration.seconds = atoi(data[7]) * 60;
|
||||
|
||||
if (data[8])
|
||||
state->cur_dive->dc.surface_pressure.mbar = atoi(data[8]);
|
||||
state->cur_dive->dcs[0].surface_pressure.mbar = atoi(data[8]);
|
||||
/*
|
||||
* TODO: the deviceid hash should be calculated here.
|
||||
*/
|
||||
|
@ -285,13 +285,13 @@ static int shearwater_dive(void *param, int, char **data, char **)
|
|||
if (data[10]) {
|
||||
switch (atoi(data[10])) {
|
||||
case 2:
|
||||
state->cur_dive->dc.model = "Shearwater Petrel/Perdix";
|
||||
state->cur_dive->dcs[0].model = "Shearwater Petrel/Perdix";
|
||||
break;
|
||||
case 4:
|
||||
state->cur_dive->dc.model = "Shearwater Predator";
|
||||
state->cur_dive->dcs[0].model = "Shearwater Predator";
|
||||
break;
|
||||
default:
|
||||
state->cur_dive->dc.model = "Shearwater import";
|
||||
state->cur_dive->dcs[0].model = "Shearwater import";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -379,13 +379,13 @@ static int shearwater_cloud_dive(void *param, int, char **data, char **)
|
|||
|
||||
/* TODO: verify that metric calculation is correct */
|
||||
if (data[6])
|
||||
state->cur_dive->dc.maxdepth.mm = state->metric ? lrint(permissive_strtod(data[6], NULL) * 1000) : feet_to_mm(permissive_strtod(data[6], NULL));
|
||||
state->cur_dive->dcs[0].maxdepth.mm = state->metric ? lrint(permissive_strtod(data[6], NULL) * 1000) : feet_to_mm(permissive_strtod(data[6], NULL));
|
||||
|
||||
if (data[7])
|
||||
state->cur_dive->dc.duration.seconds = atoi(data[7]);
|
||||
state->cur_dive->dcs[0].duration.seconds = atoi(data[7]);
|
||||
|
||||
if (data[8])
|
||||
state->cur_dive->dc.surface_pressure.mbar = atoi(data[8]);
|
||||
state->cur_dive->dcs[0].surface_pressure.mbar = atoi(data[8]);
|
||||
/*
|
||||
* TODO: the deviceid hash should be calculated here.
|
||||
*/
|
||||
|
@ -415,13 +415,13 @@ static int shearwater_cloud_dive(void *param, int, char **data, char **)
|
|||
if (data[10]) {
|
||||
switch (atoi(data[10])) {
|
||||
case 2:
|
||||
state->cur_dive->dc.model = "Shearwater Petrel/Perdix";
|
||||
state->cur_dive->dcs[0].model = "Shearwater Petrel/Perdix";
|
||||
break;
|
||||
case 4:
|
||||
state->cur_dive->dc.model = "Shearwater Predator";
|
||||
state->cur_dive->dcs[0].model = "Shearwater Predator";
|
||||
break;
|
||||
default:
|
||||
state->cur_dive->dc.model = "Shearwater import";
|
||||
state->cur_dive->dcs[0].model = "Shearwater import";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,7 +191,7 @@ static int dm4_dive(void *param, int, char **data, char **)
|
|||
if (data[3])
|
||||
state->cur_dive->duration.seconds = atoi(data[3]);
|
||||
if (data[15])
|
||||
state->cur_dive->dc.duration.seconds = atoi(data[15]);
|
||||
state->cur_dive->dcs[0].duration.seconds = atoi(data[15]);
|
||||
|
||||
/*
|
||||
* TODO: the deviceid hash should be calculated here.
|
||||
|
@ -208,11 +208,11 @@ static int dm4_dive(void *param, int, char **data, char **)
|
|||
settings_end(state);
|
||||
|
||||
if (data[6])
|
||||
state->cur_dive->dc.maxdepth.mm = lrint(permissive_strtod(data[6], NULL) * 1000);
|
||||
state->cur_dive->dcs[0].maxdepth.mm = lrint(permissive_strtod(data[6], NULL) * 1000);
|
||||
if (data[8])
|
||||
state->cur_dive->dc.airtemp.mkelvin = C_to_mkelvin(atoi(data[8]));
|
||||
state->cur_dive->dcs[0].airtemp.mkelvin = C_to_mkelvin(atoi(data[8]));
|
||||
if (data[9])
|
||||
state->cur_dive->dc.watertemp.mkelvin = C_to_mkelvin(atoi(data[9]));
|
||||
state->cur_dive->dcs[0].watertemp.mkelvin = C_to_mkelvin(atoi(data[9]));
|
||||
|
||||
/*
|
||||
* TODO: handle multiple cylinders
|
||||
|
@ -237,7 +237,7 @@ static int dm4_dive(void *param, int, char **data, char **)
|
|||
cylinder_end(state);
|
||||
|
||||
if (data[14])
|
||||
state->cur_dive->dc.surface_pressure.mbar = (atoi(data[14]) * 1000);
|
||||
state->cur_dive->dcs[0].surface_pressure.mbar = (atoi(data[14]) * 1000);
|
||||
|
||||
interval = data[16] ? atoi(data[16]) : 0;
|
||||
profileBlob = (float *)data[17];
|
||||
|
@ -249,7 +249,7 @@ static int dm4_dive(void *param, int, char **data, char **)
|
|||
if (profileBlob)
|
||||
state->cur_sample->depth.mm = lrintf(profileBlob[i] * 1000.0f);
|
||||
else
|
||||
state->cur_sample->depth.mm = state->cur_dive->dc.maxdepth.mm;
|
||||
state->cur_sample->depth.mm = state->cur_dive->dcs[0].maxdepth.mm;
|
||||
|
||||
if (data[18] && data[18][0])
|
||||
state->cur_sample->temperature.mkelvin = C_to_mkelvin(tempBlob[i]);
|
||||
|
@ -372,7 +372,7 @@ static int dm5_dive(void *param, int, char **data, char **)
|
|||
if (data[3])
|
||||
state->cur_dive->duration.seconds = atoi(data[3]);
|
||||
if (data[15])
|
||||
state->cur_dive->dc.duration.seconds = atoi(data[15]);
|
||||
state->cur_dive->dcs[0].duration.seconds = atoi(data[15]);
|
||||
|
||||
/*
|
||||
* TODO: the deviceid hash should be calculated here.
|
||||
|
@ -390,28 +390,28 @@ static int dm5_dive(void *param, int, char **data, char **)
|
|||
settings_end(state);
|
||||
|
||||
if (data[6])
|
||||
state->cur_dive->dc.maxdepth.mm = lrint(permissive_strtod(data[6], NULL) * 1000);
|
||||
state->cur_dive->dcs[0].maxdepth.mm = lrint(permissive_strtod(data[6], NULL) * 1000);
|
||||
if (data[8])
|
||||
state->cur_dive->dc.airtemp.mkelvin = C_to_mkelvin(atoi(data[8]));
|
||||
state->cur_dive->dcs[0].airtemp.mkelvin = C_to_mkelvin(atoi(data[8]));
|
||||
if (data[9])
|
||||
state->cur_dive->dc.watertemp.mkelvin = C_to_mkelvin(atoi(data[9]));
|
||||
state->cur_dive->dcs[0].watertemp.mkelvin = C_to_mkelvin(atoi(data[9]));
|
||||
|
||||
if (data[4]) {
|
||||
state->cur_dive->dc.deviceid = atoi(data[4]);
|
||||
state->cur_dive->dcs[0].deviceid = atoi(data[4]);
|
||||
}
|
||||
if (data[5])
|
||||
utf8_string_std(data[5], &state->cur_dive->dc.model);
|
||||
utf8_string_std(data[5], &state->cur_dive->dcs[0].model);
|
||||
|
||||
if (data[25]) {
|
||||
switch(atoi(data[25])) {
|
||||
case 1:
|
||||
state->cur_dive->dc.divemode = OC;
|
||||
state->cur_dive->dcs[0].divemode = OC;
|
||||
break;
|
||||
case 5:
|
||||
state->cur_dive->dc.divemode = CCR;
|
||||
state->cur_dive->dcs[0].divemode = CCR;
|
||||
break;
|
||||
default:
|
||||
state->cur_dive->dc.divemode = OC;
|
||||
state->cur_dive->dcs[0].divemode = OC;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -424,7 +424,7 @@ static int dm5_dive(void *param, int, char **data, char **)
|
|||
}
|
||||
|
||||
if (data[14])
|
||||
state->cur_dive->dc.surface_pressure.mbar = (atoi(data[14]) / 100);
|
||||
state->cur_dive->dcs[0].surface_pressure.mbar = (atoi(data[14]) / 100);
|
||||
|
||||
interval = data[16] ? atoi(data[16]) : 0;
|
||||
|
||||
|
@ -512,7 +512,7 @@ static int dm5_dive(void *param, int, char **data, char **)
|
|||
if (profileBlob)
|
||||
state->cur_sample->depth.mm = lrintf(profileBlob[i] * 1000.0f);
|
||||
else
|
||||
state->cur_sample->depth.mm = state->cur_dive->dc.maxdepth.mm;
|
||||
state->cur_sample->depth.mm = state->cur_dive->dcs[0].maxdepth.mm;
|
||||
|
||||
if (data[18] && data[18][0])
|
||||
state->cur_sample->temperature.mkelvin = C_to_mkelvin(tempBlob[i]);
|
||||
|
|
|
@ -212,7 +212,7 @@ static dc_status_t parse_gasmixes(device_data_t *devdata, struct dive *dive, dc_
|
|||
|
||||
break;
|
||||
default:
|
||||
if (dive->dc.divemode == CCR)
|
||||
if (dive->dcs[0].divemode == CCR)
|
||||
cyl.cylinder_use = DILUENT;
|
||||
else
|
||||
cyl.cylinder_use = OC_GAS;
|
||||
|
@ -526,49 +526,43 @@ static dc_status_t parse_samples(device_data_t *, struct divecomputer *dc, dc_pa
|
|||
return dc_parser_samples_foreach(parser, sample_cb, dc);
|
||||
}
|
||||
|
||||
static int might_be_same_dc(struct divecomputer *a, struct divecomputer *b)
|
||||
static int might_be_same_dc(const struct divecomputer &a, const struct divecomputer &b)
|
||||
{
|
||||
if (a->model.empty() || b->model.empty())
|
||||
if (a.model.empty() || b.model.empty())
|
||||
return 1;
|
||||
if (strcasecmp(a->model.c_str(), b->model.c_str()))
|
||||
if (strcasecmp(a.model.c_str(), b.model.c_str()))
|
||||
return 0;
|
||||
if (!a->deviceid || !b->deviceid)
|
||||
if (!a.deviceid || !b.deviceid)
|
||||
return 1;
|
||||
return a->deviceid == b->deviceid;
|
||||
return a.deviceid == b.deviceid;
|
||||
}
|
||||
|
||||
static int match_one_dive(struct divecomputer *a, struct dive *dive)
|
||||
static bool match_one_dive(const struct divecomputer &a, struct dive *dive)
|
||||
{
|
||||
struct divecomputer *b = &dive->dc;
|
||||
|
||||
/*
|
||||
* Walk the existing dive computer data,
|
||||
* see if we have a match (or an anti-match:
|
||||
* the same dive computer but a different
|
||||
* dive ID).
|
||||
*/
|
||||
do {
|
||||
int match = match_one_dc(a, b);
|
||||
if (match)
|
||||
return match > 0;
|
||||
b = b->next;
|
||||
} while (b);
|
||||
for (auto &b: dive->dcs) {
|
||||
if (match_one_dc(a, b) > 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Ok, no exact dive computer match. Does the date match? */
|
||||
b = &dive->dc;
|
||||
do {
|
||||
if (a->when == b->when && might_be_same_dc(a, b))
|
||||
return 1;
|
||||
b = b->next;
|
||||
} while (b);
|
||||
for (auto &b: dive->dcs) {
|
||||
if (a.when == b.when && might_be_same_dc(a, b))
|
||||
return true;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if this dive already existed before the import
|
||||
*/
|
||||
static int find_dive(struct divecomputer *match)
|
||||
static int find_dive(const struct divecomputer &match)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -604,13 +598,13 @@ static void parse_string_field(device_data_t *devdata, struct dive *dive, dc_fie
|
|||
{
|
||||
// Our dive ID is the string hash of the "Dive ID" string
|
||||
if (!strcmp(str->desc, "Dive ID")) {
|
||||
if (!dive->dc.diveid)
|
||||
dive->dc.diveid = calculate_string_hash(str->value);
|
||||
if (!dive->dcs[0].diveid)
|
||||
dive->dcs[0].diveid = calculate_string_hash(str->value);
|
||||
return;
|
||||
}
|
||||
|
||||
// This will pick up serial number and firmware data
|
||||
add_extra_data(&dive->dc, str->desc, str->value);
|
||||
add_extra_data(&dive->dcs[0], str->desc, str->value);
|
||||
|
||||
/* GPS data? */
|
||||
if (!strncmp(str->desc, "GPS", 3)) {
|
||||
|
@ -648,7 +642,7 @@ static dc_status_t libdc_header_parser(dc_parser_t *parser, device_data_t *devda
|
|||
}
|
||||
|
||||
// Our deviceid is the hash of the serial number
|
||||
dive->dc.deviceid = 0;
|
||||
dive->dcs[0].deviceid = 0;
|
||||
|
||||
if (rc == DC_STATUS_SUCCESS) {
|
||||
tm.tm_year = dt.year;
|
||||
|
@ -657,7 +651,7 @@ static dc_status_t libdc_header_parser(dc_parser_t *parser, device_data_t *devda
|
|||
tm.tm_hour = dt.hour;
|
||||
tm.tm_min = dt.minute;
|
||||
tm.tm_sec = dt.second;
|
||||
dive->when = dive->dc.when = utc_mktime(&tm);
|
||||
dive->when = dive->dcs[0].when = utc_mktime(&tm);
|
||||
}
|
||||
|
||||
// Parse the divetime.
|
||||
|
@ -671,7 +665,7 @@ static dc_status_t libdc_header_parser(dc_parser_t *parser, device_data_t *devda
|
|||
return rc;
|
||||
}
|
||||
if (rc == DC_STATUS_SUCCESS)
|
||||
dive->dc.duration.seconds = divetime;
|
||||
dive->dcs[0].duration.seconds = divetime;
|
||||
|
||||
// Parse the maxdepth.
|
||||
double maxdepth = 0.0;
|
||||
|
@ -681,7 +675,7 @@ static dc_status_t libdc_header_parser(dc_parser_t *parser, device_data_t *devda
|
|||
return rc;
|
||||
}
|
||||
if (rc == DC_STATUS_SUCCESS)
|
||||
dive->dc.maxdepth.mm = lrint(maxdepth * 1000);
|
||||
dive->dcs[0].maxdepth.mm = lrint(maxdepth * 1000);
|
||||
|
||||
// Parse temperatures
|
||||
double temperature;
|
||||
|
@ -697,11 +691,11 @@ static dc_status_t libdc_header_parser(dc_parser_t *parser, device_data_t *devda
|
|||
if (rc == DC_STATUS_SUCCESS)
|
||||
switch(i) {
|
||||
case 0:
|
||||
dive->dc.airtemp.mkelvin = C_to_mkelvin(temperature);
|
||||
dive->dcs[0].airtemp.mkelvin = C_to_mkelvin(temperature);
|
||||
break;
|
||||
case 1: // we don't distinguish min and max water temp here, so take min if given, max otherwise
|
||||
case 2:
|
||||
dive->dc.watertemp.mkelvin = C_to_mkelvin(temperature);
|
||||
dive->dcs[0].watertemp.mkelvin = C_to_mkelvin(temperature);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -725,16 +719,16 @@ static dc_status_t libdc_header_parser(dc_parser_t *parser, device_data_t *devda
|
|||
return rc;
|
||||
}
|
||||
if (rc == DC_STATUS_SUCCESS) {
|
||||
dive->dc.salinity = lrint(salinity.density * 10.0);
|
||||
if (dive->dc.salinity == 0) {
|
||||
dive->dcs[0].salinity = lrint(salinity.density * 10.0);
|
||||
if (dive->dcs[0].salinity == 0) {
|
||||
// sometimes libdivecomputer gives us density values, sometimes just
|
||||
// a water type and a density of zero; let's make this work as best as we can
|
||||
switch (salinity.type) {
|
||||
case DC_WATER_FRESH:
|
||||
dive->dc.salinity = FRESHWATER_SALINITY;
|
||||
dive->dcs[0].salinity = FRESHWATER_SALINITY;
|
||||
break;
|
||||
default:
|
||||
dive->dc.salinity = SEAWATER_SALINITY;
|
||||
dive->dcs[0].salinity = SEAWATER_SALINITY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -747,7 +741,7 @@ static dc_status_t libdc_header_parser(dc_parser_t *parser, device_data_t *devda
|
|||
return rc;
|
||||
}
|
||||
if (rc == DC_STATUS_SUCCESS)
|
||||
dive->dc.surface_pressure.mbar = lrint(surface_pressure * 1000.0);
|
||||
dive->dcs[0].surface_pressure.mbar = lrint(surface_pressure * 1000.0);
|
||||
|
||||
// The dive parsing may give us more device information
|
||||
int idx;
|
||||
|
@ -771,17 +765,17 @@ static dc_status_t libdc_header_parser(dc_parser_t *parser, device_data_t *devda
|
|||
if (rc == DC_STATUS_SUCCESS)
|
||||
switch(divemode) {
|
||||
case DC_DIVEMODE_FREEDIVE:
|
||||
dive->dc.divemode = FREEDIVE;
|
||||
dive->dcs[0].divemode = FREEDIVE;
|
||||
break;
|
||||
case DC_DIVEMODE_GAUGE:
|
||||
case DC_DIVEMODE_OC: /* Open circuit */
|
||||
dive->dc.divemode = OC;
|
||||
dive->dcs[0].divemode = OC;
|
||||
break;
|
||||
case DC_DIVEMODE_CCR: /* Closed circuit rebreather*/
|
||||
dive->dc.divemode = CCR;
|
||||
dive->dcs[0].divemode = CCR;
|
||||
break;
|
||||
case DC_DIVEMODE_SCR: /* Semi-closed circuit rebreather */
|
||||
dive->dc.divemode = PSCR;
|
||||
dive->dcs[0].divemode = PSCR;
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -821,8 +815,8 @@ static int dive_cb(const unsigned char *data, unsigned int size,
|
|||
auto dive = std::make_unique<struct dive>();
|
||||
|
||||
// Fill in basic fields
|
||||
dive->dc.model = devdata->model;
|
||||
dive->dc.diveid = calculate_diveid(fingerprint, fsize);
|
||||
dive->dcs[0].model = devdata->model;
|
||||
dive->dcs[0].diveid = calculate_diveid(fingerprint, fsize);
|
||||
|
||||
// Parse the dive's header data
|
||||
rc = libdc_header_parser (parser, devdata, dive.get());
|
||||
|
@ -832,7 +826,7 @@ static int dive_cb(const unsigned char *data, unsigned int size,
|
|||
}
|
||||
|
||||
// Initialize the sample data.
|
||||
rc = parse_samples(devdata, &dive->dc, parser);
|
||||
rc = parse_samples(devdata, &dive->dcs[0], parser);
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
download_error(translate("gettextFromC", "Error parsing the samples: %s"), errmsg(rc));
|
||||
goto error_exit;
|
||||
|
@ -850,32 +844,32 @@ static int dive_cb(const unsigned char *data, unsigned int size,
|
|||
devdata->fingerprint = (unsigned char *)calloc(fsize, 1);
|
||||
if (devdata->fingerprint) {
|
||||
devdata->fsize = fsize;
|
||||
devdata->fdeviceid = dive->dc.deviceid;
|
||||
devdata->fdiveid = dive->dc.diveid;
|
||||
devdata->fdeviceid = dive->dcs[0].deviceid;
|
||||
devdata->fdiveid = dive->dcs[0].diveid;
|
||||
memcpy(devdata->fingerprint, fingerprint, fsize);
|
||||
}
|
||||
}
|
||||
|
||||
/* If we already saw this dive, abort. */
|
||||
if (!devdata->force_download && find_dive(&dive->dc)) {
|
||||
if (!devdata->force_download && find_dive(dive->dcs[0])) {
|
||||
std::string date_string = get_dive_date_c_string(dive->when);
|
||||
dev_info(devdata, translate("gettextFromC", "Already downloaded dive at %s"), date_string.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Various libdivecomputer interface fixups */
|
||||
if (dive->dc.airtemp.mkelvin == 0 && first_temp_is_air && !dive->dc.samples.empty()) {
|
||||
dive->dc.airtemp = dive->dc.samples[0].temperature;
|
||||
dive->dc.samples[0].temperature.mkelvin = 0;
|
||||
if (dive->dcs[0].airtemp.mkelvin == 0 && first_temp_is_air && !dive->dcs[0].samples.empty()) {
|
||||
dive->dcs[0].airtemp = dive->dcs[0].samples[0].temperature;
|
||||
dive->dcs[0].samples[0].temperature.mkelvin = 0;
|
||||
}
|
||||
|
||||
/* special case for bug in Tecdiving DiveComputer.eu
|
||||
* often the first sample has a water temperature of 0C, followed by the correct
|
||||
* temperature in the next sample */
|
||||
if (dive->dc.model == "Tecdiving DiveComputer.eu" && !dive->dc.samples.empty() &&
|
||||
dive->dc.samples[0].temperature.mkelvin == ZERO_C_IN_MKELVIN &&
|
||||
dive->dc.samples[1].temperature.mkelvin > dive->dc.samples[0].temperature.mkelvin)
|
||||
dive->dc.samples[0].temperature.mkelvin = dive->dc.samples[1].temperature.mkelvin;
|
||||
if (dive->dcs[0].model == "Tecdiving DiveComputer.eu" && !dive->dcs[0].samples.empty() &&
|
||||
dive->dcs[0].samples[0].temperature.mkelvin == ZERO_C_IN_MKELVIN &&
|
||||
dive->dcs[0].samples[1].temperature.mkelvin > dive->dcs[0].samples[0].temperature.mkelvin)
|
||||
dive->dcs[0].samples[0].temperature.mkelvin = dive->dcs[0].samples[1].temperature.mkelvin;
|
||||
|
||||
record_dive_to_table(dive.release(), devdata->log->dives.get());
|
||||
return true;
|
||||
|
@ -1593,7 +1587,7 @@ dc_status_t libdc_buffer_parser(struct dive *dive, device_data_t *data, unsigned
|
|||
report_error("Error parsing the dive header data. Dive # %d: %s", dive->number, errmsg(rc));
|
||||
}
|
||||
}
|
||||
rc = dc_parser_samples_foreach (parser, sample_cb, &dive->dc);
|
||||
rc = dc_parser_samples_foreach (parser, sample_cb, &dive->dcs[0]);
|
||||
if (rc != DC_STATUS_SUCCESS) {
|
||||
report_error("Error parsing the sample data. Dive # %d: %s", dive->number, errmsg(rc));
|
||||
dc_parser_destroy (parser);
|
||||
|
|
|
@ -143,7 +143,7 @@ static void parse_dives(int log_version, const unsigned char *buf, unsigned int
|
|||
int i;
|
||||
auto dive = std::make_unique<struct dive>();
|
||||
memset(&sensor_ids, 0, sizeof(sensor_ids));
|
||||
dc = &dive->dc;
|
||||
dc = &dive->dcs[0];
|
||||
|
||||
/* Just the main cylinder until we can handle the buddy cylinder porperly */
|
||||
for (i = 0; i < 1; i++) {
|
||||
|
|
|
@ -1643,15 +1643,12 @@ static git_blob *git_tree_entry_blob(git_repository *repo, const git_tree_entry
|
|||
|
||||
static struct divecomputer *create_new_dc(struct dive *dive)
|
||||
{
|
||||
struct divecomputer *dc = &dive->dc;
|
||||
struct divecomputer *dc = &dive->dcs.back();
|
||||
|
||||
while (dc->next)
|
||||
dc = dc->next;
|
||||
/* Did we already fill that in? */
|
||||
if (!dc->samples.empty() || !dc->model.empty() || dc->when) {
|
||||
struct divecomputer *newdc = new divecomputer;
|
||||
dc->next = newdc;
|
||||
dc = newdc;
|
||||
dive->dcs.emplace_back();
|
||||
dc = &dive->dcs.back();
|
||||
}
|
||||
dc->when = dive->when;
|
||||
dc->duration = dive->duration;
|
||||
|
|
|
@ -152,7 +152,7 @@ void ostctools_import(const char *file, struct divelog *log)
|
|||
return;
|
||||
}
|
||||
std::string tmp = devdata.vendor + " " + devdata.model + " (Imported from OSTCTools)";
|
||||
ostcdive->dc.model = tmp.c_str();
|
||||
ostcdive->dcs[0].model = tmp;
|
||||
|
||||
// Parse the dive data
|
||||
rc = libdc_buffer_parser(ostcdive.get(), &devdata, buffer.data(), i + 1);
|
||||
|
@ -161,14 +161,14 @@ void ostctools_import(const char *file, struct divelog *log)
|
|||
|
||||
// Serial number is not part of the header nor the profile, so libdc won't
|
||||
// catch it. If Serial is part of the extra_data, and set to zero, replace it.
|
||||
ostcdive->dc.serial = std::to_string(serial);
|
||||
ostcdive->dcs[0].serial = std::to_string(serial);
|
||||
|
||||
auto it = find_if(ostcdive->dc.extra_data.begin(), ostcdive->dc.extra_data.end(),
|
||||
auto it = find_if(ostcdive->dcs[0].extra_data.begin(), ostcdive->dcs[0].extra_data.end(),
|
||||
[](auto &ed) { return ed.key == "Serial"; });
|
||||
if (it != ostcdive->dc.extra_data.end() && it->value == "0")
|
||||
it->value = ostcdive->dc.serial.c_str();
|
||||
else if (it == ostcdive->dc.extra_data.end())
|
||||
add_extra_data(&ostcdive->dc, "Serial", ostcdive->dc.serial);
|
||||
if (it != ostcdive->dcs[0].extra_data.end() && it->value == "0")
|
||||
it->value = ostcdive->dcs[0].serial.c_str();
|
||||
else if (it == ostcdive->dcs[0].extra_data.end())
|
||||
add_extra_data(&ostcdive->dcs[0], "Serial", ostcdive->dcs[0].serial);
|
||||
|
||||
record_dive_to_table(ostcdive.release(), log->dives.get());
|
||||
sort_dive_table(log->dives.get());
|
||||
|
|
|
@ -1014,9 +1014,9 @@ static int divinglog_dive_match(struct dive *dive, const char *name, char *buf,
|
|||
}
|
||||
return MATCH_STATE("divedate", divedate, &dive->when) ||
|
||||
MATCH_STATE("entrytime", divetime, &dive->when) ||
|
||||
MATCH("divetime", duration, &dive->dc.duration) ||
|
||||
MATCH_STATE("depth", depth, &dive->dc.maxdepth) ||
|
||||
MATCH_STATE("depthavg", depth, &dive->dc.meandepth) ||
|
||||
MATCH("divetime", duration, &dive->dcs[0].duration) ||
|
||||
MATCH_STATE("depth", depth, &dive->dcs[0].maxdepth) ||
|
||||
MATCH_STATE("depthavg", depth, &dive->dcs[0].meandepth) ||
|
||||
MATCH("comments", utf8_string, &dive->notes) ||
|
||||
MATCH("names.buddy", utf8_string, &dive->buddy) ||
|
||||
MATCH("name.country", utf8_string_std, &state->country) ||
|
||||
|
@ -1082,8 +1082,8 @@ uddf_datedata(min, 0)
|
|||
static int uddf_dive_match(struct dive *dive, const char *name, char *buf, struct parser_state *state)
|
||||
{
|
||||
return MATCH_STATE("datetime", uddf_datetime, &dive->when) ||
|
||||
MATCH("diveduration", duration, &dive->dc.duration) ||
|
||||
MATCH_STATE("greatestdepth", depth, &dive->dc.maxdepth) ||
|
||||
MATCH("diveduration", duration, &dive->dcs[0].duration) ||
|
||||
MATCH_STATE("greatestdepth", depth, &dive->dcs[0].maxdepth) ||
|
||||
MATCH_STATE("year.date", uddf_year, &dive->when) ||
|
||||
MATCH_STATE("month.date", uddf_mon, &dive->when) ||
|
||||
MATCH_STATE("day.date", uddf_mday, &dive->when) ||
|
||||
|
@ -1269,7 +1269,7 @@ static void try_to_fill_dive(struct dive *dive, const char *name, char *buf, str
|
|||
* Legacy format note: per-dive depths and duration get saved
|
||||
* in the first dive computer entry
|
||||
*/
|
||||
if (match_dc_data_fields(&dive->dc, name, buf, state))
|
||||
if (match_dc_data_fields(&dive->dcs[0], name, buf, state))
|
||||
return;
|
||||
|
||||
if (MATCH("filename.picture", utf8_string, &state->cur_picture.filename))
|
||||
|
|
|
@ -34,7 +34,7 @@ parser_state::~parser_state()
|
|||
*/
|
||||
struct divecomputer *get_dc(struct parser_state *state)
|
||||
{
|
||||
return state->cur_dc ?: &state->cur_dive->dc;
|
||||
return state->cur_dc ?: &state->cur_dive->dcs[0];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -118,7 +118,7 @@ void event_end(struct parser_state *state)
|
|||
bool is_dive(struct parser_state *state)
|
||||
{
|
||||
return state->cur_dive &&
|
||||
(state->cur_dive->dive_site || state->cur_dive->when || !state->cur_dive->dc.samples.empty());
|
||||
(state->cur_dive->dive_site || state->cur_dive->when || !state->cur_dive->dcs[0].samples.empty());
|
||||
}
|
||||
|
||||
void reset_dc_info(struct divecomputer *, struct parser_state *state)
|
||||
|
@ -264,7 +264,7 @@ void dive_start(struct parser_state *state)
|
|||
if (state->cur_dive)
|
||||
return;
|
||||
state->cur_dive = std::make_unique<dive>();
|
||||
reset_dc_info(&state->cur_dive->dc, state);
|
||||
reset_dc_info(&state->cur_dive->dcs[0], state);
|
||||
memset(&state->cur_tm, 0, sizeof(state->cur_tm));
|
||||
state->o2pressure_sensor = 1;
|
||||
}
|
||||
|
@ -383,20 +383,12 @@ void sample_end(struct parser_state *state)
|
|||
|
||||
void divecomputer_start(struct parser_state *state)
|
||||
{
|
||||
struct divecomputer *dc;
|
||||
|
||||
/* Start from the previous dive computer */
|
||||
dc = &state->cur_dive->dc;
|
||||
while (dc->next)
|
||||
dc = dc->next;
|
||||
struct divecomputer *dc = &state->cur_dive->dcs.back();
|
||||
|
||||
/* Did we already fill that in? */
|
||||
if (!dc->samples.empty() || !dc->model.empty() || dc->when) {
|
||||
struct divecomputer *newdc = new divecomputer;
|
||||
if (newdc) {
|
||||
dc->next = newdc;
|
||||
dc = newdc;
|
||||
}
|
||||
state->cur_dive->dcs.emplace_back();
|
||||
dc = &state->cur_dive->dcs.back();
|
||||
}
|
||||
|
||||
/* .. this is the one we'll use */
|
||||
|
|
|
@ -128,7 +128,7 @@ static int tissue_at_end(struct deco_state *ds, struct dive *dive, const struct
|
|||
return 0;
|
||||
|
||||
const struct sample *psample = nullptr;
|
||||
divemode_loop loop(dive->dc);
|
||||
divemode_loop loop(*dc);
|
||||
for (auto &sample: dc->samples) {
|
||||
o2pressure_t setpoint = psample ? psample->setpoint
|
||||
: sample.setpoint;
|
||||
|
@ -809,7 +809,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
plan_add_segment(diveplan, clock - previous_point_time, 0, current_cylinder, po2, false, divemode);
|
||||
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
||||
add_plan_to_notes(diveplan, dive, show_disclaimer, error);
|
||||
fixup_dc_duration(dc);
|
||||
fixup_dc_duration(*dc);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1091,7 +1091,7 @@ bool plan(struct deco_state *ds, struct diveplan *diveplan, struct dive *dive, i
|
|||
}
|
||||
create_dive_from_plan(diveplan, dive, dc, is_planner);
|
||||
add_plan_to_notes(diveplan, dive, show_disclaimer, error);
|
||||
fixup_dc_duration(dc);
|
||||
fixup_dc_duration(*dc);
|
||||
|
||||
return decodive;
|
||||
}
|
||||
|
|
|
@ -452,7 +452,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
|
|||
|
||||
/* Print the gas consumption next.*/
|
||||
std::string temp;
|
||||
if (dive->dc.divemode == CCR)
|
||||
if (dive->dcs[0].divemode == CCR)
|
||||
temp = translate("gettextFromC", "Gas consumption (CCR legs excluded):");
|
||||
else
|
||||
temp = casprintf_loc("%s %.*f|%.*f%s/min):", translate("gettextFromC", "Gas consumption (based on SAC"),
|
||||
|
@ -497,7 +497,7 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
|
|||
/* not for recreational mode and if no other warning was set before. */
|
||||
else
|
||||
if (lastbottomdp && gasidx == lastbottomdp->cylinderid
|
||||
&& dive->dc.divemode == OC && decoMode(true) != RECREATIONAL) {
|
||||
&& dive->dcs[0].divemode == OC && decoMode(true) != RECREATIONAL) {
|
||||
/* Calculate minimum gas volume. */
|
||||
volume_t mingasv;
|
||||
mingasv.mliter = lrint(prefs.sacfactor / 100.0 * prefs.problemsolvingtime * prefs.bottomsac
|
||||
|
@ -573,8 +573,8 @@ void add_plan_to_notes(struct diveplan *diveplan, struct dive *dive, bool show_d
|
|||
bool o2warning_exist = false;
|
||||
double amb;
|
||||
|
||||
divemode_loop loop(dive->dc);
|
||||
if (dive->dc.divemode != CCR) {
|
||||
divemode_loop loop(dive->dcs[0]);
|
||||
if (dive->dcs[0].divemode != CCR) {
|
||||
while (dp) {
|
||||
if (dp->time != 0) {
|
||||
std::string temp;
|
||||
|
|
|
@ -251,7 +251,6 @@ static void check_setpoint_events(const struct dive *, const struct divecomputer
|
|||
|
||||
static void calculate_max_limits_new(const struct dive *dive, const struct divecomputer *given_dc, struct plot_info &pi, bool in_planner)
|
||||
{
|
||||
const struct divecomputer *dc = &(dive->dc);
|
||||
bool seen = false;
|
||||
bool found_sample_beyond_last_event = false;
|
||||
int maxdepth = dive->maxdepth.mm;
|
||||
|
@ -272,17 +271,14 @@ static void calculate_max_limits_new(const struct dive *dive, const struct divec
|
|||
minpressure = mbar_end;
|
||||
}
|
||||
|
||||
/* Then do all the samples from all the dive computers */
|
||||
do {
|
||||
if (dc == given_dc)
|
||||
seen = true;
|
||||
auto process_dc = [&] (const divecomputer &dc) {
|
||||
int lastdepth = 0;
|
||||
|
||||
/* Make sure we can fit all events */
|
||||
if (!dc->events.empty())
|
||||
maxtime = std::max(maxtime, dc->events.back().time.seconds);
|
||||
if (!dc.events.empty())
|
||||
maxtime = std::max(maxtime, dc.events.back().time.seconds);
|
||||
|
||||
for (auto &s: dc->samples) {
|
||||
for (auto &s: dc.samples) {
|
||||
int depth = s.depth.mm;
|
||||
int temperature = s.temperature.mkelvin;
|
||||
int heartbeat = s.heartbeat;
|
||||
|
@ -317,13 +313,16 @@ static void calculate_max_limits_new(const struct dive *dive, const struct divec
|
|||
}
|
||||
lastdepth = depth;
|
||||
}
|
||||
};
|
||||
|
||||
dc = dc->next;
|
||||
if (dc == NULL && !seen) {
|
||||
dc = given_dc;
|
||||
/* Then do all the samples from all the dive computers */
|
||||
for (auto &dc: dive->dcs) {
|
||||
if (&dc == given_dc)
|
||||
seen = true;
|
||||
}
|
||||
} while (dc != NULL);
|
||||
process_dc(dc);
|
||||
}
|
||||
if (!seen)
|
||||
process_dc(*given_dc);
|
||||
|
||||
if (minpressure > maxpressure)
|
||||
minpressure = 0;
|
||||
|
@ -659,7 +658,7 @@ static void calculate_sac(const struct dive *dive, const struct divecomputer *dc
|
|||
}
|
||||
}
|
||||
|
||||
static void populate_secondary_sensor_data(const struct divecomputer *dc, struct plot_info &pi)
|
||||
static void populate_secondary_sensor_data(const struct divecomputer &dc, struct plot_info &pi)
|
||||
{
|
||||
std::vector<int> seen(pi.nr_cylinders, 0);
|
||||
for (int idx = 0; idx < pi.nr; ++idx)
|
||||
|
@ -668,7 +667,7 @@ static void populate_secondary_sensor_data(const struct divecomputer *dc, struct
|
|||
++seen[c]; // Count instances so we can differentiate a real sensor from just start and end pressure
|
||||
int idx = 0;
|
||||
/* We should try to see if it has interesting pressure data here */
|
||||
for (const auto &sample: dc->samples) {
|
||||
for (const auto &sample: dc.samples) {
|
||||
if (idx >= pi.nr)
|
||||
break;
|
||||
for (; idx < pi.nr; ++idx) {
|
||||
|
@ -708,7 +707,6 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive
|
|||
std::vector<int> seen(num_cyl, 0);
|
||||
std::vector<int> first(num_cyl, 0);
|
||||
std::vector<int> last(num_cyl, INT_MAX);
|
||||
const struct divecomputer *secondary;
|
||||
|
||||
int prev = explicit_first_cylinder(dive, dc);
|
||||
prev = prev >= 0 ? prev : 0;
|
||||
|
@ -761,8 +759,8 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive
|
|||
continue;
|
||||
|
||||
/* If it's only mentioned by other dc's, ignore it */
|
||||
for_each_dc(dive, secondary) {
|
||||
if (has_gaschange_event(dive, secondary, i)) {
|
||||
for (auto &secondary: dive->dcs) {
|
||||
if (has_gaschange_event(dive, &secondary, i)) {
|
||||
seen[i] = -1;
|
||||
break;
|
||||
}
|
||||
|
@ -783,12 +781,11 @@ static void setup_gas_sensor_pressure(const struct dive *dive, const struct dive
|
|||
* and try to see if they have sensor data different from the
|
||||
* current dive computer (dc).
|
||||
*/
|
||||
secondary = &dive->dc;
|
||||
do {
|
||||
if (secondary == dc)
|
||||
for (auto &secondary: dive->dcs) {
|
||||
if (&secondary == dc)
|
||||
continue;
|
||||
populate_secondary_sensor_data(secondary, pi);
|
||||
} while ((secondary = secondary->next) != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* calculate DECO STOP / TTS / NDL */
|
||||
|
@ -1001,7 +998,7 @@ static void calculate_deco_information(struct deco_state *ds, const struct deco_
|
|||
if (in_planner && !pi.waypoint_above_ceiling &&
|
||||
entry.depth < max_ceiling - 100 && entry.sec > 0) {
|
||||
struct dive *non_const_dive = (struct dive *)dive; // cast away const!
|
||||
add_event(&non_const_dive->dc, entry.sec, SAMPLE_EVENT_CEILING, -1, max_ceiling / 1000,
|
||||
add_event(&non_const_dive->dcs[0], entry.sec, SAMPLE_EVENT_CEILING, -1, max_ceiling / 1000,
|
||||
translate("gettextFromC", "planned waypoint above ceiling"));
|
||||
pi.waypoint_above_ceiling = true;
|
||||
}
|
||||
|
@ -1292,7 +1289,7 @@ struct plot_info create_plot_info_new(const struct dive *dive, const struct dive
|
|||
debug_print_profiledata(pi);
|
||||
#endif
|
||||
|
||||
pi.meandepth = dive->dc.meandepth.mm;
|
||||
pi.meandepth = dive->dcs[0].meandepth.mm;
|
||||
analyze_plot_info(pi);
|
||||
return pi;
|
||||
}
|
||||
|
|
|
@ -119,9 +119,9 @@ static void save_tags(struct membuffer *b, struct tag_entry *tags)
|
|||
put_string(b, "\n");
|
||||
}
|
||||
|
||||
static void save_extra_data(struct membuffer *b, const struct divecomputer *dc)
|
||||
static void save_extra_data(struct membuffer *b, const struct divecomputer &dc)
|
||||
{
|
||||
for (const auto &ed: dc->extra_data) {
|
||||
for (const auto &ed: dc.extra_data) {
|
||||
if (!ed.key.empty() && !ed.value.empty())
|
||||
put_format(b, "keyvalue \"%s\" \"%s\"\n", ed.key.c_str(), ed.value.c_str());
|
||||
}
|
||||
|
@ -186,34 +186,34 @@ static void save_weightsystem_info(struct membuffer *b, struct dive *dive)
|
|||
|
||||
static void save_dive_temperature(struct membuffer *b, struct dive *dive)
|
||||
{
|
||||
if (dive->airtemp.mkelvin != dc_airtemp(&dive->dc))
|
||||
if (dive->airtemp.mkelvin != dc_airtemp(dive).mkelvin)
|
||||
put_temperature(b, dive->airtemp, "airtemp ", "°C\n");
|
||||
if (dive->watertemp.mkelvin != dc_watertemp(&dive->dc))
|
||||
if (dive->watertemp.mkelvin != dc_watertemp(dive).mkelvin)
|
||||
put_temperature(b, dive->watertemp, "watertemp ", "°C\n");
|
||||
}
|
||||
|
||||
static void save_depths(struct membuffer *b, struct divecomputer *dc)
|
||||
static void save_depths(struct membuffer *b, const struct divecomputer &dc)
|
||||
{
|
||||
put_depth(b, dc->maxdepth, "maxdepth ", "m\n");
|
||||
put_depth(b, dc->meandepth, "meandepth ", "m\n");
|
||||
put_depth(b, dc.maxdepth, "maxdepth ", "m\n");
|
||||
put_depth(b, dc.meandepth, "meandepth ", "m\n");
|
||||
}
|
||||
|
||||
static void save_temperatures(struct membuffer *b, struct divecomputer *dc)
|
||||
static void save_temperatures(struct membuffer *b, const struct divecomputer &dc)
|
||||
{
|
||||
put_temperature(b, dc->airtemp, "airtemp ", "°C\n");
|
||||
put_temperature(b, dc->watertemp, "watertemp ", "°C\n");
|
||||
put_temperature(b, dc.airtemp, "airtemp ", "°C\n");
|
||||
put_temperature(b, dc.watertemp, "watertemp ", "°C\n");
|
||||
}
|
||||
|
||||
static void save_airpressure(struct membuffer *b, struct divecomputer *dc)
|
||||
static void save_airpressure(struct membuffer *b, const struct divecomputer &dc)
|
||||
{
|
||||
put_pressure(b, dc->surface_pressure, "surfacepressure ", "bar\n");
|
||||
put_pressure(b, dc.surface_pressure, "surfacepressure ", "bar\n");
|
||||
}
|
||||
|
||||
static void save_salinity(struct membuffer *b, struct divecomputer *dc)
|
||||
static void save_salinity(struct membuffer *b, const struct divecomputer &dc)
|
||||
{
|
||||
if (!dc->salinity)
|
||||
if (!dc.salinity)
|
||||
return;
|
||||
put_salinity(b, dc->salinity, "salinity ", "g/l\n");
|
||||
put_salinity(b, dc.salinity, "salinity ", "g/l\n");
|
||||
}
|
||||
|
||||
static void show_date(struct membuffer *b, timestamp_t when)
|
||||
|
@ -367,19 +367,19 @@ static void save_sample(struct membuffer *b, const struct sample &sample, struct
|
|||
put_format(b, "\n");
|
||||
}
|
||||
|
||||
static void save_samples(struct membuffer *b, struct dive *dive, struct divecomputer *dc)
|
||||
static void save_samples(struct membuffer *b, struct dive *dive, const struct divecomputer &dc)
|
||||
{
|
||||
int o2sensor;
|
||||
struct sample dummy;
|
||||
|
||||
/* Is this a CCR dive with the old-style "o2pressure" sensor? */
|
||||
o2sensor = legacy_format_o2pressures(dive, dc);
|
||||
o2sensor = legacy_format_o2pressures(dive, &dc);
|
||||
if (o2sensor >= 0) {
|
||||
dummy.sensor[0] = !o2sensor;
|
||||
dummy.sensor[1] = o2sensor;
|
||||
}
|
||||
|
||||
for (const auto &s: dc->samples)
|
||||
for (const auto &s: dc.samples)
|
||||
save_sample(b, s, dummy, o2sensor);
|
||||
}
|
||||
|
||||
|
@ -403,35 +403,35 @@ static void save_one_event(struct membuffer *b, struct dive *dive, const struct
|
|||
put_string(b, "\n");
|
||||
}
|
||||
|
||||
static void save_events(struct membuffer *b, struct dive *dive, const struct divecomputer *dc)
|
||||
static void save_events(struct membuffer *b, struct dive *dive, const struct divecomputer &dc)
|
||||
{
|
||||
for (auto &ev: dc->events)
|
||||
for (auto &ev: dc.events)
|
||||
save_one_event(b, dive, ev);
|
||||
}
|
||||
|
||||
static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer *dc)
|
||||
static void save_dc(struct membuffer *b, struct dive *dive, const struct divecomputer &dc)
|
||||
{
|
||||
show_utf8(b, "model ", dc->model.c_str(), "\n");
|
||||
if (dc->last_manual_time.seconds)
|
||||
put_duration(b, dc->last_manual_time, "lastmanualtime ", "min\n");
|
||||
if (dc->deviceid)
|
||||
put_format(b, "deviceid %08x\n", dc->deviceid);
|
||||
if (dc->diveid)
|
||||
put_format(b, "diveid %08x\n", dc->diveid);
|
||||
if (dc->when && dc->when != dive->when)
|
||||
show_date(b, dc->when);
|
||||
if (dc->duration.seconds && dc->duration.seconds != dive->dc.duration.seconds)
|
||||
put_duration(b, dc->duration, "duration ", "min\n");
|
||||
if (dc->divemode != OC) {
|
||||
put_format(b, "dctype %s\n", divemode_text[dc->divemode]);
|
||||
put_format(b, "numberofoxygensensors %d\n",dc->no_o2sensors);
|
||||
show_utf8(b, "model ", dc.model.c_str(), "\n");
|
||||
if (dc.last_manual_time.seconds)
|
||||
put_duration(b, dc.last_manual_time, "lastmanualtime ", "min\n");
|
||||
if (dc.deviceid)
|
||||
put_format(b, "deviceid %08x\n", dc.deviceid);
|
||||
if (dc.diveid)
|
||||
put_format(b, "diveid %08x\n", dc.diveid);
|
||||
if (dc.when && dc.when != dive->when)
|
||||
show_date(b, dc.when);
|
||||
if (dc.duration.seconds && dc.duration.seconds != dive->dcs[0].duration.seconds)
|
||||
put_duration(b, dc.duration, "duration ", "min\n");
|
||||
if (dc.divemode != OC) {
|
||||
put_format(b, "dctype %s\n", divemode_text[dc.divemode]);
|
||||
put_format(b, "numberofoxygensensors %d\n", dc.no_o2sensors);
|
||||
}
|
||||
|
||||
save_depths(b, dc);
|
||||
save_temperatures(b, dc);
|
||||
save_airpressure(b, dc);
|
||||
save_salinity(b, dc);
|
||||
put_duration(b, dc->surfacetime, "surfacetime ", "min\n");
|
||||
put_duration(b, dc.surfacetime, "surfacetime ", "min\n");
|
||||
|
||||
save_extra_data(b, dc);
|
||||
save_events(b, dive, dc);
|
||||
|
@ -445,8 +445,8 @@ static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer
|
|||
static void create_dive_buffer(struct dive *dive, struct membuffer *b)
|
||||
{
|
||||
pressure_t surface_pressure = un_fixup_surface_pressure(dive);
|
||||
if (dive->dc.duration.seconds > 0)
|
||||
put_format(b, "duration %u:%02u min\n", FRACTION_TUPLE(dive->dc.duration.seconds, 60));
|
||||
if (dive->dcs[0].duration.seconds > 0)
|
||||
put_format(b, "duration %u:%02u min\n", FRACTION_TUPLE(dive->dcs[0].duration.seconds, 60));
|
||||
SAVE("rating", rating);
|
||||
SAVE("visibility", visibility);
|
||||
SAVE("wavesize", wavesize);
|
||||
|
@ -611,7 +611,7 @@ static int blob_insert(git_repository *repo, struct dir *tree, struct membuffer
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int save_one_divecomputer(git_repository *repo, struct dir *tree, struct dive *dive, struct divecomputer *dc, int idx)
|
||||
static int save_one_divecomputer(git_repository *repo, struct dir *tree, struct dive *dive, const struct divecomputer &dc, int idx)
|
||||
{
|
||||
int ret;
|
||||
membuffer buf;
|
||||
|
@ -659,7 +659,6 @@ static int save_pictures(git_repository *repo, struct dir *dir, struct dive *div
|
|||
|
||||
static int save_one_dive(git_repository *repo, struct dir *tree, struct dive *dive, struct tm *tm, bool cached_ok)
|
||||
{
|
||||
struct divecomputer *dc;
|
||||
membuffer buf, name;
|
||||
struct dir *subdir;
|
||||
int ret, nr;
|
||||
|
@ -696,12 +695,9 @@ static int save_one_dive(git_repository *repo, struct dir *tree, struct dive *di
|
|||
* computer, use index 0 for that (which disables the index
|
||||
* generation when naming it).
|
||||
*/
|
||||
dc = &dive->dc;
|
||||
nr = dc->next ? 1 : 0;
|
||||
do {
|
||||
nr = dive->dcs.size() > 1 ? 1 : 0;
|
||||
for (auto &dc: dive->dcs)
|
||||
save_one_divecomputer(repo, subdir, dive, dc, nr++);
|
||||
dc = dc->next;
|
||||
} while (dc);
|
||||
|
||||
/* Save the picture data, if any */
|
||||
save_pictures(repo, subdir, dive);
|
||||
|
@ -1132,7 +1128,6 @@ static void create_commit_message(struct membuffer *msg, bool create_empty)
|
|||
std::string location = get_dive_location(dive);
|
||||
if (location.empty())
|
||||
location = "no location";
|
||||
struct divecomputer *dc = &dive->dc;
|
||||
const char *sep = "\n";
|
||||
|
||||
if (dive->number)
|
||||
|
@ -1142,12 +1137,12 @@ static void create_commit_message(struct membuffer *msg, bool create_empty)
|
|||
if (trip && !empty_string(trip->location) && location != trip->location)
|
||||
put_format(msg, " (%s)", trip->location);
|
||||
put_format(msg, "\n");
|
||||
do {
|
||||
if (!dc->model.empty()) {
|
||||
put_format(msg, "%s%s", sep, dc->model.c_str());
|
||||
for (auto &dc: dive->dcs) {
|
||||
if (!dc.model.empty()) {
|
||||
put_format(msg, "%s%s", sep, dc.model.c_str());
|
||||
sep = ", ";
|
||||
}
|
||||
} while ((dc = dc->next) != NULL);
|
||||
}
|
||||
put_format(msg, "\n");
|
||||
}
|
||||
put_format(msg, "Created by %s\n", subsurface_user_agent().c_str());
|
||||
|
|
|
@ -52,19 +52,18 @@ static void save_photos(struct membuffer *b, const char *photos_dir, const struc
|
|||
static void write_divecomputers(struct membuffer *b, const struct dive *dive)
|
||||
{
|
||||
put_string(b, "\"divecomputers\":[");
|
||||
const struct divecomputer *dc;
|
||||
const char *separator = "";
|
||||
for_each_dc (dive, dc) {
|
||||
for (auto &dc: dive->dcs) {
|
||||
put_string(b, separator);
|
||||
separator = ", ";
|
||||
put_format(b, "{");
|
||||
write_attribute(b, "model", dc->model.c_str(), ", ");
|
||||
if (dc->deviceid)
|
||||
put_format(b, "\"deviceid\":\"%08x\", ", dc->deviceid);
|
||||
write_attribute(b, "model", dc.model.c_str(), ", ");
|
||||
if (dc.deviceid)
|
||||
put_format(b, "\"deviceid\":\"%08x\", ", dc.deviceid);
|
||||
else
|
||||
put_string(b, "\"deviceid\":\"--\", ");
|
||||
if (dc->diveid)
|
||||
put_format(b, "\"diveid\":\"%08x\" ", dc->diveid);
|
||||
if (dc.diveid)
|
||||
put_format(b, "\"diveid\":\"%08x\" ", dc.diveid);
|
||||
else
|
||||
put_string(b, "\"diveid\":\"--\" ");
|
||||
put_format(b, "}");
|
||||
|
@ -82,7 +81,7 @@ static void write_dive_status(struct membuffer *b, const struct dive *dive)
|
|||
static void put_HTML_bookmarks(struct membuffer *b, const struct dive *dive)
|
||||
{
|
||||
const char *separator = "\"events\":[";
|
||||
for (const auto &ev: dive->dc.events) {
|
||||
for (const auto &ev: dive->dcs[0].events) {
|
||||
put_string(b, separator);
|
||||
separator = ", ";
|
||||
put_string(b, "{\"name\":\"");
|
||||
|
@ -172,14 +171,14 @@ static void put_cylinder_HTML(struct membuffer *b, const struct dive *dive)
|
|||
|
||||
static void put_HTML_samples(struct membuffer *b, const struct dive *dive)
|
||||
{
|
||||
put_format(b, "\"maxdepth\":%d,", dive->dc.maxdepth.mm);
|
||||
put_format(b, "\"duration\":%d,", dive->dc.duration.seconds);
|
||||
put_format(b, "\"maxdepth\":%d,", dive->dcs[0].maxdepth.mm);
|
||||
put_format(b, "\"duration\":%d,", dive->dcs[0].duration.seconds);
|
||||
|
||||
if (dive->dc.samples.empty())
|
||||
if (dive->dcs[0].samples.empty())
|
||||
return;
|
||||
|
||||
const char *separator = "\"samples\":[";
|
||||
for (auto &s: dive->dc.samples) {
|
||||
for (auto &s: dive->dcs[0].samples) {
|
||||
put_format(b, "%s[%d,%d,%d,%d]", separator, s.time.seconds, s.depth.mm, s.pressure[0].mbar, s.temperature.mkelvin);
|
||||
separator = ", ";
|
||||
}
|
||||
|
|
|
@ -210,7 +210,7 @@ static void save_profiles_buffer(struct membuffer *b, bool select_only)
|
|||
for_each_dive(i, dive) {
|
||||
if (select_only && !dive->selected)
|
||||
continue;
|
||||
plot_info pi = create_plot_info_new(dive, &dive->dc, planner_deco_state);
|
||||
plot_info pi = create_plot_info_new(dive, &dive->dcs[0], planner_deco_state);
|
||||
put_headers(b, pi.nr_cylinders);
|
||||
|
||||
for (int i = 0; i < pi.nr; i++)
|
||||
|
@ -223,7 +223,7 @@ void save_subtitles_buffer(struct membuffer *b, struct dive *dive, int offset, i
|
|||
{
|
||||
struct deco_state *planner_deco_state = NULL;
|
||||
|
||||
plot_info pi = create_plot_info_new(dive, &dive->dc, planner_deco_state);
|
||||
plot_info pi = create_plot_info_new(dive, &dive->dcs[0], planner_deco_state);
|
||||
|
||||
put_format(b, "[Script Info]\n");
|
||||
put_format(b, "; Script generated by Subsurface %s\n", subsurface_canonical_version());
|
||||
|
|
|
@ -116,13 +116,13 @@ static void save_dive_temperature(struct membuffer *b, struct dive *dive)
|
|||
{
|
||||
if (!dive->airtemp.mkelvin && !dive->watertemp.mkelvin)
|
||||
return;
|
||||
if (dive->airtemp.mkelvin == dc_airtemp(&dive->dc) && dive->watertemp.mkelvin == dc_watertemp(&dive->dc))
|
||||
if (dive->airtemp.mkelvin == dc_airtemp(dive).mkelvin && dive->watertemp.mkelvin == dc_watertemp(dive).mkelvin)
|
||||
return;
|
||||
|
||||
put_string(b, " <divetemperature");
|
||||
if (dive->airtemp.mkelvin != dc_airtemp(&dive->dc))
|
||||
if (dive->airtemp.mkelvin != dc_airtemp(dive).mkelvin)
|
||||
put_temperature(b, dive->airtemp, " air='", " C'");
|
||||
if (dive->watertemp.mkelvin != dc_watertemp(&dive->dc))
|
||||
if (dive->watertemp.mkelvin != dc_watertemp(dive).mkelvin)
|
||||
put_temperature(b, dive->watertemp, " water='", " C'");
|
||||
put_string(b, "/>\n");
|
||||
}
|
||||
|
@ -447,7 +447,7 @@ static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer
|
|||
put_format(b, " diveid='%08x'", dc->diveid);
|
||||
if (dc->when && dc->when != dive->when)
|
||||
show_date(b, dc->when);
|
||||
if (dc->duration.seconds && dc->duration.seconds != dive->dc.duration.seconds)
|
||||
if (dc->duration.seconds && dc->duration.seconds != dive->dcs[0].duration.seconds)
|
||||
put_duration(b, dc->duration, " duration='", " min'");
|
||||
if (dc->divemode != OC) {
|
||||
int i = (int)dc->divemode;
|
||||
|
@ -490,7 +490,6 @@ static void save_picture(struct membuffer *b, struct picture *pic)
|
|||
|
||||
void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize)
|
||||
{
|
||||
struct divecomputer *dc;
|
||||
pressure_t surface_pressure = un_fixup_surface_pressure(dive);
|
||||
|
||||
put_string(b, "<dive");
|
||||
|
@ -530,9 +529,9 @@ void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize)
|
|||
show_date(b, dive->when);
|
||||
if (surface_pressure.mbar)
|
||||
put_pressure(b, surface_pressure, " airpressure='", " bar'");
|
||||
if (dive->dc.duration.seconds > 0)
|
||||
if (dive->dcs[0].duration.seconds > 0)
|
||||
put_format(b, " duration='%u:%02u min'>\n",
|
||||
FRACTION_TUPLE(dive->dc.duration.seconds, 60));
|
||||
FRACTION_TUPLE(dive->dcs[0].duration.seconds, 60));
|
||||
else
|
||||
put_format(b, ">\n");
|
||||
save_overview(b, dive, anonymize);
|
||||
|
@ -540,8 +539,8 @@ void save_one_dive_to_mb(struct membuffer *b, struct dive *dive, bool anonymize)
|
|||
save_weightsystem_info(b, dive);
|
||||
save_dive_temperature(b, dive);
|
||||
/* Save the dive computer data */
|
||||
for_each_dc(dive, dc)
|
||||
save_dc(b, dive, dc);
|
||||
for (auto &dc: dive->dcs)
|
||||
save_dc(b, dive, &dc);
|
||||
FOR_EACH_PICTURE(dive)
|
||||
save_picture(b, picture);
|
||||
put_format(b, "</dive>\n");
|
||||
|
|
|
@ -151,8 +151,8 @@ stats_summary calculate_stats_summary(bool selected_only)
|
|||
out.stats_by_type[0].selection_size++;
|
||||
process_dive(dp, out.stats_by_type[0]);
|
||||
|
||||
process_dive(dp, out.stats_by_type[dp->dc.divemode + 1]);
|
||||
out.stats_by_type[dp->dc.divemode + 1].selection_size++;
|
||||
process_dive(dp, out.stats_by_type[dp->dcs[0].divemode + 1]);
|
||||
out.stats_by_type[dp->dcs[0].divemode + 1].selection_size++;
|
||||
|
||||
/* stats_by_depth[0] is all the dives combined */
|
||||
out.stats_by_depth[0].selection_size++;
|
||||
|
@ -273,7 +273,6 @@ bool has_gaschange_event(const struct dive *dive, const struct divecomputer *dc,
|
|||
|
||||
bool is_cylinder_used(const struct dive *dive, int idx)
|
||||
{
|
||||
const struct divecomputer *dc;
|
||||
cylinder_t *cyl;
|
||||
if (idx < 0 || idx >= dive->cylinders.nr)
|
||||
return false;
|
||||
|
@ -285,10 +284,10 @@ bool is_cylinder_used(const struct dive *dive, int idx)
|
|||
if ((cyl->sample_start.mbar - cyl->sample_end.mbar) > SOME_GAS)
|
||||
return true;
|
||||
|
||||
for_each_dc(dive, dc) {
|
||||
if (has_gaschange_event(dive, dc, idx))
|
||||
for (auto &dc: dive->dcs) {
|
||||
if (has_gaschange_event(dive, &dc, idx))
|
||||
return true;
|
||||
else if (dc->divemode == CCR && idx == get_cylinder_idx_by_use(dive, OXYGEN))
|
||||
else if (dc.divemode == CCR && idx == get_cylinder_idx_by_use(dive, OXYGEN))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -296,15 +295,12 @@ bool is_cylinder_used(const struct dive *dive, int idx)
|
|||
|
||||
bool is_cylinder_prot(const struct dive *dive, int idx)
|
||||
{
|
||||
const struct divecomputer *dc;
|
||||
if (idx < 0 || idx >= dive->cylinders.nr)
|
||||
return false;
|
||||
|
||||
for_each_dc(dive, dc) {
|
||||
if (has_gaschange_event(dive, dc, idx))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return std::any_of(dive->dcs.begin(), dive->dcs.end(),
|
||||
[dive, idx](auto &dc)
|
||||
{ return has_gaschange_event(dive, &dc, idx); });
|
||||
}
|
||||
|
||||
/* Returns a vector with dive->cylinders.nr entries */
|
||||
|
|
|
@ -45,7 +45,7 @@ QString formatSac(const dive *d)
|
|||
QString formatNotes(const dive *d)
|
||||
{
|
||||
QString tmp = d->notes ? QString::fromUtf8(d->notes) : QString();
|
||||
if (is_dc_planner(&d->dc)) {
|
||||
if (is_dc_planner(&d->dcs[0])) {
|
||||
QTextDocument notes;
|
||||
#define _NOTES_BR "\n"
|
||||
tmp.replace("<thead>", "<thead>" _NOTES_BR)
|
||||
|
|
|
@ -188,15 +188,15 @@ static void uemis_get_weight(std::string_view buffer, weightsystem_t &weight, in
|
|||
static std::unique_ptr<dive> uemis_start_dive(uint32_t deviceid)
|
||||
{
|
||||
auto dive = std::make_unique<struct dive>();
|
||||
dive->dc.model = "Uemis Zurich";
|
||||
dive->dc.deviceid = deviceid;
|
||||
dive->dcs[0].model = "Uemis Zurich";
|
||||
dive->dcs[0].deviceid = deviceid;
|
||||
return dive;
|
||||
}
|
||||
|
||||
static struct dive *get_dive_by_uemis_diveid(device_data_t *devdata, uint32_t object_id)
|
||||
{
|
||||
for (int i = 0; i < devdata->log->dives->nr; i++) {
|
||||
if (object_id == devdata->log->dives->dives[i]->dc.diveid)
|
||||
if (object_id == devdata->log->dives->dives[i]->dcs[0].diveid)
|
||||
return devdata->log->dives->dives[i];
|
||||
}
|
||||
return NULL;
|
||||
|
@ -732,21 +732,21 @@ static void parse_tag(struct dive *dive, std::string_view tag, std::string_view
|
|||
* with the binary data and would just get overwritten */
|
||||
#if UEMIS_DEBUG & 4
|
||||
if (tag == "file_content")
|
||||
report_info("Adding to dive %d : %s = %s\n", dive->dc.diveid, std::string(tag).c_str(), std::string(val).c_str());
|
||||
report_info("Adding to dive %d : %s = %s\n", dive->dcs[0].diveid, std::string(tag).c_str(), std::string(val).c_str());
|
||||
#endif
|
||||
if (tag == "date") {
|
||||
dive->when = uemis_ts(val);
|
||||
} else if (tag == "duration") {
|
||||
uemis_duration(val, dive->dc.duration);
|
||||
uemis_duration(val, dive->dcs[0].duration);
|
||||
} else if (tag == "depth") {
|
||||
uemis_depth(val, dive->dc.maxdepth);
|
||||
uemis_depth(val, dive->dcs[0].maxdepth);
|
||||
} else if (tag == "file_content") {
|
||||
uemis_obj.parse_divelog_binary(val, dive);
|
||||
} else if (tag == "altitude") {
|
||||
uemis_get_index(val, dive->dc.surface_pressure.mbar);
|
||||
uemis_get_index(val, dive->dcs[0].surface_pressure.mbar);
|
||||
} else if (tag == "f32Weight") {
|
||||
weightsystem_t ws = empty_weightsystem;
|
||||
uemis_get_weight(val, ws, dive->dc.diveid);
|
||||
uemis_get_weight(val, ws, dive->dcs[0].diveid);
|
||||
add_cloned_weightsystem(&dive->weightsystems, ws);
|
||||
} else if (tag == "notes") {
|
||||
uemis_add_string(val, &dive->notes, " ");
|
||||
|
@ -774,12 +774,12 @@ static bool uemis_delete_dive(device_data_t *devdata, uint32_t diveid)
|
|||
{
|
||||
struct dive *dive = NULL;
|
||||
|
||||
if (devdata->log->dives->dives[devdata->log->dives->nr - 1]->dc.diveid == diveid) {
|
||||
if (devdata->log->dives->dives[devdata->log->dives->nr - 1]->dcs[0].diveid == diveid) {
|
||||
/* we hit the last one in the array */
|
||||
dive = devdata->log->dives->dives[devdata->log->dives->nr - 1];
|
||||
} else {
|
||||
for (int i = 0; i < devdata->log->dives->nr - 1; i++) {
|
||||
if (devdata->log->dives->dives[i]->dc.diveid == diveid) {
|
||||
if (devdata->log->dives->dives[i]->dcs[0].diveid == diveid) {
|
||||
dive = devdata->log->dives->dives[i];
|
||||
for (int x = i; x < devdata->log->dives->nr - 1; x++)
|
||||
devdata->log->dives->dives[i] = devdata->log->dives->dives[x + 1];
|
||||
|
@ -902,7 +902,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
|
|||
// Is log
|
||||
if (tag == "object_id") {
|
||||
from_chars(val, max_divenr);
|
||||
owned_dive->dc.diveid = max_divenr;
|
||||
owned_dive->dcs[0].diveid = max_divenr;
|
||||
#if UEMIS_DEBUG % 2
|
||||
report_info("Adding new dive from log with object_id %d.\n", max_divenr);
|
||||
#endif
|
||||
|
@ -940,10 +940,10 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
|
|||
struct dive_site *ds = devdata->log->sites->create("from Uemis"s);
|
||||
unregister_dive_from_dive_site(non_owned_dive);
|
||||
ds->add_dive(non_owned_dive);
|
||||
uemis_obj.mark_divelocation(non_owned_dive->dc.diveid, divespot_id, ds);
|
||||
uemis_obj.mark_divelocation(non_owned_dive->dcs[0].diveid, divespot_id, ds);
|
||||
}
|
||||
#if UEMIS_DEBUG & 2
|
||||
report_info("Created divesite %d for diveid : %d\n", non_owned_dive->dive_site->uuid, non_owned_dive->dc.diveid);
|
||||
report_info("Created divesite %d for diveid : %d\n", non_owned_dive->dive_site->uuid, non_owned_dive->dcs[0].diveid);
|
||||
#endif
|
||||
} else if (non_owned_dive) {
|
||||
parse_tag(non_owned_dive, tag, val);
|
||||
|
@ -951,7 +951,7 @@ static bool process_raw_buffer(device_data_t *devdata, uint32_t deviceid, std::s
|
|||
}
|
||||
}
|
||||
if (is_log) {
|
||||
if (owned_dive->dc.diveid)
|
||||
if (owned_dive->dcs[0].diveid)
|
||||
record_dive_to_table(owned_dive.release(), devdata->log->dives.get());
|
||||
else /* partial dive */
|
||||
return false;
|
||||
|
@ -981,16 +981,15 @@ static std::pair<uint32_t, uint32_t> uemis_get_divenr(uint32_t deviceid, struct
|
|||
|
||||
for (i = 0; i < table->nr; i++) {
|
||||
struct dive *d = table->dives[i];
|
||||
struct divecomputer *dc;
|
||||
if (!d)
|
||||
continue;
|
||||
for_each_dc (d, dc) {
|
||||
if (dc->model == "Uemis Zurich" &&
|
||||
(dc->deviceid == 0 || dc->deviceid == 0x7fffffff || dc->deviceid == deviceid)) {
|
||||
if (dc->diveid > maxdiveid)
|
||||
maxdiveid = dc->diveid;
|
||||
if (dc->diveid < mindiveid)
|
||||
mindiveid = dc->diveid;
|
||||
for (auto &dc: d->dcs) {
|
||||
if (dc.model == "Uemis Zurich" &&
|
||||
(dc.deviceid == 0 || dc.deviceid == 0x7fffffff || dc.deviceid == deviceid)) {
|
||||
if (dc.diveid > maxdiveid)
|
||||
maxdiveid = dc.diveid;
|
||||
if (dc.diveid < mindiveid)
|
||||
mindiveid = dc.diveid;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1144,9 +1143,9 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
|
|||
int deleted_files = 0;
|
||||
int fail_count = 0;
|
||||
|
||||
snprintf(log_file_no_to_find, sizeof(log_file_no_to_find), "logfilenr{int{%d", dive->dc.diveid);
|
||||
snprintf(log_file_no_to_find, sizeof(log_file_no_to_find), "logfilenr{int{%d", dive->dcs[0].diveid);
|
||||
#if UEMIS_DEBUG & 2
|
||||
report_info("Looking for dive details to go with dive log id %d\n", dive->dc.diveid);
|
||||
report_info("Looking for dive details to go with dive log id %d\n", dive->dcs[0].diveid);
|
||||
#endif
|
||||
while (!found) {
|
||||
if (import_thread_cancelled)
|
||||
|
@ -1176,9 +1175,9 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
|
|||
* UEMIS unfortunately deletes dives by deleting the dive details and not the logs. */
|
||||
#if UEMIS_DEBUG & 2
|
||||
d_time = get_dive_date_c_string(dive->when);
|
||||
report_info("Matching dive log id %d from %s with dive details %d\n", dive->dc.diveid, d_time.c_str(), dive_to_read);
|
||||
report_info("Matching dive log id %d from %s with dive details %d\n", dive->dcs[0].diveid, d_time.c_str(), dive_to_read);
|
||||
#endif
|
||||
int divespot_id = uemis_obj.get_divespot_id_by_diveid(dive->dc.diveid);
|
||||
int divespot_id = uemis_obj.get_divespot_id_by_diveid(dive->dcs[0].diveid);
|
||||
if (divespot_id >= 0)
|
||||
get_uemis_divespot(data, mountpath, divespot_id, dive);
|
||||
|
||||
|
@ -1186,13 +1185,13 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
|
|||
/* in this case we found a deleted file, so let's increment */
|
||||
#if UEMIS_DEBUG & 2
|
||||
d_time = get_dive_date_c_string(dive->when);
|
||||
report_info("TRY matching dive log id %d from %s with dive details %d but details are deleted\n", dive->dc.diveid, d_time.c_str(), dive_to_read);
|
||||
report_info("TRY matching dive log id %d from %s with dive details %d but details are deleted\n", dive->dcs[0].diveid, d_time.c_str(), dive_to_read);
|
||||
#endif
|
||||
deleted_files++;
|
||||
/* mark this log entry as deleted and cleanup later, otherwise we mess up our array */
|
||||
dive->hidden_by_filter = true;
|
||||
#if UEMIS_DEBUG & 2
|
||||
report_info("Deleted dive from %s, with id %d from table -- newmax is %d\n", d_time.c_str(), dive->dc.diveid, newmax);
|
||||
report_info("Deleted dive from %s, with id %d from table -- newmax is %d\n", d_time.c_str(), dive->dcs[0].diveid, newmax);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
|
@ -1200,7 +1199,7 @@ static bool get_matching_dive(int idx, int &newmax, uemis_mem_status &mem_status
|
|||
size_t pos = mbuf.find("logfilenr");
|
||||
if (pos != std::string::npos && mbuf.find("act{") != std::string::npos) {
|
||||
sscanf(mbuf.c_str() + pos, "logfilenr{int{%u", &nr_found);
|
||||
if (nr_found >= dive->dc.diveid || nr_found == 0) {
|
||||
if (nr_found >= dive->dcs[0].diveid || nr_found == 0) {
|
||||
found_above = true;
|
||||
dive_to_read = dive_to_read - 2;
|
||||
} else {
|
||||
|
@ -1433,7 +1432,7 @@ std::string do_uemis_import(device_data_t *data)
|
|||
* to see if we have to clean some dead bodies from our download table */
|
||||
for (int next_table_index = 0; next_table_index < data->log->dives->nr; ) {
|
||||
if (data->log->dives->dives[next_table_index]->hidden_by_filter)
|
||||
uemis_delete_dive(data, data->log->dives->dives[next_table_index]->dc.diveid);
|
||||
uemis_delete_dive(data, data->log->dives->dives[next_table_index]->dcs[0].diveid);
|
||||
else
|
||||
next_table_index++;
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ void uemis::event(struct dive *dive, struct divecomputer *dc, struct sample *sam
|
|||
}
|
||||
#if UEMIS_DEBUG & 32
|
||||
printf("%dm:%ds: p_amb_tol:%d surface:%d holdtime:%d holddepth:%d/%d ---> stopdepth:%d stoptime:%d ndl:%d\n",
|
||||
sample->time.seconds / 60, sample->time.seconds % 60, u_sample->p_amb_tol, dive->dc.surface_pressure.mbar,
|
||||
sample->time.seconds / 60, sample->time.seconds % 60, u_sample->p_amb_tol, dive->dcs[0].surface_pressure.mbar,
|
||||
u_sample->hold_time, u_sample->hold_depth, stopdepth, sample->stopdepth.mm, sample->stoptime.seconds, sample->ndl.seconds);
|
||||
#endif
|
||||
}
|
||||
|
@ -283,17 +283,17 @@ void uemis::parse_divelog_binary(std::string_view base64, struct dive *dive)
|
|||
{
|
||||
struct sample *sample = NULL;
|
||||
uemis_sample *u_sample;
|
||||
struct divecomputer *dc = &dive->dc;
|
||||
struct divecomputer *dc = &dive->dcs[0];
|
||||
int dive_template, gasoffset;
|
||||
uint8_t active = 0;
|
||||
|
||||
auto data = convert_base64(base64);
|
||||
dive->dc.airtemp.mkelvin = C_to_mkelvin((*(uint16_t *)(data.data() + 45)) / 10.0);
|
||||
dive->dc.surface_pressure.mbar = *(uint16_t *)(data.data() + 43);
|
||||
dive->dcs[0].airtemp.mkelvin = C_to_mkelvin((*(uint16_t *)(data.data() + 45)) / 10.0);
|
||||
dive->dcs[0].surface_pressure.mbar = *(uint16_t *)(data.data() + 43);
|
||||
if (*(uint8_t *)(data.data() + 19))
|
||||
dive->dc.salinity = SEAWATER_SALINITY; /* avg grams per 10l sea water */
|
||||
dive->dcs[0].salinity = SEAWATER_SALINITY; /* avg grams per 10l sea water */
|
||||
else
|
||||
dive->dc.salinity = FRESHWATER_SALINITY; /* grams per 10l fresh water */
|
||||
dive->dcs[0].salinity = FRESHWATER_SALINITY; /* grams per 10l fresh water */
|
||||
|
||||
/* this will allow us to find the last dive read so far from this computer */
|
||||
dc->model = "Uemis Zurich";
|
||||
|
@ -353,7 +353,7 @@ void uemis::parse_divelog_binary(std::string_view base64, struct dive *dive)
|
|||
u_sample++;
|
||||
}
|
||||
if (sample)
|
||||
dive->dc.duration.seconds = sample->time.seconds - 1;
|
||||
dive->dcs[0].duration.seconds = sample->time.seconds - 1;
|
||||
|
||||
/* get data from the footer */
|
||||
add_extra_data(dc, "FW Version",
|
||||
|
|
|
@ -563,7 +563,7 @@ int PlannerWidgets::getDcNr()
|
|||
|
||||
divemode_t PlannerWidgets::getRebreatherMode() const
|
||||
{
|
||||
return get_dive_dc_const(planned_dive.get(), dcNr)->divemode;
|
||||
return get_dive_dc(planned_dive.get(), 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_const(currentDive, currentDcNr)->divemode);
|
||||
plannerSettingsWidget.setBailoutVisibility(get_dive_dc_const(currentDive, currentDcNr)->divemode);
|
||||
plannerSettingsWidget.setDiveMode(get_dive_dc(currentDive, currentDcNr)->divemode);
|
||||
plannerSettingsWidget.setBailoutVisibility(get_dive_dc(currentDive, currentDcNr)->divemode);
|
||||
if (currentDive->salinity)
|
||||
plannerWidget.setSalinity(currentDive->salinity);
|
||||
else // No salinity means salt water
|
||||
|
|
|
@ -705,11 +705,11 @@ void MainWindow::on_actionAddDive_triggered()
|
|||
struct dive d;
|
||||
d.id = dive_getUniqID();
|
||||
d.when = QDateTime::currentMSecsSinceEpoch() / 1000L + gettimezoneoffset() + 3600;
|
||||
d.dc.duration.seconds = 40 * 60;
|
||||
d.dc.maxdepth.mm = M_OR_FT(15, 45);
|
||||
d.dc.meandepth.mm = M_OR_FT(13, 39); // this creates a resonable looking safety stop
|
||||
make_manually_added_dive_dc(&d.dc);
|
||||
fake_dc(&d.dc);
|
||||
d.dcs[0].duration.seconds = 40 * 60;
|
||||
d.dcs[0].maxdepth.mm = M_OR_FT(15, 45);
|
||||
d.dcs[0].meandepth.mm = M_OR_FT(13, 39); // this creates a resonable looking safety stop
|
||||
make_manually_added_dive_dc(&d.dcs[0]);
|
||||
fake_dc(&d.dcs[0]);
|
||||
add_default_cylinder(&d);
|
||||
fixup_dive(&d);
|
||||
|
||||
|
|
|
@ -167,7 +167,7 @@ void ProfileWidget::setDive(const struct dive *d, int dcNr)
|
|||
{
|
||||
stack->setCurrentIndex(1); // show profile
|
||||
|
||||
bool freeDiveMode = get_dive_dc_const(d, dcNr)->divemode == FREEDIVE;
|
||||
bool freeDiveMode = get_dive_dc(d, dcNr)->divemode == FREEDIVE;
|
||||
ui.profCalcCeiling->setDisabled(freeDiveMode);
|
||||
ui.profCalcCeiling->setDisabled(freeDiveMode);
|
||||
ui.profCalcAllTissues ->setDisabled(freeDiveMode);
|
||||
|
|
|
@ -152,9 +152,9 @@ void TabDiveInformation::updateProfile()
|
|||
ui->oxygenHeliumText->setText(gaslist);
|
||||
|
||||
ui->diveTimeText->setText(get_dive_duration_string(currentDive->duration.seconds, tr("h"), tr("min"), tr("sec"),
|
||||
" ", currentDive->dc.divemode == FREEDIVE));
|
||||
" ", currentDive->dcs[0].divemode == FREEDIVE));
|
||||
|
||||
ui->sacText->setText(currentDive->cylinders.nr > 0 && mean[0] && currentDive->dc.divemode != CCR ? std::move(SACs) : QString());
|
||||
ui->sacText->setText(currentDive->cylinders.nr > 0 && mean[0] && currentDive->dcs[0].divemode != CCR ? std::move(SACs) : QString());
|
||||
|
||||
if (currentDive->surface_pressure.mbar == 0) {
|
||||
ui->atmPressVal->clear(); // If no atm pressure for dive then clear text box
|
||||
|
|
|
@ -254,7 +254,7 @@ void TabDiveNotes::updateData(const std::vector<dive *> &, dive *currentDive, in
|
|||
ui.LocationLabel->setText(tr("Location"));
|
||||
ui.NotesLabel->setText(tr("Notes"));
|
||||
ui.tagWidget->setText(QString::fromStdString(taglist_get_tagstring(currentDive->tag_list)));
|
||||
bool isManual = is_dc_manually_added_dive(¤tDive->dc);
|
||||
bool isManual = is_dc_manually_added_dive(¤tDive->dcs[0]);
|
||||
ui.depth->setVisible(isManual);
|
||||
ui.depthLabel->setVisible(isManual);
|
||||
ui.duration->setVisible(isManual);
|
||||
|
|
|
@ -108,7 +108,7 @@ void TabDiveStatistics::updateData(const std::vector<dive *> &, dive *currentDiv
|
|||
}
|
||||
|
||||
|
||||
bool is_freedive = currentDive && currentDive->dc.divemode == FREEDIVE;
|
||||
bool is_freedive = currentDive && currentDive->dcs[0].divemode == FREEDIVE;
|
||||
ui->divesAllText->setText(QString::number(stats_selection.selection_size));
|
||||
ui->totalTimeAllText->setText(get_dive_duration_string(stats_selection.total_time.seconds, tr("h"), tr("min"), tr("sec"), " ", is_freedive));
|
||||
|
||||
|
|
|
@ -534,11 +534,11 @@ QVariant TemplateLayout::getValue(QString list, QString property, const State &s
|
|||
} else if (property == "duration") {
|
||||
return formatDiveDuration(d);
|
||||
} else if (property == "noDive") {
|
||||
return d->duration.seconds == 0 && d->dc.duration.seconds == 0;
|
||||
return d->duration.seconds == 0 && d->dcs[0].duration.seconds == 0;
|
||||
} else if (property == "depth") {
|
||||
return get_depth_string(d->dc.maxdepth.mm, true, true);
|
||||
return get_depth_string(d->dcs[0].maxdepth.mm, true, true);
|
||||
} else if (property == "meandepth") {
|
||||
return get_depth_string(d->dc.meandepth.mm, true, true);
|
||||
return get_depth_string(d->dcs[0].meandepth.mm, true, true);
|
||||
} else if (property == "divemaster") {
|
||||
return d->diveguide;
|
||||
} else if (property == "diveguide") {
|
||||
|
|
|
@ -1056,7 +1056,7 @@ parsed:
|
|||
// add a hundred years.
|
||||
if (newDate.addYears(100) < QDateTime::currentDateTime().addYears(1))
|
||||
newDate = newDate.addYears(100);
|
||||
d->dc.when = d->when = dateTimeToTimestamp(newDate);
|
||||
d->dcs[0].when = d->when = dateTimeToTimestamp(newDate);
|
||||
return true;
|
||||
}
|
||||
appendTextToLog("none of our parsing attempts worked for the date string");
|
||||
|
@ -1134,9 +1134,9 @@ bool QMLManager::checkDuration(struct dive *d, QString duration)
|
|||
} else if (m6.hasMatch()) {
|
||||
m = m6.captured(1).toInt();
|
||||
}
|
||||
d->dc.duration.seconds = d->duration.seconds = h * 3600 + m * 60 + s;
|
||||
if (is_dc_manually_added_dive(&d->dc))
|
||||
d->dc.samples.clear();
|
||||
d->dcs[0].duration.seconds = d->duration.seconds = h * 3600 + m * 60 + s;
|
||||
if (is_dc_manually_added_dive(&d->dcs[0]))
|
||||
d->dcs[0].samples.clear();
|
||||
else
|
||||
appendTextToLog("Cannot change the duration on a dive that wasn't manually added");
|
||||
return true;
|
||||
|
@ -1146,16 +1146,16 @@ bool QMLManager::checkDuration(struct dive *d, QString duration)
|
|||
|
||||
bool QMLManager::checkDepth(dive *d, QString depth)
|
||||
{
|
||||
if (get_depth_string(d->dc.maxdepth.mm, true, true) != depth) {
|
||||
if (get_depth_string(d->dcs[0].maxdepth.mm, true, true) != depth) {
|
||||
int depthValue = parseLengthToMm(depth);
|
||||
// the QML code should stop negative depth, but massively huge depth can make
|
||||
// the profile extremely slow or even run out of memory and crash, so keep
|
||||
// the depth <= 500m
|
||||
if (0 <= depthValue && depthValue <= 500000) {
|
||||
d->maxdepth.mm = depthValue;
|
||||
if (is_dc_manually_added_dive(&d->dc)) {
|
||||
d->dc.maxdepth.mm = d->maxdepth.mm;
|
||||
d->dc.samples.clear();
|
||||
if (is_dc_manually_added_dive(&d->dcs[0])) {
|
||||
d->dcs[0].maxdepth.mm = d->maxdepth.mm;
|
||||
d->dcs[0].samples.clear();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1356,16 +1356,16 @@ void QMLManager::commitChanges(QString diveId, QString number, QString date, QSt
|
|||
// now that we have it all figured out, let's see what we need
|
||||
// to update
|
||||
if (diveChanged) {
|
||||
if (d->maxdepth.mm == d->dc.maxdepth.mm &&
|
||||
if (d->maxdepth.mm == d->dcs[0].maxdepth.mm &&
|
||||
d->maxdepth.mm > 0 &&
|
||||
is_dc_manually_added_dive(&d->dc) &&
|
||||
d->dc.samples.empty()) {
|
||||
is_dc_manually_added_dive(&d->dcs[0]) &&
|
||||
d->dcs[0].samples.empty()) {
|
||||
// so we have depth > 0, a manually added dive and no samples
|
||||
// let's create an actual profile so the desktop version can work it
|
||||
// first clear out the mean depth (or the fake_dc() function tries
|
||||
// to be too clever)
|
||||
d->meandepth.mm = d->dc.meandepth.mm = 0;
|
||||
fake_dc(&d->dc);
|
||||
d->meandepth.mm = d->dcs[0].meandepth.mm = 0;
|
||||
fake_dc(&d->dcs[0]);
|
||||
}
|
||||
fixup_dive(d);
|
||||
Command::editDive(orig, d_ptr.release(), dsChange.createdDs.release(), dsChange.editDs, dsChange.location); // With release() we're giving up ownership
|
||||
|
@ -1732,11 +1732,11 @@ int QMLManager::addDive()
|
|||
struct dive d;
|
||||
int diveId = d.id = dive_getUniqID();
|
||||
d.when = QDateTime::currentMSecsSinceEpoch() / 1000L + gettimezoneoffset() + 3600;
|
||||
d.dc.duration.seconds = 40 * 60;
|
||||
d.dc.maxdepth.mm = M_OR_FT(15, 45);
|
||||
d.dc.meandepth.mm = M_OR_FT(13, 39); // this creates a resonable looking safety stop
|
||||
make_manually_added_dive_dc(&d.dc);
|
||||
fake_dc(&d.dc);
|
||||
d.dcs[0].duration.seconds = 40 * 60;
|
||||
d.dcs[0].maxdepth.mm = M_OR_FT(15, 45);
|
||||
d.dcs[0].meandepth.mm = M_OR_FT(13, 39); // this creates a resonable looking safety stop
|
||||
make_manually_added_dive_dc(&d.dcs[0]);
|
||||
fake_dc(&d.dcs[0]);
|
||||
fixup_dive(&d);
|
||||
|
||||
// addDive takes over the dive and clears out the structure passed in
|
||||
|
|
|
@ -213,7 +213,7 @@ 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_const(d, dc);
|
||||
const struct divecomputer *currentdc = get_dive_dc(d, dc);
|
||||
if (!currentdc)
|
||||
return;
|
||||
bool ppGraphs = ppGraphsEnabled(currentdc, simplified);
|
||||
|
@ -291,7 +291,7 @@ struct VerticalAxisLayout {
|
|||
|
||||
void ProfileScene::updateAxes(bool diveHasHeartBeat, bool simplified)
|
||||
{
|
||||
const struct divecomputer *currentdc = get_dive_dc_const(d, dc);
|
||||
const struct divecomputer *currentdc = get_dive_dc(d, dc);
|
||||
if (!currentdc)
|
||||
return;
|
||||
|
||||
|
@ -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_const(d, dc);
|
||||
const struct divecomputer *currentdc = get_dive_dc(d, dc);
|
||||
if (!currentdc || currentdc->samples.empty()) {
|
||||
clear();
|
||||
return;
|
||||
|
|
|
@ -534,7 +534,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_const(d, dc);
|
||||
const struct divecomputer *currentdc = get_dive_dc(d, dc);
|
||||
if (!currentdc->deviceid && dc == 0 && number_of_computers(d) == 1)
|
||||
// nothing to do, can't rename, delete or reorder
|
||||
return;
|
||||
|
@ -580,7 +580,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_const(d, dc));
|
||||
divemode_loop loop(*get_dive_dc(d, dc));
|
||||
divemode_t divemode = loop.next(seconds);
|
||||
QMenu *changeMode = m.addMenu(tr("Change divemode"));
|
||||
if (divemode != OC)
|
||||
|
@ -648,7 +648,7 @@ void ProfileWidget2::contextMenuEvent(QContextMenuEvent *event)
|
|||
}
|
||||
m2->addAction(tr("All event types"), this, &ProfileWidget2::unhideEventTypes);
|
||||
}
|
||||
const struct divecomputer *currentdc = get_dive_dc_const(d, dc);
|
||||
const struct divecomputer *currentdc = get_dive_dc(d, 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);
|
||||
|
|
|
@ -401,7 +401,7 @@ bool CylindersModel::setData(const QModelIndex &index, const QVariant &value, in
|
|||
if (get_o2(cyl.gasmix) + get_he(cyl.gasmix) > 1000)
|
||||
cyl.gasmix.he.permille = 1000 - get_o2(cyl.gasmix);
|
||||
pressure_t modpO2;
|
||||
if (d->dc.divemode == PSCR)
|
||||
if (d->dcs[0].divemode == PSCR)
|
||||
modpO2.mbar = prefs.decopo2 + (1000 - get_o2(cyl.gasmix)) * SURFACE_PRESSURE *
|
||||
prefs.o2consumption / prefs.decosac / prefs.pscr_ratio;
|
||||
else
|
||||
|
|
|
@ -70,7 +70,7 @@ void DivePlannerPointsModel::createSimpleDive(struct dive *dIn)
|
|||
clear_dive(d);
|
||||
d->id = dive_getUniqID();
|
||||
d->when = QDateTime::currentMSecsSinceEpoch() / 1000L + gettimezoneoffset() + 3600;
|
||||
make_planner_dc(&d->dc);
|
||||
make_planner_dc(&d->dcs[0]);
|
||||
|
||||
clear();
|
||||
removeDeco();
|
||||
|
@ -818,7 +818,7 @@ int DivePlannerPointsModel::addStop(int milimeters, int seconds, int cylinderid_
|
|||
}
|
||||
}
|
||||
if (divemode == UNDEF_COMP_TYPE)
|
||||
divemode = get_dive_dc_const(d, dcNr)->divemode;
|
||||
divemode = get_dive_dc(d, dcNr)->divemode;
|
||||
|
||||
// add the new stop
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
|
|
|
@ -116,7 +116,7 @@ Stats::Stats() :
|
|||
|
||||
static void calculateDive(struct dive *dive, Stats &stats)
|
||||
{
|
||||
if (is_dc_planner(&dive->dc)) {
|
||||
if (is_dc_planner(&dive->dcs[0])) {
|
||||
stats.diveplans++;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -162,9 +162,9 @@ static int countPhotos(const struct dive *d)
|
|||
static QString displayDuration(const struct dive *d)
|
||||
{
|
||||
if (prefs.units.show_units_table)
|
||||
return get_dive_duration_string(d->duration.seconds, gettextFromC::tr("h"), gettextFromC::tr("min"), "", ":", d->dc.divemode == FREEDIVE);
|
||||
return get_dive_duration_string(d->duration.seconds, gettextFromC::tr("h"), gettextFromC::tr("min"), "", ":", d->dcs[0].divemode == FREEDIVE);
|
||||
else
|
||||
return get_dive_duration_string(d->duration.seconds, "", "", "", ":", d->dc.divemode == FREEDIVE);
|
||||
return get_dive_duration_string(d->duration.seconds, "", "", "", ":", d->dcs[0].divemode == FREEDIVE);
|
||||
}
|
||||
|
||||
static QString displayTemperature(const struct dive *d, bool units)
|
||||
|
@ -281,9 +281,9 @@ QVariant DiveTripModelBase::diveData(const struct dive *d, int column, int role)
|
|||
case MobileListModel::IdRole: return d->id;
|
||||
case MobileListModel::NumberRole: return d->number;
|
||||
case MobileListModel::LocationRole: return QString::fromStdString(get_dive_location(d));
|
||||
case MobileListModel::DepthRole: return get_depth_string(d->dc.maxdepth.mm, true, true);
|
||||
case MobileListModel::DepthRole: return get_depth_string(d->dcs[0].maxdepth.mm, true, true);
|
||||
case MobileListModel::DurationRole: return formatDiveDuration(d);
|
||||
case MobileListModel::DepthDurationRole: return QStringLiteral("%1 / %2").arg(get_depth_string(d->dc.maxdepth.mm, true, true),
|
||||
case MobileListModel::DepthDurationRole: return QStringLiteral("%1 / %2").arg(get_depth_string(d->dcs[0].maxdepth.mm, true, true),
|
||||
formatDiveDuration(d));
|
||||
case MobileListModel::RatingRole: return d->rating;
|
||||
case MobileListModel::VizRole: return d->visibility;
|
||||
|
@ -298,7 +298,7 @@ QVariant DiveTripModelBase::diveData(const struct dive *d, int column, int role)
|
|||
case MobileListModel::NotesRole: return formatNotes(d);
|
||||
case MobileListModel::GpsRole: return formatDiveGPS(d);
|
||||
case MobileListModel::GpsDecimalRole: return format_gps_decimal(d);
|
||||
case MobileListModel::NoDiveRole: return d->duration.seconds == 0 && d->dc.duration.seconds == 0;
|
||||
case MobileListModel::NoDiveRole: return d->duration.seconds == 0 && d->dcs[0].duration.seconds == 0;
|
||||
case MobileListModel::DiveSiteRole: return QVariant::fromValue(d->dive_site);
|
||||
case MobileListModel::CylinderRole: return formatGetCylinder(d).join(", ");
|
||||
case MobileListModel::GetCylinderRole: return formatGetCylinder(d);
|
||||
|
@ -363,7 +363,7 @@ QVariant DiveTripModelBase::diveData(const struct dive *d, int column, int role)
|
|||
case NOTES:
|
||||
return QString(d->notes);
|
||||
case DIVEMODE:
|
||||
return QString(divemode_text_ui[(int)d->dc.divemode]);
|
||||
return QString(divemode_text_ui[(int)d->dcs[0].divemode]);
|
||||
}
|
||||
break;
|
||||
case Qt::DecorationRole:
|
||||
|
@ -1780,6 +1780,6 @@ bool DiveTripModelList::lessThan(const QModelIndex &i1, const QModelIndex &i2) c
|
|||
case NOTES:
|
||||
return lessThanHelper(strCmp(d1->notes, d2->notes), row_diff);
|
||||
case DIVEMODE:
|
||||
return lessThanHelper((int)d1->dc.divemode - (int)d2->dc.divemode, row_diff);
|
||||
return lessThanHelper((int)d1->dcs[0].divemode - (int)d2->dcs[0].divemode, row_diff);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -696,9 +696,9 @@ static void smtk_parse_relations(MdbHandle *mdb, struct dive *dive, char *dive_i
|
|||
else
|
||||
concat(tmp, ", ", str);
|
||||
if (str.find("SCR") != std::string::npos)
|
||||
dive->dc.divemode = PSCR;
|
||||
dive->dcs[0].divemode = PSCR;
|
||||
else if (str.find("CCR") != std::string::npos)
|
||||
dive->dc.divemode = CCR;
|
||||
dive->dcs[0].divemode = CCR;
|
||||
}
|
||||
if (!tmp.empty())
|
||||
concat(&dive->notes, "\n", format_string_std("Smartrak %s: %s", table_name, tmp.c_str()));
|
||||
|
@ -759,11 +759,11 @@ static void smtk_parse_bookmarks(MdbHandle *mdb, struct dive *d, char *dive_idx)
|
|||
if (same_string(table.get_data(0), dive_idx)) {
|
||||
time = lrint(strtod(table.get_data(4), NULL) * 60);
|
||||
const char *tmp = table.get_data(2);
|
||||
ev = find_bookmark(d->dc, time);
|
||||
ev = find_bookmark(d->dcs[0], time);
|
||||
if (ev)
|
||||
ev->name = tmp;
|
||||
else
|
||||
if (!add_event(&d->dc, time, SAMPLE_EVENT_BOOKMARK, 0, 0, tmp))
|
||||
if (!add_event(&d->dcs[0], time, SAMPLE_EVENT_BOOKMARK, 0, 0, tmp))
|
||||
report_error("[smtk-import] Error - Couldn't add bookmark, dive %d, Name = %s",
|
||||
d->number, tmp);
|
||||
}
|
||||
|
@ -941,7 +941,7 @@ void smartrak_import(const char *file, struct divelog *log)
|
|||
dc_fam = DC_FAMILY_UWATEC_ALADIN;
|
||||
}
|
||||
rc = prepare_data(dc_model, (char *)col[coln(DCNUMBER)]->bind_ptr, dc_fam, devdata);
|
||||
smtkdive->dc.model = devdata.model;
|
||||
smtkdive->dcs[0].model = devdata.model;
|
||||
if (rc == DC_STATUS_SUCCESS && mdb_table.get_len(coln(PROFILE))) {
|
||||
prf_buffer = static_cast<unsigned char *>(mdb_ole_read_full(mdb, col[coln(PROFILE)], &prf_length));
|
||||
if (prf_length > 0) {
|
||||
|
@ -959,16 +959,16 @@ void smartrak_import(const char *file, struct divelog *log)
|
|||
} else {
|
||||
/* Dives without profile samples (usual in older aladin series) */
|
||||
report_error("[Warning][smartrak_import]\t No profile for dive %d", smtkdive->number);
|
||||
smtkdive->dc.duration.seconds = smtkdive->duration.seconds = smtk_time_to_secs((char *)col[coln(DURATION)]->bind_ptr);
|
||||
smtkdive->dc.maxdepth.mm = smtkdive->maxdepth.mm = lrint(strtod((char *)col[coln(MAXDEPTH)]->bind_ptr, NULL) * 1000);
|
||||
smtkdive->dcs[0].duration.seconds = smtkdive->duration.seconds = smtk_time_to_secs((char *)col[coln(DURATION)]->bind_ptr);
|
||||
smtkdive->dcs[0].maxdepth.mm = smtkdive->maxdepth.mm = lrint(strtod((char *)col[coln(MAXDEPTH)]->bind_ptr, NULL) * 1000);
|
||||
}
|
||||
free(hdr_buffer);
|
||||
free(prf_buffer);
|
||||
} else {
|
||||
/* Manual dives or unknown DCs */
|
||||
report_error("[Warning][smartrak_import]\t Manual or unknown dive computer for dive %d", smtkdive->number);
|
||||
smtkdive->dc.duration.seconds = smtkdive->duration.seconds = smtk_time_to_secs((char *)col[coln(DURATION)]->bind_ptr);
|
||||
smtkdive->dc.maxdepth.mm = smtkdive->maxdepth.mm = lrint(strtod((char *)col[coln(MAXDEPTH)]->bind_ptr, NULL) * 1000);
|
||||
smtkdive->dcs[0].duration.seconds = smtkdive->duration.seconds = smtk_time_to_secs((char *)col[coln(DURATION)]->bind_ptr);
|
||||
smtkdive->dcs[0].maxdepth.mm = smtkdive->maxdepth.mm = lrint(strtod((char *)col[coln(MAXDEPTH)]->bind_ptr, NULL) * 1000);
|
||||
}
|
||||
/*
|
||||
* Cylinder and gasmixes completion.
|
||||
|
@ -1009,8 +1009,8 @@ void smartrak_import(const char *file, struct divelog *log)
|
|||
/* Date issues with libdc parser - Take date time from mdb */
|
||||
smtk_date_to_tm((char *)col[coln(_DATE)]->bind_ptr, &tm_date);
|
||||
smtk_time_to_tm((char *)col[coln(INTIME)]->bind_ptr, &tm_date);
|
||||
smtkdive->dc.when = smtkdive->when = smtk_timegm(&tm_date);
|
||||
smtkdive->dc.surfacetime.seconds = smtk_time_to_secs((char *)col[coln(INTVAL)]->bind_ptr);
|
||||
smtkdive->dcs[0].when = smtkdive->when = smtk_timegm(&tm_date);
|
||||
smtkdive->dcs[0].surfacetime.seconds = smtk_time_to_secs((char *)col[coln(INTVAL)]->bind_ptr);
|
||||
|
||||
/* Data that user may have registered manually if not supported by DC, or not parsed */
|
||||
if (!smtkdive->airtemp.mkelvin)
|
||||
|
|
|
@ -1402,7 +1402,7 @@ struct DiveModeBinner : public SimpleBinner<DiveModeBinner, IntBin> {
|
|||
return QString(divemode_text_ui[derived_bin(bin).value]);
|
||||
}
|
||||
int to_bin_value(const dive *d) const {
|
||||
int res = (int)d->dc.divemode;
|
||||
int res = (int)d->dcs[0].divemode;
|
||||
return res >= 0 && res < NUM_DIVEMODE ? res : OC;
|
||||
}
|
||||
};
|
||||
|
@ -1413,7 +1413,7 @@ struct DiveModeVariable : public StatsVariableTemplate<StatsVariable::Type::Disc
|
|||
return StatsTranslations::tr("Dive mode");
|
||||
}
|
||||
QString diveCategories(const dive *d) const override {
|
||||
int mode = (int)d->dc.divemode;
|
||||
int mode = (int)d->dcs[0].divemode;
|
||||
return mode >= 0 && mode < NUM_DIVEMODE ?
|
||||
QString(divemode_text_ui[mode]) : QString();
|
||||
}
|
||||
|
|
|
@ -195,7 +195,7 @@ void TestParse::testParseHUDC()
|
|||
if (divelog.dives->nr > 0) {
|
||||
struct dive *dive = divelog.dives->dives[divelog.dives->nr - 1];
|
||||
dive->when = 1255152761;
|
||||
dive->dc.when = 1255152761;
|
||||
dive->dcs[0].when = 1255152761;
|
||||
}
|
||||
|
||||
sort_dive_table(divelog.dives);
|
||||
|
|
|
@ -496,20 +496,20 @@ void TestPlan::testMetric()
|
|||
while (!dp->minimum_gas.mbar && dp->next)
|
||||
dp = dp->next;
|
||||
QCOMPARE(lrint(dp->minimum_gas.mbar / 1000.0), 148l);
|
||||
QVERIFY(dive.dc.events.size() >= 2);
|
||||
QVERIFY(dive.dcs[0].events.size() >= 2);
|
||||
// check first gas change to EAN36 at 33m
|
||||
struct event *ev = &dive.dc.events[0];
|
||||
struct event *ev = &dive.dcs[0].events[0];
|
||||
QCOMPARE(ev->gas.index, 1);
|
||||
QCOMPARE(ev->value, 36);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 33000);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 33000);
|
||||
// check second gas change to Oxygen at 6m
|
||||
ev = &dive.dc.events[1];
|
||||
ev = &dive.dcs[0].events[1];
|
||||
QVERIFY(ev != NULL);
|
||||
QCOMPARE(ev->gas.index, 2);
|
||||
QCOMPARE(ev->value, 100);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 6000);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 6000);
|
||||
// check expected run time of 109 minutes
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 109u * 60u, 109u * 60u));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 109u * 60u, 109u * 60u));
|
||||
}
|
||||
|
||||
void TestPlan::testImperial()
|
||||
|
@ -537,21 +537,20 @@ void TestPlan::testImperial()
|
|||
while (!dp->minimum_gas.mbar && dp->next)
|
||||
dp = dp->next;
|
||||
QCOMPARE(lrint(dp->minimum_gas.mbar / 1000.0), 155l);
|
||||
QVERIFY(dive.dc.events.size() >= 2);
|
||||
QVERIFY(dive.dcs[0].events.size() >= 2);
|
||||
// check first gas change to EAN36 at 33m
|
||||
struct event *ev = &dive.dc.events[0];
|
||||
QVERIFY(ev != NULL);
|
||||
struct event *ev = &dive.dcs[0].events[0];
|
||||
QCOMPARE(ev->gas.index, 1);
|
||||
QCOMPARE(ev->value, 36);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 33528);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 33528);
|
||||
// check second gas change to Oxygen at 6m
|
||||
ev = &dive.dc.events[1];
|
||||
ev = &dive.dcs[0].events[1];
|
||||
QVERIFY(ev != NULL);
|
||||
QCOMPARE(ev->gas.index, 2);
|
||||
QCOMPARE(ev->value, 100);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 6096);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 6096);
|
||||
// check expected run time of 111 minutes
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 111u * 60u - 2u, 111u * 60u - 2u));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 111u * 60u - 2u, 111u * 60u - 2u));
|
||||
}
|
||||
|
||||
void TestPlan::testVpmbMetric45m30minTx()
|
||||
|
@ -581,7 +580,7 @@ void TestPlan::testVpmbMetric45m30minTx()
|
|||
// print first ceiling
|
||||
printf("First ceiling %.1f m\n", (mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar, &dive) * 0.001));
|
||||
// check benchmark run time of 141 minutes, and known Subsurface runtime of 139 minutes
|
||||
//QVERIFY(compareDecoTime(dive.dc.duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
||||
//QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
||||
}
|
||||
|
||||
void TestPlan::testVpmbMetric60m10minTx()
|
||||
|
@ -611,7 +610,7 @@ void TestPlan::testVpmbMetric60m10minTx()
|
|||
// print first ceiling
|
||||
printf("First ceiling %.1f m\n", (mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar, &dive) * 0.001));
|
||||
// check benchmark run time of 141 minutes, and known Subsurface runtime of 139 minutes
|
||||
//QVERIFY(compareDecoTime(dive.dc.duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
||||
//QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
||||
}
|
||||
|
||||
void TestPlan::testVpmbMetric60m30minAir()
|
||||
|
@ -641,7 +640,7 @@ void TestPlan::testVpmbMetric60m30minAir()
|
|||
// print first ceiling
|
||||
printf("First ceiling %.1f m\n", (mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar, &dive) * 0.001));
|
||||
// check benchmark run time of 141 minutes, and known Subsurface runtime of 139 minutes
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 141u * 60u + 20u, 139u * 60u + 20u));
|
||||
}
|
||||
|
||||
void TestPlan::testVpmbMetric60m30minEan50()
|
||||
|
@ -670,15 +669,14 @@ void TestPlan::testVpmbMetric60m30minEan50()
|
|||
QCOMPARE(lrint(dp->minimum_gas.mbar / 1000.0), 155l);
|
||||
// print first ceiling
|
||||
printf("First ceiling %.1f m\n", (mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar, &dive) * 0.001));
|
||||
QVERIFY(dive.dc.events.size() >= 1);
|
||||
QVERIFY(dive.dcs[0].events.size() >= 1);
|
||||
// check first gas change to EAN50 at 21m
|
||||
struct event *ev = &dive.dc.events[0];
|
||||
QVERIFY(ev != NULL);
|
||||
struct event *ev = &dive.dcs[0].events[0];
|
||||
QCOMPARE(ev->gas.index, 1);
|
||||
QCOMPARE(ev->value, 50);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 21000);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 21000);
|
||||
// check benchmark run time of 95 minutes, and known Subsurface runtime of 96 minutes
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 95u * 60u + 20u, 96u * 60u + 20u));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 95u * 60u + 20u, 96u * 60u + 20u));
|
||||
}
|
||||
|
||||
void TestPlan::testVpmbMetric60m30minTx()
|
||||
|
@ -708,14 +706,13 @@ void TestPlan::testVpmbMetric60m30minTx()
|
|||
// print first ceiling
|
||||
printf("First ceiling %.1f m\n", (mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar, &dive) * 0.001));
|
||||
// check first gas change to EAN50 at 21m
|
||||
QVERIFY(dive.dc.events.size() >= 1);
|
||||
struct event *ev = &dive.dc.events[0];
|
||||
QVERIFY(ev != NULL);
|
||||
QVERIFY(dive.dcs[0].events.size() >= 1);
|
||||
struct event *ev = &dive.dcs[0].events[0];
|
||||
QCOMPARE(ev->gas.index, 1);
|
||||
QCOMPARE(ev->value, 50);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 21000);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 21000);
|
||||
// check benchmark run time of 89 minutes, and known Subsurface runtime of 89 minutes
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 89u * 60u + 20u, 89u * 60u + 20u));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 89u * 60u + 20u, 89u * 60u + 20u));
|
||||
}
|
||||
|
||||
void TestPlan::testVpmbMetric100m60min()
|
||||
|
@ -744,21 +741,20 @@ void TestPlan::testVpmbMetric100m60min()
|
|||
QCOMPARE(lrint(dp->minimum_gas.mbar / 1000.0), 157l);
|
||||
// print first ceiling
|
||||
printf("First ceiling %.1f m\n", (mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar, &dive) * 0.001));
|
||||
QVERIFY(dive.dc.events.size() >= 2);
|
||||
QVERIFY(dive.dcs[0].events.size() >= 2);
|
||||
// check first gas change to EAN50 at 21m
|
||||
struct event *ev = &dive.dc.events[0];
|
||||
QVERIFY(ev != NULL);
|
||||
struct event *ev = &dive.dcs[0].events[0];
|
||||
QCOMPARE(ev->gas.index, 1);
|
||||
QCOMPARE(ev->value, 50);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 21000);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 21000);
|
||||
// check second gas change to Oxygen at 6m
|
||||
ev = &dive.dc.events[1];
|
||||
ev = &dive.dcs[0].events[1];
|
||||
QVERIFY(ev != NULL);
|
||||
QCOMPARE(ev->gas.index, 2);
|
||||
QCOMPARE(ev->value, 100);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 6000);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 6000);
|
||||
// check benchmark run time of 311 minutes, and known Subsurface runtime of 314 minutes
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 311u * 60u + 20u, 315u * 60u + 20u));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 311u * 60u + 20u, 315u * 60u + 20u));
|
||||
}
|
||||
|
||||
void TestPlan::testMultipleGases()
|
||||
|
@ -782,9 +778,9 @@ void TestPlan::testMultipleGases()
|
|||
#endif
|
||||
|
||||
gasmix gas;
|
||||
gas = get_gasmix_at_time(dive, dive.dc, {20 * 60 + 1});
|
||||
gas = get_gasmix_at_time(dive, dive.dcs[0], {20 * 60 + 1});
|
||||
QCOMPARE(get_o2(gas), 110);
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 2480u, 2480u));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 2480u, 2480u));
|
||||
}
|
||||
|
||||
void TestPlan::testVpmbMetricMultiLevelAir()
|
||||
|
@ -814,7 +810,7 @@ void TestPlan::testVpmbMetricMultiLevelAir()
|
|||
// print first ceiling
|
||||
printf("First ceiling %.1f m\n", (mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar, &dive) * 0.001));
|
||||
// check benchmark run time of 167 minutes, and known Subsurface runtime of 169 minutes
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 167u * 60u + 20u, 169u * 60u + 20u));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 167u * 60u + 20u, 169u * 60u + 20u));
|
||||
}
|
||||
|
||||
void TestPlan::testVpmbMetric100m10min()
|
||||
|
@ -843,21 +839,21 @@ void TestPlan::testVpmbMetric100m10min()
|
|||
QCOMPARE(lrint(dp->minimum_gas.mbar / 1000.0), 175l);
|
||||
// print first ceiling
|
||||
printf("First ceiling %.1f m\n", (mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar, &dive) * 0.001));
|
||||
QVERIFY(dive.dc.events.size() >= 2);
|
||||
QVERIFY(dive.dcs[0].events.size() >= 2);
|
||||
// check first gas change to EAN50 at 21m
|
||||
struct event *ev = &dive.dc.events[0];
|
||||
struct event *ev = &dive.dcs[0].events[0];
|
||||
QVERIFY(ev != NULL);
|
||||
QCOMPARE(ev->gas.index, 1);
|
||||
QCOMPARE(ev->value, 50);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 21000);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 21000);
|
||||
// check second gas change to Oxygen at 6m
|
||||
ev = &dive.dc.events[1];
|
||||
ev = &dive.dcs[0].events[1];
|
||||
QVERIFY(ev != NULL);
|
||||
QCOMPARE(ev->gas.index, 2);
|
||||
QCOMPARE(ev->value, 100);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 6000);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 6000);
|
||||
// check benchmark run time of 58 minutes, and known Subsurface runtime of 57 minutes
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 58u * 60u + 20u, 57u * 60u + 20u));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 58u * 60u + 20u, 57u * 60u + 20u));
|
||||
}
|
||||
|
||||
/* This tests that a previously calculated plan isn't affecting the calculations of the next plan.
|
||||
|
@ -891,9 +887,9 @@ void TestPlan::testVpmbMetricRepeat()
|
|||
// print first ceiling
|
||||
printf("First ceiling %.1f m\n", (mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar, &dive) * 0.001));
|
||||
// check benchmark run time of 27 minutes, and known Subsurface runtime of 28 minutes
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 27u * 60u + 20u, 27u * 60u + 20u));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 27u * 60u + 20u, 27u * 60u + 20u));
|
||||
|
||||
int firstDiveRunTimeSeconds = dive.dc.duration.seconds;
|
||||
int firstDiveRunTimeSeconds = dive.dcs[0].duration.seconds;
|
||||
|
||||
setupPlanVpmb100mTo70m30min(&testPlan);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
@ -911,27 +907,27 @@ void TestPlan::testVpmbMetricRepeat()
|
|||
QCOMPARE(lrint(dp->minimum_gas.mbar / 1000.0), 80l);
|
||||
// print first ceiling
|
||||
printf("First ceiling %.1f m\n", (mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar, &dive) * 0.001));
|
||||
QVERIFY(dive.dc.events.size() >= 3);
|
||||
QVERIFY(dive.dcs[0].events.size() >= 3);
|
||||
// check first gas change to 21/35 at 66m
|
||||
struct event *ev = &dive.dc.events[0];
|
||||
struct event *ev = &dive.dcs[0].events[0];
|
||||
QVERIFY(ev != NULL);
|
||||
QCOMPARE(ev->gas.index, 1);
|
||||
QCOMPARE(ev->gas.mix.o2.permille, 210);
|
||||
QCOMPARE(ev->gas.mix.he.permille, 350);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 66000);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 66000);
|
||||
// check second gas change to EAN50 at 21m
|
||||
ev = &dive.dc.events[1];
|
||||
ev = &dive.dcs[0].events[1];
|
||||
QCOMPARE(ev->gas.index, 2);
|
||||
QCOMPARE(ev->value, 50);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 21000);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 21000);
|
||||
// check third gas change to Oxygen at 6m
|
||||
ev = &dive.dc.events[2];
|
||||
ev = &dive.dcs[0].events[2];
|
||||
QVERIFY(ev != NULL);
|
||||
QCOMPARE(ev->gas.index, 3);
|
||||
QCOMPARE(ev->value, 100);
|
||||
QCOMPARE(get_depth_at_time(&dive.dc, ev->time.seconds), 6000);
|
||||
QCOMPARE(get_depth_at_time(&dive.dcs[0], ev->time.seconds), 6000);
|
||||
// we don't have a benchmark, known Subsurface runtime is 126 minutes
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 127u * 60u + 20u, 127u * 60u + 20u));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 127u * 60u + 20u, 127u * 60u + 20u));
|
||||
|
||||
setupPlanVpmb30m20min(&testPlan);
|
||||
plan(&test_deco_state, &testPlan, &dive, 0, 60, stoptable, cache, 1, 0);
|
||||
|
@ -951,7 +947,7 @@ void TestPlan::testVpmbMetricRepeat()
|
|||
printf("First ceiling %.1f m\n", (mbar_to_depth(test_deco_state.first_ceiling_pressure.mbar, &dive) * 0.001));
|
||||
|
||||
// check runtime is exactly the same as the first time
|
||||
int finalDiveRunTimeSeconds = dive.dc.duration.seconds;
|
||||
int finalDiveRunTimeSeconds = dive.dcs[0].duration.seconds;
|
||||
QCOMPARE(finalDiveRunTimeSeconds, firstDiveRunTimeSeconds);
|
||||
}
|
||||
|
||||
|
@ -967,7 +963,7 @@ void TestPlan::testCcrBailoutGasSelection()
|
|||
prefs.unit_system = METRIC;
|
||||
prefs.units.length = units::METERS;
|
||||
prefs.planner_deco_mode = BUEHLMANN;
|
||||
dive.dc.divemode = CCR;
|
||||
dive.dcs[0].divemode = CCR;
|
||||
prefs.dobailout = true;
|
||||
|
||||
struct diveplan testPlan = {};
|
||||
|
@ -982,22 +978,22 @@ void TestPlan::testCcrBailoutGasSelection()
|
|||
#endif
|
||||
|
||||
// check diluent used
|
||||
cylinder_t *cylinder = get_cylinder(&dive, get_cylinderid_at_time(&dive, &dive.dc, { 20 * 60 - 1 }));
|
||||
cylinder_t *cylinder = get_cylinder(&dive, get_cylinderid_at_time(&dive, &dive.dcs[0], { 20 * 60 - 1 }));
|
||||
QCOMPARE(cylinder->cylinder_use, DILUENT);
|
||||
QCOMPARE(get_o2(cylinder->gasmix), 200);
|
||||
|
||||
// check deep bailout used
|
||||
cylinder = get_cylinder(&dive, get_cylinderid_at_time(&dive, &dive.dc, { 20 * 60 + 1 }));
|
||||
cylinder = get_cylinder(&dive, get_cylinderid_at_time(&dive, &dive.dcs[0], { 20 * 60 + 1 }));
|
||||
QCOMPARE(cylinder->cylinder_use, OC_GAS);
|
||||
QCOMPARE(get_o2(cylinder->gasmix), 190);
|
||||
|
||||
// check shallow bailout used
|
||||
cylinder = get_cylinder(&dive, get_cylinderid_at_time(&dive, &dive.dc, { 30 * 60 }));
|
||||
cylinder = get_cylinder(&dive, get_cylinderid_at_time(&dive, &dive.dcs[0], { 30 * 60 }));
|
||||
QCOMPARE(cylinder->cylinder_use, OC_GAS);
|
||||
QCOMPARE(get_o2(cylinder->gasmix), 530);
|
||||
|
||||
// check expected run time of 51 minutes
|
||||
QVERIFY(compareDecoTime(dive.dc.duration.seconds, 51 * 60, 51 * 60));
|
||||
QVERIFY(compareDecoTime(dive.dcs[0].duration.seconds, 51 * 60, 51 * 60));
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue