aboutsummaryrefslogtreecommitdiff
path: root/simloop/include/simloop.h
diff options
context:
space:
mode:
Diffstat (limited to 'simloop/include/simloop.h')
-rw-r--r--simloop/include/simloop.h38
1 files changed, 36 insertions, 2 deletions
diff --git a/simloop/include/simloop.h b/simloop/include/simloop.h
index f267d40..6ee3b98 100644
--- a/simloop/include/simloop.h
+++ b/simloop/include/simloop.h
@@ -3,6 +3,37 @@
3 * This implements a simulation loop but in a way that the client retains 3 * This implements a simulation loop but in a way that the client retains
4 * control flow. The client steps the loop and then checks whether the 4 * control flow. The client steps the loop and then checks whether the
5 * simulation must be updated and/or the result rendered. 5 * simulation must be updated and/or the result rendered.
6 *
7 * If the simulation's update cannot keep up with the desired frame rate, then
8 * the loop degrades to match the simulation's rate by requesting a single
9 * update.
10 *
11 * Under a variable time delta, the loop could simply update the simulation
12 * with a large delta that puts the simulation back into the current clock
13 * time. Under a fixed time delta this isn't possible, and we seem to have two
14 * choices instead:
15 *
16 * a) Queue as many updates as necessary to bring the simulation back to the
17 * current clock time (time_diff / fixed_delta).
18 *
19 * b) Queue a single update.
20 *
21 * The issue with (a) is that the number of requested updates diverges and
22 * eventually the simulation appears to freeze. At every loop, the number of
23 * queued updates increases with respect to the last iteration as the
24 * simulation fails to keep up with the desired frame rate. Example:
25 *
26 * desired delta = 10ms (100 fps)
27 * actual delta = 20ms ( 50 fps)
28 * ---------------------------
29 * iter, sim time, clock time
30 * ---------------------------
31 * 0, 0, 0, initial state
32 * 1, 0, 10, queue 1 update
33 * 2, 10, 30, queue (30-10)/10 = 2 updates
34 * 3, 30, 70, queue (70-30)/10 = 4 updates
35 * 4, 70, 150, queue (150-70)/10 = 8 updates
36 * ...
6 */ 37 */
7#pragma once 38#pragma once
8 39
@@ -21,8 +52,8 @@ typedef struct SimloopOut {
21 time_delta render_elapsed; ///< Amount of time elapsed in the rendering. 52 time_delta render_elapsed; ///< Amount of time elapsed in the rendering.
22 time_delta update_elapsed; ///< Amount of time elapsed in the simulation. 53 time_delta update_elapsed; ///< Amount of time elapsed in the simulation.
23 time_delta update_dt; ///< Delta time for simulation updates. 54 time_delta update_dt; ///< Delta time for simulation updates.
24 int updates_pending; ///< Number of frames the simulation should produce. 55 bool should_update; ///< Whether the simulation should update.
25 bool should_render; ///< Whether the simulation should be rendered. 56 bool should_render; ///< Whether the simulation should be rendered.
26} SimloopOut; 57} SimloopOut;
27 58
28typedef struct SimloopTimeline { 59typedef struct SimloopTimeline {
@@ -35,10 +66,13 @@ typedef struct Simloop {
35 SimloopTimeline render; ///< Render timeline. 66 SimloopTimeline render; ///< Render timeline.
36 uint64_t frame; ///< Frame counter. 67 uint64_t frame; ///< Frame counter.
37 Timer* timer; 68 Timer* timer;
69 bool first_iter;
38} Simloop; 70} Simloop;
39 71
40/// Create a simulation loop. 72/// Create a simulation loop.
41Simloop simloop_make(const SimloopArgs*); 73Simloop simloop_make(const SimloopArgs*);
42 74
43/// Step the simulation loop. 75/// Step the simulation loop.
76///
77/// The simulation always triggers a render of the initial state of simulation.
44void simloop_update(Simloop*, SimloopOut*); 78void simloop_update(Simloop*, SimloopOut*);