[PATCH 4/4] Start using the actual cylinder data for gas switch events

Linus Torvalds torvalds at linux-foundation.org
Sat Apr 2 14:40:33 PDT 2016


From: Linus Torvalds <torvalds at linux-foundation.org>
Date: Sat, 2 Apr 2016 16:07:06 -0500
Subject: [PATCH 4/4] Start using the actual cylinder data for gas switch events

Now that gas switch events always have indices into the cylinder table,
start using that to look up the gas mix from the cylinders rather than
from the gas switch event itself.  In other words, the cylinder index is
now the primary data for gas switch events.

This means that now as you change the cylinder information, the gas
switch events will automatically update to reflect those changes.

Note that on loading data from the outside (either from a xml file, from
a git/cloud account, or from a dive computer), we may or may not
initially have an index for the gas change event.  The external data may
be from an older version of subsurface, or it may be from a
libdivecomputer download that just doesn't give index data at all.

In that case, we will do:

 - if there is no index, but there is explicit gas mix information, we
   will look up the index based on that gas mix, picking the cylinder
   that has the closest mix.

 - if there isn't even explicit gas mix data, so we only have the event
   value from libdivecomputer, we will turn that value into a gasmix,
   and use that to look up the cylinder index as above.

 - if no valid cylinder information is available at all, gas switch
   events will just be dropped.

When saving the data, we now always save the cylinder index, and the gas
mix associated with that cylinder (that gas mix will be ignored on load,
since the index is the primary, but it makes the event much easier to
read).

It is worth noting we do not modify the libdivecomputer value, even if
the gasmix has changed, so that remains as a record of the original
download.

Signed-off-by: Linus Torvalds <torvalds at linux-foundation.org>
---

This is the patch that allows you to actually edit the cylinder 
gasmix, and the gas switch data will automatically update correctly.

Before, it was really easy to generate nonsensical gas switches, where you 
might switch to a gas that just didn't actually exist.

 profile-widget/diveeventitem.cpp | 25 ++++++++++++++-----------
 subsurface-core/dive.c           |  6 +++++-
 subsurface-core/save-git.c       | 24 ++++++++++++++----------
 subsurface-core/save-xml.c       | 24 ++++++++++++++----------
 4 files changed, 47 insertions(+), 32 deletions(-)

