refactor(engine): ambiguity gate covers the full cluster — batches 1-3, 585 pairs burned to zero
Port the July 7 gate-extender branch onto current master (the You-hub, touch action bar, glass tab bar, Phase L, and hint-ghost work all landed since) and finish batch 3. cluster_app now includes the mode, replay, input, radial, tooltip, cursor, touch-selection, and safe-area plugins on top of batches 1-2; the 585 ambiguous pairs the expansion exposed are annotated down to zero and the gate stays assert_eq!(count, 0). New ordering machinery: - ReplayPlayback: playback driver chain on the pre-mutation spine (PointerInput < ReplayPlayback < overlay chain < GameMutation) - ModeStart: mode-start handlers between the stats abandon-recorder and GameMutation; ChallengeCompletion < DailyCompletion < WeeklyGoalsEval pinned inside ProgressUpdate so `.after(ProgressUpdate)` readers see settled progress - PointerInput: public set wrapping the input chain; AbandonRecord on the stats abandon-recorder; PendingHint around the async hint pipeline; HintGhostFx for the ghost chain (after the full visual spine) - Clubs: MoveRequestWriters, WarningToastWriters join the existing request/toast writer clubs; UiTextFx grows the overlay/tooltip/safe-area chrome painters; SettingsAccess grows the lag-tolerant settings readers Gate: cargo test --workspace green (993 engine tests), clippy --all-targets -D warnings clean, rustfmt applied. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -87,6 +87,19 @@ pub struct SettingsChangedEvent(pub Settings);
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct SettingsMutation;
|
||||
|
||||
/// Self-ambiguous club for the screen/overlay systems that touch
|
||||
/// [`SettingsResource`] (onboarding first-run flag, home difficulty/draw
|
||||
/// chips, leaderboard opt-in and display name, pause draw toggle, splash
|
||||
/// reduce-motion reads, …). Each accessor touches its own disjoint fields,
|
||||
/// and the modal-stacking guard means at most one of these screens is
|
||||
/// interactive at a time — same-frame access order is provably irrelevant,
|
||||
/// so members declare `.in_set(SettingsAccess).ambiguous_with(SettingsAccess)`
|
||||
/// (#143). [`SettingsMutation`] is nested inside the club (its members keep
|
||||
/// their internal chain). Do NOT add members whose settings read must be
|
||||
/// same-frame-exact; order those `.after(SettingsMutation)` instead.
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct SettingsAccess;
|
||||
|
||||
/// Marker on the root Settings panel entity.
|
||||
#[derive(Component, Debug)]
|
||||
pub struct SettingsPanel;
|
||||
@@ -459,7 +472,12 @@ impl Plugin for SettingsPlugin {
|
||||
Update,
|
||||
SettingsMutation
|
||||
.after(crate::layout::LayoutSystem::UpdateOnResize)
|
||||
.before(crate::game_plugin::GameMutation),
|
||||
.before(crate::game_plugin::GameMutation)
|
||||
// Nested in the club: members keep their chain, but
|
||||
// their pairs against other screen-plugin settings
|
||||
// accessors are declared irrelevant (#143).
|
||||
.in_set(SettingsAccess)
|
||||
.ambiguous_with(SettingsAccess),
|
||||
)
|
||||
.add_systems(
|
||||
Update,
|
||||
@@ -482,8 +500,12 @@ impl Plugin for SettingsPlugin {
|
||||
toggle_settings_screen
|
||||
.before(crate::ui_focus::FocusKeys)
|
||||
.ambiguous_with(crate::hud_plugin::HudButtons),
|
||||
scroll_settings_panel,
|
||||
crate::ui_modal::touch_scroll_panel::<SettingsPanelScrollable>,
|
||||
scroll_settings_panel
|
||||
.in_set(crate::ui_modal::PanelScroll)
|
||||
.ambiguous_with(crate::ui_modal::PanelScroll),
|
||||
crate::ui_modal::touch_scroll_panel::<SettingsPanelScrollable>
|
||||
.in_set(crate::ui_modal::PanelScroll)
|
||||
.ambiguous_with(crate::ui_modal::PanelScroll),
|
||||
)
|
||||
.chain(),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user