aboutsummaryrefslogtreecommitdiff
path: root/simloop/test/simloop_test.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2026-04-26 13:06:44 -0700
committer3gg <3gg@shellblade.net>2026-04-26 13:06:44 -0700
commit48422e313b31b79d76dd8f027b4d934994168859 (patch)
tree8235fe036e556ee3810d0a57846be7f666b1a894 /simloop/test/simloop_test.c
parente014d3cc269c636767528f2cdd716fc6badcaa89 (diff)
Test for catch-up. Document
Diffstat (limited to 'simloop/test/simloop_test.c')
-rw-r--r--simloop/test/simloop_test.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/simloop/test/simloop_test.c b/simloop/test/simloop_test.c
index 50e0852..790ad73 100644
--- a/simloop/test/simloop_test.c
+++ b/simloop/test/simloop_test.c
@@ -250,4 +250,58 @@ TEST_CASE(simloop_determinism) {
250 TEST_EQUAL(sim[0].sum, sim[1].sum); 250 TEST_EQUAL(sim[0].sum, sim[1].sum);
251} 251}
252 252
253/// The simulation loop attempts to catch up with the clock in the event of a
254/// time spike. This is possible only if the simulation loops with a frequency
255/// higher than the requested update frequency given by the update delta time.
256static void simloop_catch_up(
257 struct test_case_metadata* metadata, int update_ddt_ms, int loop_step_ms,
258 bool expect_catchup) {
259 const int UPDATE_FPS = 1000 / update_ddt_ms;
260 const simloop_time_t UPDATE_DDT =
261 time_delta_from_sec(1.0 / (double)UPDATE_FPS);
262 const simloop_time_t STEP =
263 time_delta_from_sec((double)loop_step_ms / 1000.0);
264 const simloop_time_t SIM_DURATION_SEC = time_delta_from_sec(30);
265 const int EXPECTED_TOTAL_FRAMES_WITH_CATCHUP =
266 (int)(SIM_DURATION_SEC / UPDATE_DDT);
267
268 Simloop simloop = simloop_make(&(SimloopArgs){.update_fps = UPDATE_FPS});
269 SimloopOut simout;
270 int frames = 0;
271
272 // Simulate a time spike.
273 // Advance time to t=10s. That is a lag of 10,000ms / 100ms = 100 frames.
274 // The simulation now has 20s to catch up.
275 simloop_time_t dt = time_delta_from_sec(10);
276 for (simloop_time_t t = dt; t <= SIM_DURATION_SEC;) {
277 simloop_update(&simloop, dt, &simout);
278
279 if (simout.should_update) {
280 frames++;
281 }
282
283 // New delta is as usual.
284 dt = STEP;
285 t += dt;
286 }
287
288 if (expect_catchup) {
289 TEST_EQUAL(frames, EXPECTED_TOTAL_FRAMES_WITH_CATCHUP);
290 } else {
291 TEST_TRUE(frames < EXPECTED_TOTAL_FRAMES_WITH_CATCHUP);
292 }
293}
294/// (Loop frequency > update frequency) => successful catch-up.
295TEST_CASE(simloop_catch_up_success) {
296 constexpr int UPDATE_DDT_MS = 100;
297 constexpr int LOOP_DDT_MS = 10;
298 simloop_catch_up(metadata, UPDATE_DDT_MS, LOOP_DDT_MS, true);
299}
300/// (Loop frequency < update frequency) => failed catch-up.
301TEST_CASE(simloop_catch_up_failure) {
302 constexpr int UPDATE_DDT_MS = 10;
303 constexpr int LOOP_DDT_MS = 100;
304 simloop_catch_up(metadata, UPDATE_DDT_MS, LOOP_DDT_MS, false);
305}
306
253int main() { return 0; } 307int main() { return 0; }