diff --git a/profile-widget/diveeventitem.cpp b/profile-widget/diveeventitem.cpp
index 3e1de48f372a..709be6839d05 100644
--- a/profile-widget/diveeventitem.cpp
+++ b/profile-widget/diveeventitem.cpp
@@ -94,9 +94,10 @@ void DiveEventItem::setupPixmap()
 		transparentPixmap.fill(QColor::fromRgbF(1.0, 1.0, 1.0, 0.01));
 		setPixmap(transparentPixmap);
 	} else if (event_is_gaschange(internalEvent)) {
-		if (internalEvent->gas.mix.he.permille)
+		struct gasmix *mix = get_gasmix_from_event(&displayed_dive, internalEvent);
+		if (mix->he.permille)
 			setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeTrimix"));
-		else if (gasmix_is_air(&internalEvent->gas.mix))
+		else if (gasmix_is_air(mix))
 			setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeAir"));
 		else
 			setPixmap(EVENT_PIXMAP_BIGGER(":gaschangeNitrox"));
@@ -112,15 +113,17 @@ void DiveEventItem::setupToolTipString()
 	QString name = gettextFromC::instance()->tr(internalEvent->name);
 	int value = internalEvent->value;
 	int type = internalEvent->type;
-	if (value) {
-		if (event_is_gaschange(internalEvent)) {
-			name += ": ";
-			name += gasname(&internalEvent->gas.mix);
-
-			/* Do we have an explicit cylinder index?  Show it. */
-			if (internalEvent->gas.index >= 0)
-				name += QString(" (cyl %1)").arg(internalEvent->gas.index+1);
-		} else if (type == SAMPLE_EVENT_PO2 && name == "SP change") {
+
+	if (event_is_gaschange(internalEvent)) {
+		struct gasmix *mix = get_gasmix_from_event(&displayed_dive, internalEvent);
+		name += ": ";
+		name += gasname(mix);
+
+		/* Do we have an explicit cylinder index?  Show it. */
+		if (internalEvent->gas.index >= 0)
+			name += QString(" (cyl %1)").arg(internalEvent->gas.index+1);
+	} else if (value) {
+		if (type == SAMPLE_EVENT_PO2 && name == "SP change") {
 			name += QString(":%1").arg((double)value / 1000);
 		} else {
 			name += QString(":%1").arg(value);
diff --git a/subsurface-core/dive.c b/subsurface-core/dive.c
index 04e83339d4b6..6d899e2a1819 100644
--- a/subsurface-core/dive.c
+++ b/subsurface-core/dive.c
@@ -158,8 +158,12 @@ void add_extra_data(struct divecomputer *dc, const char *key, const char *value)
 struct gasmix *get_gasmix_from_event(struct dive *dive, struct event *ev)
 {
 	static struct gasmix dummy;
-	if (ev && event_is_gaschange(ev))
+	if (ev && event_is_gaschange(ev)) {
+		int index = ev->gas.index;
+		if (index >= 0 && index <= MAX_CYLINDERS)
+			return &dive->cylinder[index].gasmix;
 		return &ev->gas.mix;
+	}
 
 	return &dummy;
 }
diff --git a/subsurface-core/save-git.c b/subsurface-core/save-git.c
index 5e658ca29c26..4d9cd38e1818 100644
--- a/subsurface-core/save-git.c
+++ b/subsurface-core/save-git.c
@@ -220,10 +220,15 @@ static void show_date(struct membuffer *b, timestamp_t when)
 		   tm.tm_hour, tm.tm_min, tm.tm_sec);
 }
 
+static void show_integer(struct membuffer *b, int value, const char *pre, const char *post)
+{
+	put_format(b, " %s%d%s", pre, value, post);
+}
+
 static void show_index(struct membuffer *b, int value, const char *pre, const char *post)
 {
 	if (value)
-		put_format(b, " %s%d%s", pre, value, post);
+		show_integer(b, value, pre, post);
 }
 
 /*
@@ -314,7 +319,7 @@ static void save_samples(struct membuffer *b, int nr, struct sample *s)
 	}
 }
 
-static void save_one_event(struct membuffer *b, struct event *ev)
+static void save_one_event(struct membuffer *b, struct dive *dive, struct event *ev)
 {
 	put_format(b, "event %d:%02d", FRACTION(ev->time.seconds, 60));
 	show_index(b, ev->type, "type=", "");
@@ -322,19 +327,18 @@ static void save_one_event(struct membuffer *b, struct event *ev)
 	show_index(b, ev->value, "value=", "");
 	show_utf8(b, " name=", ev->name, "");
 	if (event_is_gaschange(ev)) {
-		if (ev->gas.index >= 0) {
-			show_index(b, ev->gas.index, "cylinder=", "");
-			put_gasmix(b, &ev->gas.mix);
-		} else
-			put_gasmix(b, &ev->gas.mix);
+		struct gasmix *mix = get_gasmix_from_event(dive, ev);
+		if (ev->gas.index >= 0)
+			show_integer(b, ev->gas.index, "cylinder=", "");
+		put_gasmix(b, mix);
 	}
 	put_string(b, "\n");
 }
 
-static void save_events(struct membuffer *b, struct event *ev)
+static void save_events(struct membuffer *b, struct dive *dive, struct event *ev)
 {
 	while (ev) {
-		save_one_event(b, ev);
+		save_one_event(b, dive, ev);
 		ev = ev->next;
 	}
 }
@@ -362,7 +366,7 @@ static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer
 	put_duration(b, dc->surfacetime, "surfacetime ", "min\n");
 
 	save_extra_data(b, dc->extra_data);
-	save_events(b, dc->events);
+	save_events(b, dive, dc->events);
 	save_samples(b, dc->samples, dc->sample);
 }
 
diff --git a/subsurface-core/save-xml.c b/subsurface-core/save-xml.c
index 045e47c55bc7..80dda63b8ae7 100644
--- a/subsurface-core/save-xml.c
+++ b/subsurface-core/save-xml.c
@@ -178,10 +178,15 @@ static void save_weightsystem_info(struct membuffer *b, struct dive *dive)
 	}
 }
 
+static void show_integer(struct membuffer *b, int value, const char *pre, const char *post)
+{
+	put_format(b, " %s%d%s", pre, value, post);
+}
+
 static void show_index(struct membuffer *b, int value, const char *pre, const char *post)
 {
 	if (value)
-		put_format(b, " %s%d%s", pre, value, post);
+		show_integer(b, value, pre, post);
 }
 
 static void save_sample(struct membuffer *b, struct sample *sample, struct sample *old)
@@ -258,7 +263,7 @@ static void save_sample(struct membuffer *b, struct sample *sample, struct sampl
 	put_format(b, " />\n");
 }
 
-static void save_one_event(struct membuffer *b, struct event *ev)
+static void save_one_event(struct membuffer *b, struct dive *dive, struct event *ev)
 {
 	put_format(b, "  <event time='%d:%02d min'", FRACTION(ev->time.seconds, 60));
 	show_index(b, ev->type, "type='", "'");
@@ -266,20 +271,19 @@ static void save_one_event(struct membuffer *b, struct event *ev)
 	show_index(b, ev->value, "value='", "'");
 	show_utf8(b, ev->name, " name='", "'", 1);
 	if (event_is_gaschange(ev)) {
-		if (ev->gas.index >= 0) {
-			show_index(b, ev->gas.index, "cylinder='", "'");
-			put_gasmix(b, &ev->gas.mix);
-		} else
-			put_gasmix(b, &ev->gas.mix);
+		struct gasmix *mix = get_gasmix_from_event(dive, ev);
+		if (ev->gas.index >= 0)
+			show_integer(b, ev->gas.index, "cylinder='", "'");
+		put_gasmix(b, mix);
 	}
 	put_format(b, " />\n");
 }
 
 
-static void save_events(struct membuffer *b, struct event *ev)
+static void save_events(struct membuffer *b, struct dive *dive, struct event *ev)
 {
 	while (ev) {
-		save_one_event(b, ev);
+		save_one_event(b, dive, ev);
 		ev = ev->next;
 	}
 }
@@ -360,7 +364,7 @@ static void save_dc(struct membuffer *b, struct dive *dive, struct divecomputer
 	save_salinity(b, dc);
 	put_duration(b, dc->surfacetime, "  <surfacetime>", " min</surfacetime>\n");
 	save_extra_data(b, dc->extra_data);
-	save_events(b, dc->events);
+	save_events(b, dive, dc->events);
 	save_samples(b, dc->samples, dc->sample);
 
 	put_format(b, "  </divecomputer>\n");
-- 
2.8.0.rc4.303.g3931579



More information about the subsurface mailing list