summaryrefslogtreecommitdiffstats
path: root/profile.c
diff options
context:
space:
mode:
authorGravatar Linus Torvalds <torvalds@linux-foundation.org>2013-01-24 17:55:48 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-01-24 19:12:28 -0800
commitcb0d6d6eaf549d593557490eb690bb22e91de151 (patch)
tree2353aa02ff08021451e37fbf4ed6934430c2f7c1 /profile.c
parent002fe45dfd4776bb44a9e786625421a67558d60c (diff)
downloadsubsurface-cb0d6d6eaf549d593557490eb690bb22e91de151.tar.gz
Fix overly complicated and fragile "same_cylinder" logic
The plot-info per-event 'same_cylinder' logic was fragile, and caused us to not print the beginning pressure of the first cylinder. In particular, there was a nasty interaction with not all plot entries having pressures, and the whole logic that avoid some of the early plot entries because they are fake entries that are just there to make sure that we don't step off the edge of the world. When we then only do certain things on the particular entries that don't have the same cylinder as the last plot entry, things don't always happen like they should. Fix this by: - get rid of the computed "same_cylinder" state entirely. All the cases where we use it, we might as well just look at what the last cylinder we used was, and thus "same_cylinder" is just about testing the current cylinder index against that last index. - get rid of some of the edge conditions by just writing the loops more clearly, so that they simply don't have special cases. For example, instead of setting some "last_pressure" for a cylinder at cylinder changes, just set the damn thing on every single sample. The last pressure will automatically be the pressure we set last! The code is simpler and more straightforward. So this simplifies the code and just makes it less fragile - it doesn't matter if the cylinder change happens to happen at a sample that doesn't have a pressure reading, for example, because we no longer care so deeply about exactly which sample the cylinder change happens at. As a result, the bug Mika noticed just goes away. Reported-by: Miika Turkia <miika.turkia@gmail.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Diffstat (limited to 'profile.c')
-rw-r--r--profile.c49
1 files changed, 17 insertions, 32 deletions
diff --git a/profile.c b/profile.c
index 4b04d68ce..0963b5c76 100644
--- a/profile.c
+++ b/profile.c
@@ -30,7 +30,7 @@ static struct plot_data *last_pi_entry = NULL;
typedef enum { STABLE, SLOW, MODERATE, FAST, CRAZY } velocity_t;
struct plot_data {
- unsigned int same_cylinder:1, in_deco:1;
+ unsigned int in_deco:1;
unsigned int cylinderindex;
int sec;
/* pressure[0] is sensor pressure
@@ -193,9 +193,9 @@ static void dump_pi (struct plot_info *pi)
pi->maxpressure, pi->mintemp, pi->maxtemp);
for (i = 0; i < pi->nr; i++) {
struct plot_data *entry = &pi->entry[i];
- printf(" entry[%d]:{same_cylinder:%d cylinderindex:%d sec:%d pressure:{%d,%d}\n"
+ printf(" entry[%d]:{cylinderindex:%d sec:%d pressure:{%d,%d}\n"
" time:%d:%02d temperature:%d depth:%d stopdepth:%d stoptime:%d ndl:%d smoothed:%d po2:%lf phe:%lf pn2:%lf sum-pp %lf}\n",
- i, entry->same_cylinder, entry->cylinderindex, entry->sec,
+ i, entry->cylinderindex, entry->sec,
entry->pressure[0], entry->pressure[1],
entry->sec / 60, entry->sec % 60,
entry->temperature, entry->depth, entry->stopdepth, entry->stoptime, entry->ndl, entry->smoothed,
@@ -1018,7 +1018,7 @@ static void plot_cylinder_pressure(struct graphics_context *gc, struct plot_info
struct dive *dive)
{
int i;
- int last = -1;
+ int last = -1, last_index = -1;
int lift_pen = FALSE;
int first_plot = TRUE;
int sac = 0;
@@ -1034,7 +1034,7 @@ static void plot_cylinder_pressure(struct graphics_context *gc, struct plot_info
struct plot_data *entry = pi->entry + i;
mbar = GET_PRESSURE(entry);
- if (!entry->same_cylinder) {
+ if (entry->cylinderindex != last_index) {
lift_pen = TRUE;
last_entry = NULL;
}
@@ -1059,7 +1059,7 @@ static void plot_cylinder_pressure(struct graphics_context *gc, struct plot_info
}
set_sac_color(gc, sac, dive->sac);
if (lift_pen) {
- if (!first_plot && entry->same_cylinder) {
+ if (!first_plot && entry->cylinderindex == last_index) {
/* if we have a previous event from the same tank,
* draw at least a short line */
int prev_pr;
@@ -1076,6 +1076,7 @@ static void plot_cylinder_pressure(struct graphics_context *gc, struct plot_info
}
cairo_stroke(gc->cr);
move_to(gc, entry->sec, mbar);
+ last_index = entry->cylinderindex;
}
}
@@ -1102,37 +1103,23 @@ static void plot_cylinder_pressure_text(struct graphics_context *gc, struct plot
if (!get_cylinder_pressure_range(gc, pi))
return;
- /* only loop over the actual events from the dive computer
- * plus the second synthetic event at the start (to make sure
- * we get "time=0" right)
- * sadly with a recent change that first entry may no longer
- * have any pressure reading - in that case just grab the
- * pressure from the second entry */
- if (GET_PRESSURE(pi->entry + 1) == 0 && GET_PRESSURE(pi->entry + 2) !=0)
- INTERPOLATED_PRESSURE(pi->entry + 1) = GET_PRESSURE(pi->entry + 2);
- for (i = 1; i < pi->nr; i++) {
+ cyl = -1;
+ for (i = 0; i < pi->nr; i++) {
entry = pi->entry + i;
+ mbar = GET_PRESSURE(entry);
- if (!entry->same_cylinder) {
+ if (!mbar)
+ continue;
+ if (cyl != entry->cylinderindex) {
cyl = entry->cylinderindex;
if (!seen_cyl[cyl]) {
- mbar = GET_PRESSURE(entry);
plot_pressure_value(gc, mbar, entry->sec, LEFT, BOTTOM);
seen_cyl[cyl] = TRUE;
}
- if (i > 2) {
- /* remember the last pressure and time of
- * the previous cylinder */
- cyl = (entry - 1)->cylinderindex;
- last_pressure[cyl] = GET_PRESSURE(entry - 1);
- last_time[cyl] = (entry - 1)->sec;
- }
}
+ last_pressure[cyl] = mbar;
+ last_time[cyl] = entry->sec;
}
- cyl = entry->cylinderindex;
- if (GET_PRESSURE(entry))
- last_pressure[cyl] = GET_PRESSURE(entry);
- last_time[cyl] = entry->sec;
for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) {
if (last_time[cyl]) {
@@ -1766,14 +1753,12 @@ static void populate_pressure_information(struct dive *dive, struct divecomputer
entry = pi->entry + i;
- entry->same_cylinder = entry->cylinderindex == cylinderindex;
- cylinderindex = entry->cylinderindex;
-
/* discrete integration of pressure over time to get the SAC rate equivalent */
current->pressure_time += pressure_time(dive, entry-1, entry);
/* track the segments per cylinder and their pressure/time integral */
- if (!entry->same_cylinder) {
+ if (entry->cylinderindex != cylinderindex) {
+ cylinderindex = entry->cylinderindex;
current = pr_track_alloc(SENSOR_PRESSURE(entry), entry->sec);
track_pr[cylinderindex] = list_add(track_pr[cylinderindex], current);
} else { /* same cylinder */