summaryrefslogtreecommitdiffstats
path: root/core/dive.c
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2020-04-11 11:03:05 -0700
committerGravatar GitHub <noreply@github.com>2020-04-11 11:03:05 -0700
commit6d187b5f4a3b51043fa3b53b6c73a7e0ec7f0b53 (patch)
tree93b26b7381e565ecc0dc6d93e2d35b61a1cdaca9 /core/dive.c
parent2990010ccde56acec980e76ef5671137e87af488 (diff)
parent7dc04b4437c7aa1788f7d85a513a246ce502dea4 (diff)
downloadsubsurface-6d187b5f4a3b51043fa3b53b6c73a7e0ec7f0b53.tar.gz
Merge pull request #2643 from bstoeger/cylinder4
First steps of cylinder-editing undo
Diffstat (limited to 'core/dive.c')
-rw-r--r--core/dive.c96
1 files changed, 80 insertions, 16 deletions
diff --git a/core/dive.c b/core/dive.c
index c97c229f6..df5d7951d 100644
--- a/core/dive.c
+++ b/core/dive.c
@@ -11,6 +11,7 @@
#include "device.h"
#include "divelist.h"
#include "divesite.h"
+#include "errorhelper.h"
#include "qthelper.h"
#include "metadata.h"
#include "membuffer.h"
@@ -126,10 +127,10 @@ int event_is_gaschange(const struct event *ev)
ev->type == SAMPLE_EVENT_GASCHANGE2;
}
-struct event *add_event(struct divecomputer *dc, unsigned int time, int type, int flags, int value, const char *name)
+struct event *create_event(unsigned int time, int type, int flags, int value, const char *name)
{
int gas_index = -1;
- struct event *ev, **p;
+ struct event *ev;
unsigned int size, len = strlen(name);
size = sizeof(*ev) + len + 1;
@@ -164,18 +165,85 @@ struct event *add_event(struct divecomputer *dc, unsigned int time, int type, in
break;
}
+ return ev;
+}
+
+/* warning: does not test idx for validity */
+struct event *create_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx)
+{
+ /* The gas switch event format is insane for historical reasons */
+ struct gasmix mix = get_cylinder(dive, idx)->gasmix;
+ int o2 = get_o2(mix);
+ int he = get_he(mix);
+ struct event *ev;
+ int value;
+
+ o2 = (o2 + 5) / 10;
+ he = (he + 5) / 10;
+ value = o2 + (he << 16);
+
+ ev = create_event(seconds, he ? SAMPLE_EVENT_GASCHANGE2 : SAMPLE_EVENT_GASCHANGE, 0, value, "gaschange");
+ ev->gas.index = idx;
+ ev->gas.mix = mix;
+ return ev;
+}
+
+struct event *clone_event_rename(const struct event *ev, const char *name)
+{
+ return create_event(ev->time.seconds, ev->type, ev->flags, ev->value, name);
+}
+
+void add_event_to_dc(struct divecomputer *dc, struct event *ev)
+{
+ struct event **p;
+
p = &dc->events;
/* insert in the sorted list of events */
- while (*p && (*p)->time.seconds <= time)
+ while (*p && (*p)->time.seconds <= ev->time.seconds)
p = &(*p)->next;
ev->next = *p;
*p = ev;
+}
+
+struct event *add_event(struct divecomputer *dc, unsigned int time, int type, int flags, int value, const char *name)
+{
+ struct event *ev = create_event(time, type, flags, value, name);
+
+ if (!ev)
+ return NULL;
+
+ add_event_to_dc(dc, ev);
+
remember_event(name);
return ev;
}
-static int same_event(const struct event *a, const struct event *b)
+void add_gas_switch_event(struct dive *dive, struct divecomputer *dc, int seconds, int idx)
+{
+ /* sanity check so we don't crash */
+ if (idx < 0 || idx >= dive->cylinders.nr) {
+ report_error("Unknown cylinder index: %d", idx);
+ return;
+ }
+ struct event *ev = create_gas_switch_event(dive, dc, seconds, idx);
+ add_event_to_dc(dc, ev);
+}
+
+/* Substitutes an event in a divecomputer for another. No reordering is performed! */
+void swap_event(struct divecomputer *dc, struct event *from, struct event *to)
+{
+ for (struct event **ep = &dc->events; *ep; ep = &(*ep)->next) {
+ if (*ep == from) {
+ to->next = from->next;
+ *ep = to;
+ from->next = NULL; // For good measure.
+ break;
+ }
+ }
+}
+
+bool same_event(const struct event *a, const struct event *b)
{
if (a->time.seconds != b->time.seconds)
return 0;
@@ -188,19 +256,15 @@ static int same_event(const struct event *a, const struct event *b)
return !strcmp(a->name, b->name);
}
-void remove_event(struct event *event)
+/* Remove given event from dive computer. Does *not* free the event. */
+void remove_event_from_dc(struct divecomputer *dc, struct event *event)
{
- struct event **ep = &current_dc->events;
- while (ep && !same_event(*ep, event))
- ep = &(*ep)->next;
- if (ep) {
- /* we can't link directly with event->next
- * because 'event' can be a copy from another
- * dive (for instance the displayed_dive
- * that we use on the interface to show things). */
- struct event *temp = (*ep)->next;
- free(*ep);
- *ep = temp;
+ for (struct event **ep = &dc->events; *ep; ep = &(*ep)->next) {
+ if (*ep == event) {
+ *ep = event->next;
+ event->next = NULL; // For good measure.
+ break;
+ }
}
}