When computing the suggested switch depth for a gas,
we should take the next stop depth above the MOD, i.e.
round down. Otherwise we can produce MOD violation warnings.
We need, however, a bit of fudge as otherwise we do not
suggest to switch to o2 at 6m.
TestPlan uses the MOD to determine the depth to switch to
Tx21/35. This happens to be 65.378m. Therefore, switching
at 66m violates the MOD, the switch should be at 63m.
This then affects the gas usage.
Signed-off-by: Robert C. Helling <helling@atdotde.de>
We had a pattern where doubles were converted to long with
lrint() and then down-cast to a narrower int type.
Because this is unwieldy, introduce a function encapsulating
this.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Now that we have defined addition and subtraction on unit
classes, let's use them in a few examples.
Yes, some of these are a bit pointless, because they are
of the kind
a.mbar - b.mbar => (a-b).mbar
However, these probably should be further simplified
by storing the result in a unit type.
This commit is mostly a proof-of-concept.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The goal here is to add general addition and scalar multiplication
functions to the unit types.
Thereto, we need a CRTP
(https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)
base class.
However, this breaks compound initialization, so we have to use
named initializers:
weight_t { 2000 } -> weight_t { .grams = 2000 }
The good thing is that this is exactly how these classes were
supposed to be used: make the unit explicit!
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Improve the event loop architecture by making it set the divecomputer in
the constructor - using the same loop for multiple dive computers is not
intended to work.
Also change `next()` in `divemode_loop` to `at()` to make the name more
aligned with its function.
Signed-off-by: Michael Keller <github@ike.ch>
When merging two dives, if a divesite is chosen that doesn't
have a GPS location, but another divesite has a GPS location,
then the GPS location of the former is set to that of the
latter.
However, that was done outside of the undo system, so that
it is not undone and the frontend is not made aware of the
change.
Fix this. To simplify things, move the code from the undo
machinery to the core.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Fix the initial gasmix that is shown in the tank bar of the profile.
Also add a meaningful gas name for gases with negative values for
percentages.
@bstoeger: This is a side effect of the `event_loop` functionality
introduced as part of #4198. In the case of an `event_loop("gasmix")`
this does not take into account the edge case where there is no
gaschange event at the very beginning of the dive, and the first gasmix
is implicitly used as the starting gasmix. This happens for planned and
manually added dives, but also for some dive computers.
We are using the
same kind of loop in a number of other places in `core/profile.cpp`,
`core/dive.cpp`, `core/gaspressures.cpp`, and `profile-widget/tankitem.cpp`,
and I am wondering if we should be converting these to use
`gasmix_loop` instead to avoid being bit by this special case?
Signed-off-by: Michael Keller <github@ike.ch>
Commit c27314d60 ("core: replace add_sample() by append_sample()") broke
the dive computer interleaving when merging two dives: the sample
merging (done by "merge_samples()") no longer took the offset between
the two merged dives into account, and instead just blindly copied the
samples from the second dive computer with no time offset.
The end result was a completely broken profile.
This adds back the sample offset. It also takes the offset not from the
difference in time of the two dives, but the difference in time of the
dive computers. That way we're not mixing up different times from
different sources that aren't necessarily in sync (the time *difference*
is hopefully the same, but still..).
The dive merging still messes up the dive location. That's some other bug.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This has become a bit of a catch-all overhaul of a large portion of the
planner - I started out wanting to improve the CCR mode, but then as I
started pulling all the other threads that needed addressing started to
come with it.
Improve how the gas selection is handled when planning dives in CCR
mode, by making the type (OC / CCR) of segments dependent on the gas use
type that was set for the selected gas.
Add a preference to allow the user to chose to use OC gases as diluent,
in a similar fashion to the original implementation.
Hide gases that cannot be used in the currently selected dive mode in
all drop downs.
Include usage type in gas names if this is needed.
Hide columns and disable elements in the 'Dive planner points' table if
they can they can not be edited in the curently selected dive mode.
Visually identify gases and usage types that are not appropriate for the
currently selected dive mode.
Move the 'Dive mode' selection to the top of the planner view, to
accommodate the fact that this is a property of the dive and not a
planner setting.
Show a warning instead of the dive plan if the plan contains gases that
are not usable in the selected dive mode.
Fix the data entry for the setpoint in the 'Dive planner points' table.
Fix problems with enabling / disabling planner settings when switching
between dive modes.
Refactor some names to make them more appropriate for their current
usage.
One point that is still open is to hide gas usage graphs in the planner
profile if the gas isn't used for OC, as there is no way to meaningfully
interpolate such usage.
Signed-off-by: Michael Keller <github@ike.ch>
If there were more than one redundant event in the 60 sec range,
the event would be deleted multiple time, leading to a crash.
Only mark for deletion once.
Moreover, don't consider events that were already marked for
deletion, because that would mean that redundant events all 59 secs
would lead to all events (but the first one) deleted.
Finally, optimize the loop by stopping once the 60 sec limit
is reached.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The copy/pasting of dive-sites was fundamentally broken in at least two
ways:
1) The dive-site pointer in struct dive was simply overwritten, which
breaks internal consistency. Also, no dive-site changed signals where
sent.
2) The copied dive-site was stored as a pointer in a struct dive. Thus,
the user could copy a dive, then delete the dive-site and paste.
This would lead to a dangling pointer and ultimately crash the
application.
Fix this by storing the UUID of the dive-site, not a pointer.
To do that, don't store a copy of the dive, but collect all
the data in a `dive_paste_data` structure.
If the dive site has been deleted on paste, do nothing.
Send the appropriate signals on pasting.
The mobile version had an additional bug: It kept a pointer to the
dive to be copied, which might become stale by undo.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This one-liner wasn't really doing anything and there was only
one user of the return value.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The important point is that this now takes a reference that
avoid string copying. The old code used C-strings and therefore
copy-semantics were OK.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Feels natural in a C++ code base.
This removes a nullptr-check so some care has to be taken.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Feel natural in a C++ code base.
Remove the second parameter, because all callers where passing
`true` anyway.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Feels natural in a C++ code base.
Change the function to return a weight_t. Sadly, use of the
units.h types is very inconsistent and many parts of the code
use int or double instead. So let's try to make this consistent.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Feels natural in a C++ code base.
Moreover, remove the fulltext-unregistration, as this is a
layering violation.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
It is unclear why this was declared in divelist.h.
Moreover, rename it to get_maximal_gas() to better reflect
what it does.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
These functions have to access other dives in the list to
calculate CNS, etc, so let's call them from there.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
These functions have to access other dives in the list to
calculate CNS, etc, so let's call them from there.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This accesses the global dive_table, so make this explicit.
Since force_fixup_dive() and default_dive() use fixup_dive(),
also move them to struct dive_table.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Before, a non-owning pointer was passed and the dive moved
away from the dive. Instead, let the caller decide if they
still want to keep a copy of the dive, or give up ownership:
In MainWindow and QMLManager new dives are generated, so
one might just as well give up ownership. In contrast,
the planner works on a copy (originally the infamous
"displayed_dive") and now moves the data manually.
This commit also removes duplicate code, by moving the
"create default dive" code from MainWindow and QMLManager
to struct dive.
Finally, determination of the "time zone offset" is not done
in POSIX, since we want to avoid calls form the core into
Qt.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This implicitly accessed the global divelog. Most of the users were
in the test/ folder anyway. Replace by explicit accesses to the
global divelog.dives.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This function implicitely accessed the global divelog. To make
that explicit make it a member of dive_table, such that the
caller must access it via the global variable.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is a messy commit, because the "qPref" system relies
heavily on QString, which means lots of conversions between
the two worlds. Ultimately, I plan to base the preferences
system on std::string and only convert to QString when
pushing through Qt's property system or when writing into
Qt's settings.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is a humongous commit, because it touches all parts of the
code. It removes the last user of our horrible TABLE macros, which
simulate std::vector<> in a very clumsy way.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Nothing against free-standing functions, but in the case
of dc_watertemp(), dc_airtemp(), endtime() and totaltime(),
it seems natural to move this into the dive class and avoid
polution of the global name space.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>