refactor(engine): ambiguity burn-down batch 4 — zero ambiguities, gate enforced
Test / test (pull_request) Failing after 17m5s
Test / test (pull_request) Failing after 17m5s
Clears the final 47 pairs and turns the ratchet into a hard gate (AMBIGUITY_BASELINE = 0, assert_eq): - HudButtons: the 14 HUD button/popover handlers run as one chain, before ui_focus::FocusKeys — Esc/keyboard consumption order is now defined (restore prompt → buttons/popovers → focus navigation → settings toggle) instead of scheduler-dependent. - HUD text updaters (update_hud, update_selection_hud, update_won_previously) chained, in UiTextFx, after the new AutoComplete set (update_hud reads AutoCompleteState). - restore_hud_on_modal → apply_hud_visibility chained before UpdateOnResize: HudVisibility writes, application, and the layout read happen in a fixed order. - New writer sets UndoRequestWriters / InfoToastWriters (same self-ambiguous pattern as NewGameRequestWriters). - Logic-before-paint: check_no_moves and the AutoComplete chain order before BoardVisuals; SettingsMutation after UpdateOnResize. - MarkerVisuals set wraps the table painter chain; chrome fx declare disjointness from it. - update_hud_typography after BoardVisuals; avatar/settings-toggle interaction handlers declared disjoint from HudButtons. 302 → 198 → 171 → 47 → 0 in four batches, one day. New systems now fail CI unless they declare their ordering or their disjointness. Closes #143 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -75,6 +75,17 @@ pub struct GameMutation;
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct NewGameRequestWriters;
|
||||
|
||||
/// Self-ambiguous set for writers of `UndoRequestEvent` — same rationale as
|
||||
/// [`NewGameRequestWriters`]: consumers drain the queue, append order is
|
||||
/// meaningless (#143).
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct UndoRequestWriters;
|
||||
|
||||
/// Self-ambiguous set for writers of `InfoToastEvent` — toasts queue in
|
||||
/// arrival order and any same-frame order is fine (#143).
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct InfoToastWriters;
|
||||
|
||||
/// Persistence path for the in-progress game state file. `None` disables I/O.
|
||||
#[derive(Resource, Debug, Clone)]
|
||||
pub struct GameStatePath(pub Option<PathBuf>);
|
||||
@@ -233,7 +244,14 @@ impl Plugin for GamePlugin {
|
||||
.chain()
|
||||
.in_set(GameMutation),
|
||||
)
|
||||
.add_systems(Update, check_no_moves.after(GameMutation))
|
||||
.add_systems(
|
||||
Update,
|
||||
check_no_moves
|
||||
.after(GameMutation)
|
||||
.before(crate::card_plugin::BoardVisuals)
|
||||
.in_set(InfoToastWriters)
|
||||
.ambiguous_with(InfoToastWriters),
|
||||
)
|
||||
.add_systems(Update, record_replay_on_win.after(GameMutation))
|
||||
.add_systems(
|
||||
Update,
|
||||
@@ -244,14 +262,16 @@ impl Plugin for GamePlugin {
|
||||
handle_game_over_button_input,
|
||||
)
|
||||
.after(GameMutation)
|
||||
.before(crate::ui_focus::FocusKeys)
|
||||
.in_set(NewGameRequestWriters)
|
||||
.ambiguous_with(NewGameRequestWriters),
|
||||
.ambiguous_with(NewGameRequestWriters)
|
||||
.in_set(UndoRequestWriters)
|
||||
.ambiguous_with(UndoRequestWriters),
|
||||
)
|
||||
// Restore prompt: spawn the modal once the splash is gone,
|
||||
// route Continue / New Game intents back into the existing
|
||||
// GameMutation flow.
|
||||
.add_systems(Update, spawn_restore_prompt_if_pending)
|
||||
// All three pre-mutation game-state writers are chained: elapsed
|
||||
// All pre-mutation game-state writers are chained: elapsed
|
||||
// time ticks first, settings sync next, then the restore prompt —
|
||||
// a deterministic spine instead of three unordered ResMut holders
|
||||
// (ambiguity burn-down, #143).
|
||||
@@ -260,6 +280,7 @@ impl Plugin for GamePlugin {
|
||||
(
|
||||
tick_elapsed_time,
|
||||
sync_settings_to_game,
|
||||
spawn_restore_prompt_if_pending,
|
||||
handle_restore_prompt
|
||||
.in_set(NewGameRequestWriters)
|
||||
.ambiguous_with(NewGameRequestWriters),
|
||||
|
||||
Reference in New Issue
Block a user