mirror of
https://github.com/subsurface/subsurface.git
synced 2025-02-19 22:16:15 +00:00
core: turn event-list of divecomputer into std::vector<>
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 commit is contained in:
parent
8ddc960fa0
commit
27dbdd35c6
36 changed files with 644 additions and 821 deletions
133
core/event.cpp
133
core/event.cpp
|
@ -1,67 +1,24 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "event.h"
|
||||
#include "divecomputer.h"
|
||||
#include "eventtype.h"
|
||||
#include "subsurface-string.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
event::event() : next(nullptr), type(SAMPLE_EVENT_NONE), flags(0), value(0),
|
||||
divemode(OC), deleted(false), hidden(false)
|
||||
event::event() : type(SAMPLE_EVENT_NONE), flags(0), value(0),
|
||||
divemode(OC), hidden(false)
|
||||
{
|
||||
/* That overwrites divemode. Is this a smart thing to do? */
|
||||
gas.index = -1;
|
||||
gas.mix = gasmix_air;
|
||||
}
|
||||
|
||||
event::~event()
|
||||
{
|
||||
}
|
||||
|
||||
int event_is_gaschange(const struct event *ev)
|
||||
{
|
||||
return ev->type == SAMPLE_EVENT_GASCHANGE ||
|
||||
ev->type == SAMPLE_EVENT_GASCHANGE2;
|
||||
}
|
||||
|
||||
bool event_is_divemodechange(const struct event *ev)
|
||||
{
|
||||
return ev->name == "modechange";
|
||||
}
|
||||
|
||||
struct event *clone_event(const struct event *src_ev)
|
||||
{
|
||||
struct event *ev;
|
||||
if (!src_ev)
|
||||
return NULL;
|
||||
|
||||
ev = new event;
|
||||
*ev = *src_ev;
|
||||
ev->next = NULL;
|
||||
|
||||
return ev;
|
||||
}
|
||||
|
||||
void free_events(struct event *ev)
|
||||
{
|
||||
while (ev) {
|
||||
struct event *next = ev->next;
|
||||
delete ev;
|
||||
ev = next;
|
||||
}
|
||||
}
|
||||
|
||||
struct event *create_event(unsigned int time, int type, int flags, int value, const std::string &name)
|
||||
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)
|
||||
{
|
||||
int gas_index = -1;
|
||||
struct event *ev;
|
||||
|
||||
ev = new event;
|
||||
ev->name = name;
|
||||
ev->time.seconds = time;
|
||||
ev->type = type;
|
||||
ev->flags = flags;
|
||||
ev->value = value;
|
||||
fraction_t he;
|
||||
this->time.seconds = time;
|
||||
|
||||
/*
|
||||
* Expand the events into a sane format. Currently
|
||||
|
@ -70,7 +27,7 @@ struct event *create_event(unsigned int time, int type, int flags, int value, co
|
|||
switch (type) {
|
||||
case SAMPLE_EVENT_GASCHANGE2:
|
||||
/* High 16 bits are He percentage */
|
||||
ev->gas.mix.he.permille = (value >> 16) * 10;
|
||||
he.permille = (value >> 16) * 10;
|
||||
|
||||
/* Extension to the GASCHANGE2 format: cylinder index in 'flags' */
|
||||
/* TODO: verify that gas_index < num_cylinders. */
|
||||
|
@ -79,37 +36,39 @@ struct event *create_event(unsigned int time, int type, int flags, int value, co
|
|||
/* Fallthrough */
|
||||
case SAMPLE_EVENT_GASCHANGE:
|
||||
/* Low 16 bits are O2 percentage */
|
||||
ev->gas.mix.o2.permille = (value & 0xffff) * 10;
|
||||
ev->gas.index = gas_index;
|
||||
gas.mix.he = he;
|
||||
gas.mix.o2.permille = (value & 0xffff) * 10;
|
||||
gas.index = gas_index;
|
||||
break;
|
||||
}
|
||||
|
||||
remember_event_type(ev);
|
||||
|
||||
return ev;
|
||||
remember_event_type(this);
|
||||
}
|
||||
|
||||
struct event *clone_event_rename(const struct event *ev, const std::string &name)
|
||||
event::~event()
|
||||
{
|
||||
return create_event(ev->time.seconds, ev->type, ev->flags, ev->value, name);
|
||||
}
|
||||
|
||||
bool same_event(const struct event *a, const struct event *b)
|
||||
bool event_is_gaschange(const struct event &ev)
|
||||
{
|
||||
if (a->time.seconds != b->time.seconds)
|
||||
return 0;
|
||||
if (a->type != b->type)
|
||||
return 0;
|
||||
if (a->flags != b->flags)
|
||||
return 0;
|
||||
if (a->value != b->value)
|
||||
return 0;
|
||||
return a->name == b->name;
|
||||
return ev.type == SAMPLE_EVENT_GASCHANGE ||
|
||||
ev.type == SAMPLE_EVENT_GASCHANGE2;
|
||||
}
|
||||
|
||||
extern enum event_severity get_event_severity(const struct event *ev)
|
||||
bool event_is_divemodechange(const struct event &ev)
|
||||
{
|
||||
switch (ev->flags & SAMPLE_FLAGS_SEVERITY_MASK) {
|
||||
return ev.name == "modechange";
|
||||
}
|
||||
|
||||
bool event::operator==(const event &b) const
|
||||
{
|
||||
return std::tie(time.seconds, type, flags, value, name) ==
|
||||
std::tie(b.time.seconds, b.type, b.flags, b.value, b.name);
|
||||
}
|
||||
|
||||
extern enum event_severity get_event_severity(const struct event &ev)
|
||||
{
|
||||
switch (ev.flags & SAMPLE_FLAGS_SEVERITY_MASK) {
|
||||
case SAMPLE_FLAGS_SEVERITY_INFO:
|
||||
return EVENT_SEVERITY_INFO;
|
||||
case SAMPLE_FLAGS_SEVERITY_WARN:
|
||||
|
@ -120,3 +79,35 @@ extern enum event_severity get_event_severity(const struct event *ev)
|
|||
return EVENT_SEVERITY_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue