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 is a rather long commit, because it refactors lots of the event
code from pointer to value semantics: pointers to entries in an
std::vector<> are not stable, so better use indexes.
To step through the event-list at diven time stamps, add *_loop classes,
which encapsulate state that had to be manually handled before by
the caller. I'm not happy about the interface, but it tries to
mirror the one we had before.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is a hairy one, because the sample code is rather tricky.
There was a pattern of looping through pairs of adjacent samples,
for interpolation purposes. Add an range adapter to generalize
such loops.
Removes the finish_sample() function: The code would call
prepare_sample() to start parsing of samples and then
finish_sample() to actuall add it. I.e. a kind of commit().
Since, with one exception, all users of prepare_sample()
called finish_sample() in all code paths, we might just add
the sample in the first place. The exception was sample_end()
in parse.cpp. This brings a small change: samples are now
added, even if they could only be parsed partially. I doubt
that this makes any difference, since it will only happen
for broken divelogs anyway.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This allows us to use non-C member variables. Convert a number
of pointers to unique_ptr<>s.
Code in uemis-downloader.cpp had to be refactored, because
it mixed owning and non-owning pointers. Mad.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since everything is C++ now, we can use unique_ptr<>s. This makes
the code significantly shorter, because we can now use the default
move constructor and assignment operators.
This has a semantic change when std::move()-ing the divelog:
now not the contents of the tables are moved, but the pointers.
That is, the moved-from object now has no more tables and
must not be used anymore. This made it necessary to replace
std::move()s by std::swap()s. In that regard, the old code was
in principle broken: it used moved-from objects, which may work
but usually doesn't.
This commit adds a myriad of .get() function calls where the code
expects a C-style pointer. The plan is to remove virtually all of
them, when we move free-standing functions into the class it acts
on. Or, replace C-style pointers by references where we don't support
NULL.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
There were only two of them, from the time C-code had to access
the divelog: clear_divelog() and delete_single_dive().
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The old code would construct and then initialize the object
in a separate function, which added lots of complication.
Just initialize the thing in the constructor, store a
reference, not a pointer to the table. And do a few other
code cleanups. The result is distinctly more pleasing.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This gives the distance between to location_t objects. It is
unclear why this was in divesite.cpp.
Moreover pass by value, not raw pointer.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
There were a number of free standing functions acting on a
dive-site-table. Make them member functions. This allows
for shorter names. Use the get_idx() function of the base
class, which returns a size_t instead of an int (since that
is what the standard, somewhat unfortunately, uses).
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This makes memory management more simple, as not explicit deletion
is necessary.
A rather large commit, because changing QVector<> to std::vector<>
is propagated up the call chain.
Adds a new range_contains() helper function for collection
types such as std::vector<>. I didn't want to call it
contains(), since we already have a contains function
for strings and let's keep argument overloading simple.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
This is a long commit, because it introduces a new abstraction:
a general std::vector<> of std::unique_ptrs<>.
Moreover, it replaces a number of pointers by C++ references,
when the callee does not suppoert null objects.
This simplifies memory management and makes ownership more
explicit. It is a proof-of-concept and a test-bed for
the other core data structrures.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Makes the code much nicer to read.
Default initialize cylinder_t to the empty cylinder.
This produces lots of warnings, because most structure are now
not PODs anymore and shouldn't be erased using memset().
These memset()s will be removed one-by-one and replaced by
proper constructors.
The whole ordeal made it necessary to add a constructor to
struct event. To simplify things the whole optimization of
the variable-size event names was removed. In upcoming commits
this will be replaced by std::string anyway.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since this is now in C++, we don't have to use our crazy
TABLE_* macros.
This contains a logic change: the dives associated to a
dive site are now unsorted.
The old code was subtly buggy: dives were added in a sorted
manner, but when the dive was edited the list was not
resorted. Very unlikely that this leads to a serious
problem, still not good.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Since the taxonomy is now a real C++ struct with constructor
and destructor, dive_site has to be converted to C++ as well.
A bit hairy for now, but will ultimately be distinctly simpler.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Use std::vector<> instead of fixed size array.
Doesn't do any logic change, even though the back-translation
logic is ominous.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The old code was wild: For the yearly statistics it would allocate
one entry per dive in the log. Of course, it would also leak
C-style strings.
Convert the whole thing to somewhat idiomatic C++.
Somewhat wasted work, because I'd like to convert the whole thing
to the new statistics code. But let's finish the conversion to C++
first.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Fix an issue introduced in #4148.
Essentially the refactoring missed the fact that in the imperial system
tank size is tracked as the free gas volume, but in the metric system
(which is the one used in most of Subsurface's calculations) tank size
is tracked as water capacity.
So when updating a tank template tracking imperial measurements, the
given (metric) volume in l has to be multiplied by the working pressure,
and vice versa.
This also combines all the logic dealing with `tank_info` data in one
place, hopefully making it less likely that this will be broken by
inconsistencies in the future.
Fixes#4239.
Signed-off-by: Michael Keller <github@ike.ch>
The roles DIVE_IDX and SELECTED_ROLE were used for the old selection
system and removed in b8e7a600d2.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
- show the correct gasmix in the profile;
- make gases available for gas switches in the profile after they have
been added;
- persist gas changes;
- add air as a default gas when adding a dive.
This still has problems when undoing a gas switch - instead of
completely removing the gas switch it is just moved to the next point in the
profile.
Signed-off-by: Michael Keller <github@ike.ch>
- standardise the naming;
- use it consistently;
- apply the 'samples < 50' only when putting manually added dives into
edit mode - everywhere else manually added dives should be treated as
such;
- do not show a warning before editing a manually added dive in planner.
Signed-off-by: Michael Keller <github@ike.ch>
The lambda that created the list of gases took a copy not a
reference of the planned dive. Of course, that never had its
gases updated. Ultimately this would crash, because this sent
an index of "-1" on change.
Fix by
1) Using a reference to the dive, not the copy
2) Catch an invalid "-1" index (by Michael Keller <github@ike.ch>)
Fixes#4188
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Currently editing of planned dives that have been merged with actual
(logged) dives only works if the 'Planned dive' divecomputer is the
first divecomputer, and this divecomputer is selected when clicking
'Edit planned dive'. In other cases the profile of the first
divecomputer is overlaid with the profile of the planned dive, and the
first divecomputer's profile is overwritten when saving the dive plan.
Fix this problem.
Triggered by @SeppoTakalo's comment (https://github.com/subsurface/subsurface/issues/1913#issuecomment-2075562119): Users don't like that planned dives show up as their own entries in the dive list, so being able to merge them with the actual dive after it has been executed is a good feature - but this wasn't working well until now.
Signed-off-by: Michael Keller <github@ike.ch>
The old code was leaking memory. Use std::unique_ptr<> for
ownership management.
This is still very primitive and divetags are kept during
application lifetime. There should probably be some form
of reference counting. And the taglist should not be global,
but attached to the divelog.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The deco timestep is a parameter to the plan() function. There
seems no need to define this as a global macro. Probably some
code reshuffeling artifact.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The combo-boxes (cylinder type, weightsystem, etc.) were controlled
by global models. Keeping these models up-to-date was very combersome
and buggy.
Create a new model everytime a combobox is opened. Ultimately it
might even be better to create a copy of the strings and switch
to simple QStringListModel. Set data in the core directly and
don't do this via the models.
The result is much simpler and easier to handle.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Q_FOREACH and foreach are anachronisms.
Range based for may cause a performance regression: it can
lead to a copy of shared containers (one reason why Qt's
COW containers are broken). However, as long as there is no
user noticeable delay, there is no point in analyzing each case.
And also no point in slapping an 'asConst' on every container
that is looped over.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
qthelper.h is an absolute monstrosity and it is unclear what
report_info and SSRF_INFO have to do with Qt.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The automatic conversion from char * to QVariant failed to
compile for me. Let's hint that this should be interpreted
as a string. No idea, why this happens for me, but apparently
not on CI.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Fix the persisting and use of gradient factor preferences for dive
profiles in the mobile version.
Also rename the mobile backend gradient factor settings to make it
obvious that they are used by the (not currently enabled) planner.
Signed-off-by: Michael Keller <github@ike.ch>
Mostly irrelevant std::move() stuff of copy-on-write Qt objects,
a few real bugs, a timestamp_t downconversion and some codingsyle
adaptation.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Unfortunately Coverity doesn't understand that most Qt data
structures are copy-on-write. It's a mis-feature of Qt, but
it is the way it is. Thus, passing by value is not an issue.
Out of ca. 25 warnings only two were legit. Let's silence
the others by either std::move()ing or passing by reference,
as would be idiomatic C++, which Qt is not.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
Include unused tanks in merges of multiple logs into a single dive if
the 'Show unused cylinders' preference is enabled.
Also rename the preference (in code) to `include_unused_tanks` to
reflect the fact that it is already used in more places than just the
display (exporting, cloning dives).
Simplified the cylinder model to make forced inclusion of unused tanks
dependent on use of the model in planner.
Leaving the persisted name of the preference as `display_unused_tanks`
to avoid resetting this for all users - is there a good way to migrate
preference names?
Signed-off-by: Michael Keller <github@ike.ch>
There was this completely weird loop that the planner-widget would
call the planner-model to get the current rebreather mode, which
would then access the dive in the planner widget. Just keep those
things in the planner widgets.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The only user of the DivePlannerPointsModel and the
GasSelectionModel is the planner. Let's keep these models
there.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The gas and dive-type models were repopulated in the
diveplanner model. The former are used in the planner.
However, the latter is also used outside of the planner,
when editing non-planned dives. Thus the former shouldn't
be repopulated by the latter, but by the code that needs
it.
Side note: repopulating the dive-type model seems to
make no sense whatsoever since the values never change,
but let's keep it for now.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
The mode was accessed via the global `displayed_dive`. In an effort
to remove globals, access it via the DivePlannerPointsModel instead.
Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>