git.lucas.co / cce-designer
graphic design tool
git clone https://git.lucas.co/cce-designer.git

commite1177b88623c8417e2c957189b137909de1e5f9e
parent648183ba17
authorLucas Galante <lsgalante12@gmail.com>
date2026-09-28 18:59
test: playback frame and last-substep anchoring

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

 src/main.rs | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/src/main.rs b/src/main.rs
index e803eb0..e8ecf28 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -12710,4 +12710,30 @@ mod tests {
         assert!(state.handle_event(&WindowEvent::MouseWheel { delta: MouseScrollDelta::LineDelta(0.0, -1.0) }));
         assert_eq!(value(&state), before);
     }
+
+    /// During playback the scene is built for the frame the playbar shows,
+    /// within the same tick. The Playbar's tick advances the frame, so the
+    /// frame-change check has to run after the widget ticks; before
+    /// 2026-09-28 it ran first, and every tick rebuilt the scene for the
+    /// previous tick's frame and then advanced the readout.
+    #[test]
+    fn playback_builds_the_scene_for_the_frame_the_playbar_shows() {
+        let mut state = State::new(false);
+        state.resize(1600.0, 900.0, 1.0);
+        state.rebuild_positions();
+        state.apply_layout();
+        let mut redraw = false;
+        state.apply_action(McpAction::AddNode { template_name: "Simnet".into(), name: Some("sim".into()), x: 6.0, y: 8.0 }, &mut redraw).unwrap();
+        assert!(crate::geometry::contains_simnet(&state.fs_root));
+        state.tick_frame(1.0 / 60.0);
+        assert_eq!(state.last_sim_frame, state.sim_frame());
+        state.slots.playbar.inner_mut().playing = true;
+        state.slots.playbar.inner_mut().fps = 60.0;
+        let start = state.sim_frame();
+        for i in 1..=3 {
+            assert!(state.tick_frame(1.0 / 60.0), "a playing tick asks for a redraw");
+            assert_eq!(state.sim_frame(), start + i, "the playbar advanced a frame");
+            assert_eq!(state.last_sim_frame, state.sim_frame(), "and the scene was built for that frame, not the last one");
+        }
+    }
 }