2020-10-25 08:14:16 +00:00
|
|
|
// SPDX-License-Identifier: GPL-2.0
|
|
|
|
#include "event.h"
|
2024-05-25 06:16:57 +00:00
|
|
|
#include "divecomputer.h"
|
2024-02-14 09:59:13 +00:00
|
|
|
#include "eventtype.h"
|
2020-10-25 08:14:16 +00:00
|
|
|
#include "subsurface-string.h"
|
|
|
|
|
2024-05-25 06:16:57 +00:00
|
|
|
event::event() : type(SAMPLE_EVENT_NONE), flags(0), value(0),
|
|
|
|
divemode(OC), hidden(false)
|
2024-05-04 17:15:47 +00:00
|
|
|
{
|
|
|
|
/* That overwrites divemode. Is this a smart thing to do? */
|
|
|
|
gas.index = -1;
|
|
|
|
gas.mix = gasmix_air;
|
|
|
|
}
|
|
|
|
|
2024-05-25 06:16:57 +00:00
|
|
|
event::event(unsigned int time, int type, int flags, int value, const std::string &name) :
|
|
|
|
type(type), flags(flags), value(value), divemode(OC),
|
|
|
|
hidden(false), name(name)
|
2020-10-25 08:14:16 +00:00
|
|
|
{
|
|
|
|
int gas_index = -1;
|
2024-05-25 06:16:57 +00:00
|
|
|
fraction_t he;
|
|
|
|
this->time.seconds = time;
|
2020-10-25 08:14:16 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Expand the events into a sane format. Currently
|
|
|
|
* just gas switches
|
|
|
|
*/
|
|
|
|
switch (type) {
|
|
|
|
case SAMPLE_EVENT_GASCHANGE2:
|
|
|
|
/* High 16 bits are He percentage */
|
2024-05-25 06:16:57 +00:00
|
|
|
he.permille = (value >> 16) * 10;
|
2020-10-25 08:14:16 +00:00
|
|
|
|
|
|
|
/* Extension to the GASCHANGE2 format: cylinder index in 'flags' */
|
|
|
|
/* TODO: verify that gas_index < num_cylinders. */
|
|
|
|
if (flags > 0)
|
|
|
|
gas_index = flags-1;
|
|
|
|
/* Fallthrough */
|
|
|
|
case SAMPLE_EVENT_GASCHANGE:
|
|
|
|
/* Low 16 bits are O2 percentage */
|
2024-05-25 06:16:57 +00:00
|
|
|
gas.mix.he = he;
|
|
|
|
gas.mix.o2.permille = (value & 0xffff) * 10;
|
|
|
|
gas.index = gas_index;
|
2020-10-25 08:14:16 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2024-05-25 06:16:57 +00:00
|
|
|
remember_event_type(this);
|
|
|
|
}
|
2023-02-12 15:18:17 +00:00
|
|
|
|
2024-05-25 06:16:57 +00:00
|
|
|
event::~event()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2024-05-25 18:12:10 +00:00
|
|
|
bool event::is_gaschange() const
|
2024-05-25 06:16:57 +00:00
|
|
|
{
|
2024-05-25 18:12:10 +00:00
|
|
|
return type == SAMPLE_EVENT_GASCHANGE || type == SAMPLE_EVENT_GASCHANGE2;
|
2020-10-25 08:14:16 +00:00
|
|
|
}
|
|
|
|
|
2024-05-25 18:12:10 +00:00
|
|
|
bool event::is_divemodechange() const
|
2020-10-25 08:14:16 +00:00
|
|
|
{
|
2024-05-25 18:12:10 +00:00
|
|
|
return name == "modechange";
|
2020-10-25 08:14:16 +00:00
|
|
|
}
|
|
|
|
|
2024-05-25 06:16:57 +00:00
|
|
|
bool event::operator==(const event &b) const
|
2020-10-25 08:14:16 +00:00
|
|
|
{
|
2024-05-25 06:16:57 +00:00
|
|
|
return std::tie(time.seconds, type, flags, value, name) ==
|
|
|
|
std::tie(b.time.seconds, b.type, b.flags, b.value, b.name);
|
2020-10-25 08:14:16 +00:00
|
|
|
}
|
2024-02-14 20:29:48 +00:00
|
|
|
|
2024-05-25 18:12:10 +00:00
|
|
|
enum event_severity event::get_severity() const
|
2024-02-14 20:29:48 +00:00
|
|
|
{
|
2024-05-25 18:12:10 +00:00
|
|
|
switch (flags & SAMPLE_FLAGS_SEVERITY_MASK) {
|
2024-02-14 20:29:48 +00:00
|
|
|
case SAMPLE_FLAGS_SEVERITY_INFO:
|
|
|
|
return EVENT_SEVERITY_INFO;
|
|
|
|
case SAMPLE_FLAGS_SEVERITY_WARN:
|
|
|
|
return EVENT_SEVERITY_WARN;
|
|
|
|
case SAMPLE_FLAGS_SEVERITY_ALARM:
|
|
|
|
return EVENT_SEVERITY_ALARM;
|
|
|
|
default:
|
|
|
|
return EVENT_SEVERITY_NONE;
|
|
|
|
}
|
|
|
|
}
|
2024-05-25 06:16:57 +00:00
|
|
|
|
|
|
|
event_loop::event_loop(const char *name) : name(name), idx(0)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
struct event *event_loop::next(struct divecomputer &dc)
|
|
|
|
{
|
|
|
|
if (name.empty())
|
|
|
|
return nullptr;
|
|
|
|
while (idx < dc.events.size()) {
|
|
|
|
struct event &ev = dc.events[idx++];
|
|
|
|
if (ev.name == name)
|
|
|
|
return &ev;
|
|
|
|
}
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
const struct event *event_loop::next(const struct divecomputer &dc)
|
|
|
|
{
|
|
|
|
return next(const_cast<divecomputer &>(dc));
|
|
|
|
}
|
|
|
|
|
|
|
|
struct event *get_first_event(struct divecomputer &dc, const std::string &name)
|
|
|
|
{
|
|
|
|
auto it = std::find_if(dc.events.begin(), dc.events.end(), [name](auto &ev) { return ev.name == name; });
|
|
|
|
return it != dc.events.end() ? &*it : nullptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
const struct event *get_first_event(const struct divecomputer &dc, const std::string &name)
|
|
|
|
{
|
|
|
|
return get_first_event(const_cast<divecomputer &>(dc), name);
|
|
|
|
}
|