MapFacet — idle auto-rotate
The map/3D pane spins itself when the user walks away — a screensaver-style "show off the scene" that any interaction instantly cancels. Lives on MapFacet (the shared, source-agnostic map facet), so every map surface inherits it; the funnel/graph panes reuse the same idea.
What it is
- Off by default. Turn on with
MapFacet::with_auto_rotate(true)/set_auto_rotate(true). - Idle-gated. A frame clock (
idle_elapsed_s) counts up while the pane is untouched; once it crossesidle_threshold_s(6 s) the camerabearing_degadvances atrotate_speed_deg_s(8 °/s). Any pointer/scroll/key event resets the clock and stops the spin. - Pure + drivable in code.
tick(dt_s, interacted) -> booltakes the frame delta + an "interacted this frame" flag (no wall-clock read), so it is deterministic and testable headlessly.ui()feeds it egui'sstable_dt+ input-event presence and requests a repaint while spinning. - Observable.
state_json()exposesauto_rotate,idle_rotating,idle_elapsed_s— "see what the user sees" as data.
Coverage (LAW: robot + test-matrix, driven in code)
- Headless robot drive:
layer::tests::idle_auto_rotate_spins_only_when_idledrivestick()in code — asserts no spin while interacting → spins after the idle threshold (bearing advances) → a touch resets/stops → off-by-default never spins — reading back throughstate_json(). - test-matrix cell: emits
facett-map / idle_auto_rotateviafacett_core::testmatrix::emit(eddanornir-testmatrix) under--features testmatrix. - Follow-up: the visible
watch-on-DISPLAY:0 leg (egui_kittest frame loop, as intests/robot_callchain.rs) asserting the painted bearing changes across frames.