aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2012-11-10 11:40:35 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2012-11-10 11:54:15 +0100
commit6ad73a8f043be283c07df34c6a5a43fee1b444e8 (patch)
tree792bdf62cd3036f9e367573bf2a828aed7e70380
parente07531dd10a9126544b4cb949b05ee2d15a50d5d (diff)
downloadsubsurface-6ad73a8f043b.tar.gz
Improve logic handling events
We now throw away redundant events, just as we throw away other redundant data coming from the dive computer. Events are considered redundant if they are less than 61 seconds apart and identical. This also improves the display of the remaining events in the profile as we now show the value of the event, if it is present (for example for a deco event we show the duration of the deepest stop). Finally, for events that define a range (so they set the beginning flag and assume and end flag some time later) we no loger show the triangle but assume that some other code handles visualizing them (as happens for the ceiling events). Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--dive.c61
-rw-r--r--dive.h1
-rw-r--r--gtk-gui.c2
-rw-r--r--profile.c11
4 files changed, 72 insertions, 3 deletions
diff --git a/dive.c b/dive.c
index c855acef8..06d15efdd 100644
--- a/dive.c
+++ b/dive.c
@@ -373,6 +373,30 @@ static void sanitize_cylinder_info(struct dive *dive)
}
}
+/* some events should never be thrown away */
+static gboolean is_potentially_redundant(struct event *event)
+{
+ if (!strcmp(event->name, "gaschange"))
+ return FALSE;
+ return TRUE;
+}
+
+/* match just by name - we compare the details in the code that uses this helper */
+static struct event *find_previous_event(struct dive *dive, struct event *event)
+{
+ struct event *ev = dive->events;
+ struct event *previous = NULL;
+
+ if (!event->name)
+ return NULL;
+ while (ev && ev != event) {
+ if(ev->name && !strcmp(ev->name, event->name))
+ previous = ev;
+ ev = ev->next;
+ }
+ return previous;
+}
+
struct dive *fixup_dive(struct dive *dive)
{
int i,j;
@@ -384,6 +408,7 @@ struct dive *fixup_dive(struct dive *dive)
int lastdepth = 0;
int lasttemp = 0, lastpressure = 0;
int pressure_delta[MAX_CYLINDERS] = {INT_MAX, };
+ struct event *event;
add_people(dive->buddy);
add_people(dive->divemaster);
@@ -514,6 +539,42 @@ struct dive *fixup_dive(struct dive *dive)
add_weightsystem_description(ws);
}
+ /* events are stored as a linked list, so the concept of
+ * "consecutive, identical events" is somewhat hard to
+ * implement correctly (especially given that on some dive
+ * computers events are asynchronous, so they can come in
+ * between what would be the non-constant sample rate).
+ *
+ * So what we do is that we throw away clearly redundant
+ * events that are fewer than 61 seconds apart (assuming there
+ * is no dive computer with a sample rate of more than 60
+ * seconds... that would be pretty pointless to plot the
+ * profile with)
+ * We first only mark the events for deletion so that we
+ * still know when the previous event happened. */
+ event = dive->events;
+ while (event) {
+ struct event *prev;
+ if (is_potentially_redundant(event)) {
+ prev = find_previous_event(dive, event);
+ if (prev && prev->value == event->value &&
+ prev->flags == event->flags &&
+ event->time.seconds - prev->time.seconds < 61)
+ event->deleted = TRUE;
+ }
+ event = event->next;
+ }
+ event = dive->events;
+ while (event) {
+ if (event->next && event->next->deleted) {
+ struct event *nextnext = event->next->next;
+ free(event->next);
+ event->next = nextnext;
+ } else {
+ event = event->next;
+ }
+ }
+
return dive;
}
diff --git a/dive.h b/dive.h
index 114ab9cbf..a6ba61519 100644
--- a/dive.h
+++ b/dive.h
@@ -233,6 +233,7 @@ struct event {
struct event *next;
duration_t time;
int type, flags, value;
+ gboolean deleted;
char name[];
};
diff --git a/gtk-gui.c b/gtk-gui.c
index 665a4abef..690b2a488 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -1231,7 +1231,7 @@ void attach_tooltip(int x, int y, int w, int h, const char *text)
rect->y = y;
rect->width = w;
rect->height = h;
- tooltip_rects[tooltips].text = text;
+ tooltip_rects[tooltips].text = strdup(text);
tooltips++;
}
diff --git a/profile.c b/profile.c
index e20527986..7902560f3 100644
--- a/profile.c
+++ b/profile.c
@@ -15,6 +15,7 @@
#include "display-gtk.h"
#include "divelist.h"
#include "color.h"
+#include "libdivecomputer/parser.h"
int selected_dive = 0;
char zoomed_plot = 0;
@@ -345,6 +346,7 @@ static void plot_one_event(struct graphics_context *gc, struct plot_info *pi, st
{
int i, depth = 0;
int x,y;
+ char buffer[80];
/* is plotting this event disabled? */
if (event->name) {
@@ -380,7 +382,11 @@ static void plot_one_event(struct graphics_context *gc, struct plot_info *pi, st
cairo_line_to(gc->cr, x-9, y+4);
cairo_stroke(gc->cr);
/* we display the event on screen - so translate */
- attach_tooltip(x-15, y-6, 12, 12, _(event->name));
+ if (event->value)
+ snprintf(buffer, sizeof(buffer), "%s: %d", _(event->name), event->value);
+ else
+ snprintf(buffer, sizeof(buffer), "%s", _(event->name));
+ attach_tooltip(x-15, y-6, 12, 12, buffer);
}
static void plot_events(struct graphics_context *gc, struct plot_info *pi, struct dive *dive)
@@ -392,7 +398,8 @@ static void plot_events(struct graphics_context *gc, struct plot_info *pi, struc
return;
while (event) {
- plot_one_event(gc, pi, event, &tro);
+ if (event->flags != SAMPLE_FLAGS_BEGIN && event->flags != SAMPLE_FLAGS_END)
+ plot_one_event(gc, pi, event, &tro);
event = event->next;
}
}