mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-02 11:53:23 +00:00
db516b6d4e
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>
107 lines
2.9 KiB
C++
107 lines
2.9 KiB
C++
// SPDX-License-Identifier: GPL-2.0
|
|
#ifndef EVENT_H
|
|
#define EVENT_H
|
|
|
|
#include "divemode.h"
|
|
#include "gas.h"
|
|
#include "units.h"
|
|
|
|
#include <string>
|
|
#include <libdivecomputer/parser.h>
|
|
|
|
struct divecomputer;
|
|
|
|
enum event_severity {
|
|
EVENT_SEVERITY_NONE = 0,
|
|
EVENT_SEVERITY_INFO,
|
|
EVENT_SEVERITY_WARN,
|
|
EVENT_SEVERITY_ALARM
|
|
};
|
|
|
|
/*
|
|
* Events are currently based straight on what libdivecomputer gives us.
|
|
* We need to wrap these into our own events at some point to remove some of the limitations.
|
|
*/
|
|
|
|
struct event {
|
|
duration_t time;
|
|
int type;
|
|
/* This is the annoying libdivecomputer format. */
|
|
int flags, value;
|
|
/* .. and this is our "extended" data for some event types */
|
|
union {
|
|
enum divemode_t divemode; // for divemode change events
|
|
/*
|
|
* NOTE! The index may be -1, which means "unknown". In that
|
|
* case, the get_cylinder_index() function will give the best
|
|
* match with the cylinders in the dive based on gasmix.
|
|
*/
|
|
struct { // for gas switch events
|
|
int index;
|
|
struct gasmix mix;
|
|
} gas;
|
|
};
|
|
bool hidden;
|
|
std::string name;
|
|
event();
|
|
event(unsigned int time, int type, int flags, int value, const std::string &name);
|
|
~event();
|
|
|
|
bool operator==(const event &b2) const;
|
|
|
|
bool is_gaschange() const;
|
|
bool is_divemodechange() const;
|
|
event_severity get_severity() const;
|
|
};
|
|
|
|
class event_loop
|
|
{
|
|
std::string name;
|
|
size_t idx;
|
|
public:
|
|
event_loop(const char *name);
|
|
struct event *next(struct divecomputer &dc); // nullptr -> end
|
|
const struct event *next(const struct divecomputer &dc); // nullptr -> end
|
|
};
|
|
|
|
/* Get gasmixes at increasing timestamps. */
|
|
class gasmix_loop {
|
|
const struct dive &dive;
|
|
const struct divecomputer &dc;
|
|
bool first_run;
|
|
event_loop loop;
|
|
const struct event *next_event;
|
|
int last_cylinder_index;
|
|
int last_time;
|
|
public:
|
|
gasmix_loop(const struct dive &dive, const struct divecomputer &dc);
|
|
// Return the next cylinder index / gasmix from the list of gas switches
|
|
// and the time in seconds when this gas switch happened
|
|
// (including the potentially imaginary first gas switch to cylinder 0 / air)
|
|
std::pair<int, int> next_cylinder_index(); // -1 -> end
|
|
std::pair<gasmix, int> next(); // gasmix_invalid -> end
|
|
|
|
// Return the cylinder index / gasmix at a given time during the dive
|
|
// and the time in seconds when this switch to this gas happened
|
|
// (including the potentially imaginary first gas switch to cylinder 0 / air)
|
|
std::pair<int, int> cylinder_index_at(int time); // -1 -> end
|
|
std::pair<gasmix, int> at(int time); // gasmix_invalid -> end
|
|
|
|
bool has_next() const;
|
|
};
|
|
|
|
/* Get divemodes at increasing timestamps. */
|
|
class divemode_loop {
|
|
const struct divecomputer &dc;
|
|
divemode_t last;
|
|
event_loop loop;
|
|
const struct event *ev;
|
|
public:
|
|
divemode_loop(const struct divecomputer &dc);
|
|
divemode_t next(int time);
|
|
};
|
|
|
|
extern const struct event *get_first_event(const struct divecomputer &dc, const std::string &name);
|
|
extern struct event *get_first_event(struct divecomputer &dc, const std::string &name);
|
|
|
|
#endif
|