On Wed, Aug 6, 2014 at 9:06 AM, Dirk Hohndel <d...@hohndel.org> wrote:
>
> Well, let's revert my amateur patch and use the one from the expert.

No, don't revert it, I have a interdiff. And your patch fixed some of
the 0.00 cases fine, so it doesn't *all* need to be reverted, it just
didn't fix the statistics page right.

So try this. I have *not* tested it with the odd cases that I tested
things originally, but the code hasn't really changed and it should
all be ok. And I updated the commit message, so it should be better.

It's called "0002" because "0001" is my "private trips for downloads" thing.

              Linus
From 2e46a8c371ec8e0832a0271c0420a52c5cdcba66 Mon Sep 17 00:00:00 2001
From: Linus Torvalds <torva...@linux-foundation.org>
Date: Wed, 30 Jul 2014 10:08:33 -0700
Subject: [PATCH 2/2] Make gas use statistics be coherent and more complete

The gas use logic in the dive statistics page is confused.

The SAC case had a special case for "unknown", but only for
the first gas. Other gases had the normal empty case.

Also, the logic was really odd - if you had gases that weren't used (or
pressures not known) intermixed with gases you *did* have pressure for,
the statistics got really confused.

The list of gases showed all gases that we know about during the dive,
but then the gas use and SAC-rate lists wouldn't necessarily match,
because the loops that computed those stopped after the first gas that
didn't have any pressure change.

To make things worse, the first cylinder was special-cased again, so it
all lined up for the single-cylinder case.

This makes all the cylinders act the same way, leaving unknown gas use
(and thus SAC) just empty for that gas.

It also fixes the SAC calculation case where we don't have real samples,
and the profile is a fake profile - possibly with gas changes in between
the fake points. We now make the SAC calculations match what we show -
which is admittedly not at all necessarily what the dive was, but at
least we're consistent.

Signed-off-by: Linus Torvalds <torva...@linux-foundation.org>
---
 dive.c            | 17 ++++++++++++++++-
 qt-ui/maintab.cpp | 32 +++++++++++++++++---------------
 statistics.c      | 27 ---------------------------
 statistics.h      |  1 -
 4 files changed, 33 insertions(+), 44 deletions(-)

diff --git a/dive.c b/dive.c
index c981cc100753..4f7da788462f 100644
--- a/dive.c
+++ b/dive.c
@@ -7,6 +7,7 @@
 #include "gettext.h"
 #include "dive.h"
 #include "libdivecomputer.h"
+#include "device.h"
 
 /* one could argue about the best place to have this variable -
  * it's used in the UI, but it seems to make the most sense to have it
@@ -586,14 +587,28 @@ void per_cylinder_mean_depth(struct dive *dive, struct divecomputer *dc, int *me
 		duration[0] = dc->duration.seconds;
 		return;
 	}
+	if (!dc->samples)
+		dc = fake_dc(dc);
 	for (i = 0; i < dc->samples; i++) {
 		struct sample *sample = dc->sample + i;
 		int time = sample->time.seconds;
 		int depth = sample->depth.mm;
-		if (ev && time >= ev->time.seconds) {
+
+		/* Make sure to move the event past 'lasttime' */
+		while (ev && lasttime >= ev->time.seconds) {
 			idx = get_cylinder_index(dive, ev);
 			ev = get_next_event(ev->next, "gaschange");
 		}
