From: Antonio Ospite <ospite@studenti.unina.it>
Date: Sun, 14 Jul 2013 11:14:26 +0000 (+0200)
Subject: Factor out some more useful functions
X-Git-Url: https://git.ao2.it/experiments/fps-limit.git/commitdiff_plain/79510a9d3bee77059bd543413ccc9aa739881c52

Factor out some more useful functions
---

diff --git a/fps-limit.c b/fps-limit.c
index 7759349..3ed784f 100644
--- a/fps-limit.c
+++ b/fps-limit.c
@@ -18,6 +18,7 @@
  */
 
 #include <stdio.h>
+#include <string.h>
 #include <time.h>
 
 #ifdef DEBUG
@@ -45,34 +46,61 @@
 		}                                                \
 	} while(0)
 
-int main(void)
-{
+struct fps_limit_stats {
 	struct timespec time_start;
 	struct timespec time_end;
+	unsigned int fps;
+};
+
+static void fps_limit_init(struct fps_limit_stats *stats, unsigned int fps)
+{
+	memset(stats, 0, sizeof(*stats));
+
+	clock_gettime(CLOCK_MONOTONIC, &stats->time_start);
+	dbg("Init time: s: %ld, ns: %ld", stats->time_start.tv_sec, stats->time_start.tv_nsec);
+
+	stats->fps = fps;
+}
+
+static void fps_limit_sleep(struct fps_limit_stats *stats)
+{
 	struct timespec elapsed;
-	struct timespec remaining = {0, 0};
 
+	dbg("Start time: s: %ld, ns: %ld", stats->time_start.tv_sec, stats->time_start.tv_nsec);
+
+	clock_gettime(CLOCK_MONOTONIC, &stats->time_end);
+	dbg("End time: s: %ld, ns: %ld", stats->time_end.tv_sec, stats->time_end.tv_nsec);
+
+	timespecsub(&stats->time_end, &stats->time_start, &elapsed);
+	dbg("Elapsed s: %ld ns: %ld", elapsed.tv_sec, elapsed.tv_nsec);
+
+	if (elapsed.tv_sec == 0 && elapsed.tv_nsec < NSEC_PER_SEC / stats->fps) {
+		struct timespec remaining = {0, 0};
+
+		/* remaining delay, _relative_ to time_end */
+		remaining.tv_nsec = (NSEC_PER_SEC / stats->fps) - elapsed.tv_nsec;
+		dbg("Sleeping for: ns: %ld", remaining.tv_nsec);
+
+		clock_nanosleep(CLOCK_MONOTONIC, 0, &remaining, NULL);
+	}
+
+	/* update the stats for the next iteration */
+	clock_gettime(CLOCK_MONOTONIC, &stats->time_start);
+}
+
+int main(void)
+{
+	struct fps_limit_stats stats;
 	struct timespec tmp;
 
+	fps_limit_init(&stats, FPS);
 	while (1) {
-		clock_gettime(CLOCK_MONOTONIC, &time_start);
-		dbg("Start time: s: %ld, ns: %ld", time_start.tv_sec, time_start.tv_nsec);
-
 		dbg("Doing some work, max: %d", NSEC_PER_SEC / FPS);
 		tmp.tv_sec = 0;
 		tmp.tv_nsec = (NSEC_PER_SEC / FPS) * 2 / 3;
 		nanosleep(&tmp, NULL);
 
-		clock_gettime(CLOCK_MONOTONIC, &time_end);
-		dbg("End time: s: %ld, ns: %ld", time_end.tv_sec, time_end.tv_nsec);
-		timespecsub(&time_end, &time_start, &elapsed);
-		dbg("Elapsed s: %ld ns: %ld", elapsed.tv_sec, elapsed.tv_nsec);
-		if (elapsed.tv_sec == 0 && elapsed.tv_nsec < NSEC_PER_SEC / FPS) {
-			/* remaining delay, _relative_ to time_end */
-			remaining.tv_nsec = (NSEC_PER_SEC / FPS) - elapsed.tv_nsec;
-			dbg("Sleeping for: ns: %ld", remaining.tv_nsec);
-			clock_nanosleep(CLOCK_MONOTONIC, 0, &remaining, NULL);
-		}
+		fps_limit_sleep(&stats);
 	}
 
 	return 0;