From c35a8302c6275a1ba71dcdff15f58310d064a909 Mon Sep 17 00:00:00 2001
From: rodri <rgl@antares-labs.eu>
Date: Mon, 8 Mar 2021 21:01:40 +0000
Subject: refactor statistics code to make it more general purpose.

---
 dat.h   | 14 ++++++++++++--
 fns.h   |  8 ++++++++
 main.c  | 11 +++--------
 mkfile  |  1 +
 stats.c | 18 ++++++++++++++++++
 5 files changed, 42 insertions(+), 10 deletions(-)
 create mode 100644 stats.c

diff --git a/dat.h b/dat.h
index 6503042..4dd4250 100644
--- a/dat.h
+++ b/dat.h
@@ -1,11 +1,21 @@
 typedef struct State State;
 typedef struct Derivative Derivative;
+typedef struct Stats Stats;
+
+struct Stats
+{
+	double cur;
+	double total;
+	double min, avg, max;
+	uvlong nupdates;
+
+	void (*update)(Stats*, double);
+};
 
 struct State
 {
 	double x, v;
-	double acc, min, max, avg;
-	int nsteps;
+	Stats stats;
 };
 
 struct Derivative
diff --git a/fns.h b/fns.h
index ece9b68..2325ae1 100644
--- a/fns.h
+++ b/fns.h
@@ -1,3 +1,11 @@
+/*
+ *	alloc
+ */
 void *emalloc(ulong);
 void *erealloc(void*, ulong);
 Image *eallocimage(Display*, Rectangle, ulong, int, ulong);
+
+/*
+ *	stats
+ */
+void statsupdate(Stats*, double);
diff --git a/main.c b/main.c
index 106b31f..c7ae3a3 100644
--- a/main.c
+++ b/main.c
@@ -13,9 +13,6 @@ State state;
 double t, Δt;
 
 
-double min(double a, double b) { return a < b? a: b; }
-double max(double a, double b) { return a > b? a: b; }
-
 /*
  *	Dynamics stepper
  *
@@ -153,7 +150,7 @@ redraw(void)
 
 	draw(screen, screen->r, display->black, nil, ZP);
 	drawtimestep(t);
-	drawbar(state.min); drawbar(state.max); drawbar(state.avg);
+	drawbar(state.stats.min); drawbar(state.stats.max); drawbar(state.stats.avg);
 	fillellipse(screen, toscreen(Pt2(0,state.x,1)), 2, 2, display->white, ZP);
 
 	flushimage(display, 1);
@@ -176,6 +173,7 @@ resetsim(void)
 {
 	memset(&state, 0, sizeof(State));
 	state.x = 100;
+	state.stats.update = statsupdate;
 	t = 0;
 }
 
@@ -275,10 +273,7 @@ threadmain(int argc, char *argv[])
 
 		integrate(&state, t, Δt);
 
-		state.acc += state.x;
-		state.avg = state.acc/++state.nsteps;
-		state.min = min(state.min, state.x);
-		state.max = max(state.max, state.x);
+		state.stats.update(&state.stats, state.x);
 
 		redraw();
 
diff --git a/mkfile b/mkfile
index 5c8fdf6..278bf28 100644
--- a/mkfile
+++ b/mkfile
@@ -4,6 +4,7 @@ BIN=/$objtype/bin/games
 TARG=physics
 OFILES=\
 	alloc.$O\
+	stats.$O\
 	main.$O\
 
 HFILES=\
diff --git a/stats.c b/stats.c
new file mode 100644
index 0000000..2232937
--- /dev/null
+++ b/stats.c
@@ -0,0 +1,18 @@
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include "dat.h"
+#include "fns.h"
+
+static double min(double a, double b) { return a < b? a: b; }
+static double max(double a, double b) { return a > b? a: b; }
+
+void
+statsupdate(Stats *s, double n)
+{
+	s->cur = n;
+	s->total += s->cur;
+	s->avg = s->total/++s->nupdates;
+	s->min = min(s->cur, s->min);
+	s->max = max(s->cur, s->max);
+}
-- 
cgit v1.2.3