+
+		/* Do we need to fake a midway sample at an event? */
+		if (ev && time > ev->time.seconds) {
+			int newtime = ev->time.seconds;
+			int newdepth = interpolate(lastdepth, depth, newtime - lasttime, time - lasttime);
+
+			time = newtime;
+			depth = newdepth;
+			i--;
+		}
 		/* We ignore segments at the surface */
 		if (depth > SURFACE_THRESHOLD || lastdepth > SURFACE_THRESHOLD) {
 			duration[idx] += time - lasttime;
diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp
index 075bfb734fa9..ed65a1943d8e 100644
--- a/qt-ui/maintab.cpp
+++ b/qt-ui/maintab.cpp
@@ -472,28 +472,30 @@ void MainTab::updateDiveInfo(bool clear)
 		ui.airTemperatureText->setText(get_temperature_string(displayed_dive.airtemp, true));
 		volume_t gases[MAX_CYLINDERS] = {};
 		get_gas_used(&displayed_dive, gases);
-		QString volumes = get_volume_string(gases[0], true);
+		QString volumes;
 		int mean[MAX_CYLINDERS], duration[MAX_CYLINDERS];
 		per_cylinder_mean_depth(&displayed_dive, select_dc(&displayed_dive), mean, duration);
 		volume_t sac;
-		QString SACs;
-		if (mean[0] && duration[0] && gases[0].mliter) {
-			sac.mliter = gases[0].mliter / (depth_to_atm(mean[0], &displayed_dive) * duration[0] / 60.0);
-			SACs = get_volume_string(sac, true).append(tr("/min"));
-		} else {
-			SACs = QString(tr("unknown"));
-		}
-		for (int i = 1; i < MAX_CYLINDERS && gases[i].mliter != 0; i++) {
-			volumes.append("\n" + get_volume_string(gases[i], true));
-			if (duration[i] && gases[i].mliter) {
+		QString gaslist, SACs, separator;
+
+		gaslist = ""; SACs = ""; volumes = ""; separator = "";
+		for (int i = 0; i < MAX_CYLINDERS; i++) {
+			if (!is_cylinder_used(&displayed_dive, i))
+				continue;
+			gaslist.append(separator); volumes.append(separator); SACs.append(separator);
+			separator = "\n";
+
+			gaslist.append(gasname(&displayed_dive.cylinder[i].gasmix));
+			if (!gases[i].mliter)
+				continue;
+			volumes.append(get_volume_string(gases[i], true));
+			if (duration[i]) {
 				sac.mliter = gases[i].mliter / (depth_to_atm(mean[i], &displayed_dive) * duration[i] / 60);
-				SACs.append("\n" + get_volume_string(sac, true).append(tr("/min")));
-			} else {
-				SACs.append("\n");
+				SACs.append(get_volume_string(sac, true).append(tr("/min")));
 			}
 		}
 		ui.gasUsedText->setText(volumes);
-		ui.oxygenHeliumText->setText(get_gaslist(&displayed_dive));
+		ui.oxygenHeliumText->setText(gaslist);
 		ui.dateText->setText(get_short_dive_date_string(displayed_dive.when));
 		ui.diveTimeText->setText(QString::number((int)((displayed_dive.duration.seconds + 30) / 60)));
 		if (prevd)
diff --git a/statistics.c b/statistics.c
index 21b386b21554..01adf4f14497 100644
--- a/statistics.c
+++ b/statistics.c
@@ -331,33 +331,6 @@ void get_gas_used(struct dive *dive, volume_t gases[MAX_CYLINDERS])
 	}
 }
 
-#define MAXBUF 80
-/* for the O2/He readings just create a list of them */
-char *get_gaslist(struct dive *dive)
-{
-	int idx, offset = 0;
-	static char buf[MAXBUF];
-
-	buf[0] = '\0';
-	for (idx = 0; idx < MAX_CYLINDERS; idx++) {
-		cylinder_t *cyl;
-		if (!is_cylinder_used(dive, idx))
-			continue;
-		cyl = &dive->cylinder[idx];
-		if (offset > 0) {
-			strncpy(buf + offset, "\n", MAXBUF - offset);
-			offset = strlen(buf);
-		}
-		strncpy(buf + offset, gasname(&cyl->gasmix), MAXBUF - offset);
-		offset = strlen(buf);
-	}
-	if (*buf == '\0')
-		strncpy(buf, translate("gettextFromC", "air"), MAXBUF);
-
-	buf[MAXBUF - 1] = '\0';
-	return buf;
-}
-
 /* Quite crude reverse-blender-function, but it produces a approx result */
 static void get_gas_parts(struct gasmix mix, volume_t vol, int o2_in_topup, volume_t *o2, volume_t *he)
 {
diff --git a/statistics.h b/statistics.h
index e28fb8f55115..4d14139e63ec 100644
--- a/statistics.h
+++ b/statistics.h
@@ -45,7 +45,6 @@ extern char *get_minutes(int seconds);
 extern void process_all_dives(struct dive *dive, struct dive **prev_dive);
 extern void get_selected_dives_text(char *buffer, int size);
 extern void get_gas_used(struct dive *dive, volume_t gases[MAX_CYLINDERS]);
-extern char *get_gaslist(struct dive *dive);
 extern void process_selected_dives(void);
 void selected_dives_gas_parts(volume_t *o2_tot, volume_t *he_tot);
 
-- 
2.1.0.rc0.52.gaa544bf

_______________________________________________
subsurface mailing list
subsurface@hohndel.org
http://lists.hohndel.org/cgi-bin/mailman/listinfo/subsurface

Reply via email to