#include #include #include /// An initial render should always trigger on frame 0. TEST_CASE(simloop_initial_render) { constexpr int UPDATE_FPS = 10; Timer timer = {}; Simloop simloop = simloop_make(&(SimloopArgs){ .update_fps = UPDATE_FPS, .max_render_fps = 0, .timer = &timer}); SimloopOut simout; simloop_update(&simloop, &simout); TEST_TRUE(simout.should_render); } /// A simulation loop with no render frame cap. TEST_CASE(simloop_test_no_render_frame_cap) { constexpr int UPDATE_FPS = 10; const time_delta STEP = sec_to_time_delta(1); const time_delta SIM_TIME_SEC = sec_to_time_delta(30); Timer timer = {}; Simloop simloop = simloop_make(&(SimloopArgs){ .update_fps = UPDATE_FPS, .max_render_fps = 0, .timer = &timer}); SimloopOut simout; for (time_delta t = STEP; t < SIM_TIME_SEC; t += STEP) { timer_advance(&timer, t); simloop_update(&simloop, &simout); TEST_TRUE(simout.should_render); TEST_EQUAL(simout.updates_pending, UPDATE_FPS); } } /// A simulation loop with a render frame cap. TEST_CASE(simloop_test_with_render_frame_cap) { constexpr int UPDATE_FPS = 10; constexpr int RENDER_FPS = 5; const time_delta STEP = sec_to_time_delta(0.1); const time_delta SIM_TIME_SEC = sec_to_time_delta(30); const time_delta EXPECT_UPDATE = sec_to_time_delta(1.0 / (double)UPDATE_FPS); const time_delta EXPECT_RENDER = sec_to_time_delta(1.0 / (double)RENDER_FPS); Timer timer = {}; Simloop simloop = simloop_make(&(SimloopArgs){ .update_fps = UPDATE_FPS, .max_render_fps = 0, .timer = &timer}); SimloopOut simout; for (time_delta t = STEP; t < SIM_TIME_SEC; t += STEP) { timer_advance(&timer, t); simloop_update(&simloop, &simout); TEST_TRUE(((STEP % EXPECT_RENDER) == 0) ? simout.should_render : true); TEST_TRUE(((STEP % EXPECT_UPDATE) == 0) ? simout.updates_pending : true); } } int main() { return 0; }