refactor(engine): ambiguity burn-down batch 2 — SettingsResource cleared (198 → 171) #147

Merged
funman300 merged 1 commits from refactor/ambiguity-settings into master 2026-07-07 03:48:11 +00:00
6 changed files with 38 additions and 6 deletions
+1
View File
@@ -265,6 +265,7 @@ impl Plugin for GamePlugin {
.ambiguous_with(NewGameRequestWriters), .ambiguous_with(NewGameRequestWriters),
) )
.chain() .chain()
.after(crate::settings_plugin::SettingsMutation)
.before(GameMutation), .before(GameMutation),
) )
.init_resource::<AutoSaveTimer>() .init_resource::<AutoSaveTimer>()
+7 -1
View File
@@ -473,7 +473,13 @@ impl Plugin for HudPlugin {
apply_hud_visibility.before(LayoutSystem::UpdateOnResize), apply_hud_visibility.before(LayoutSystem::UpdateOnResize),
) )
.add_systems(Update, restore_hud_on_modal) .add_systems(Update, restore_hud_on_modal)
.add_systems(Update, (update_hud_avatar, handle_avatar_button)) .add_systems(
Update,
(
update_hud_avatar.after(crate::settings_plugin::SettingsMutation),
handle_avatar_button,
),
)
.add_systems(Update, update_won_previously.after(GameMutation)) .add_systems(Update, update_won_previously.after(GameMutation))
.add_systems(Update, announce_auto_complete.after(GameMutation)) .add_systems(Update, announce_auto_complete.after(GameMutation))
.add_systems( .add_systems(
+1 -1
View File
@@ -38,7 +38,7 @@ mod tests {
/// ordering edge — add `.before`/`.after` (order matters) or /// ordering edge — add `.before`/`.after` (order matters) or
/// `.ambiguous_with` (provably order-independent) at the registration /// `.ambiguous_with` (provably order-independent) at the registration
/// site. When triage lowers the real count, lower this constant too. /// site. When triage lowers the real count, lower this constant too.
const AMBIGUITY_BASELINE: usize = 198; const AMBIGUITY_BASELINE: usize = 171;
fn cluster_app() -> App { fn cluster_app() -> App {
let mut app = App::new(); let mut app = App::new();
+26 -2
View File
@@ -79,6 +79,14 @@ pub struct PendingWindowGeometry {
#[derive(Message, Debug, Clone)] #[derive(Message, Debug, Clone)]
pub struct SettingsChangedEvent(pub Settings); pub struct SettingsChangedEvent(pub Settings);
/// System set for the systems that mutate [`SettingsResource`] every frame
/// (hotkeys and window-geometry persistence). Ordered before
/// [`crate::game_plugin::GameMutation`]; readers of settings should sit
/// after this set (directly, or transitively via `.after(GameMutation)`)
/// so they observe the current frame's settings deterministically (#143).
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
pub struct SettingsMutation;
/// Marker on the root Settings panel entity. /// Marker on the root Settings panel entity.
#[derive(Component, Debug)] #[derive(Component, Debug)]
pub struct SettingsPanel; pub struct SettingsPanel;
@@ -372,15 +380,31 @@ impl Plugin for SettingsPlugin {
// also runs cleanly under `MinimalPlugins` (tests). // also runs cleanly under `MinimalPlugins` (tests).
.add_message::<WindowResized>() .add_message::<WindowResized>()
.add_message::<WindowMoved>() .add_message::<WindowMoved>()
// Settings changes land before game logic runs: the mutator
// chain (volume keys → geometry record → geometry persist) is a
// deterministic spine, and the whole set precedes GameMutation so
// every reader already ordered after GameMutation sees this
// frame's settings transitively (ambiguity burn-down, #143).
.configure_sets(
Update,
SettingsMutation.before(crate::game_plugin::GameMutation),
)
.add_systems( .add_systems(
Update, Update,
( (
handle_volume_keys, handle_volume_keys,
record_window_geometry_changes,
persist_window_geometry_after_debounce,
)
.chain()
.in_set(SettingsMutation),
)
.add_systems(
Update,
(
toggle_settings_screen, toggle_settings_screen,
scroll_settings_panel, scroll_settings_panel,
crate::ui_modal::touch_scroll_panel::<SettingsPanelScrollable>, crate::ui_modal::touch_scroll_panel::<SettingsPanelScrollable>,
record_window_geometry_changes,
persist_window_geometry_after_debounce,
), ),
); );
+1 -1
View File
@@ -149,7 +149,7 @@ impl Plugin for UiFocusPlugin {
clear_hud_focus_on_unhover, clear_hud_focus_on_unhover,
handle_focus_keys, handle_focus_keys,
update_focus_overlay, update_focus_overlay,
pulse_focus_overlay, pulse_focus_overlay.after(crate::settings_plugin::SettingsMutation),
) )
.chain(), .chain(),
); );
+2 -1
View File
@@ -695,7 +695,8 @@ impl Plugin for UiModalPlugin {
advance_modal_enter, advance_modal_enter,
paint_modal_buttons, paint_modal_buttons,
) )
.chain(), .chain()
.after(crate::settings_plugin::SettingsMutation),
); );
// Click-outside-to-dismiss is independent of the open // Click-outside-to-dismiss is independent of the open
// animation chain — it reads `just_pressed(Left)` and runs // animation chain — it reads `just_pressed(Left)` and runs