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:
@@ -99,6 +99,38 @@ pub struct DrawRequestWriters;
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct InfoToastWriters;
|
||||
|
||||
/// Self-ambiguous club for writers of `MoveRequestEvent` (drag drops, stock
|
||||
/// clicks, radial menu, selection keys, replay step button). Consumers drain
|
||||
/// the whole queue — append order is meaningless (#143). Same rules as
|
||||
/// [`NewGameRequestWriters`]: do NOT hang ordering edges off this set.
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct MoveRequestWriters;
|
||||
|
||||
/// Self-ambiguous club for writers of `WarningToastEvent` (daily-expiry
|
||||
/// warning, leaderboard opt-in/out failure polls). The toast pipeline
|
||||
/// drains the whole queue — append order is meaningless (#143). Same
|
||||
/// rules as [`InfoToastWriters`].
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct WarningToastWriters;
|
||||
|
||||
/// Set + self-ambiguous club for the mode-start request handlers (challenge,
|
||||
/// daily, time-attack, play-by-seed, difficulty). Each drains its own
|
||||
/// request stream and resets `GameStateResource` for its mode; only one
|
||||
/// stream carries an event on any real frame, so member order is irrelevant
|
||||
/// (club), while the set as a whole runs between the stats abandon-recorder
|
||||
/// ([`crate::stats_plugin::AbandonRecord`], which must read the old game
|
||||
/// first) and [`GameMutation`] (#143).
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ModeStart;
|
||||
|
||||
/// Set wrapping `GamePlugin`'s pre-mutation game-state spine (elapsed-time
|
||||
/// tick, settings sync, restore prompt). Sits between
|
||||
/// [`crate::settings_plugin::SettingsMutation`] and [`GameMutation`]; other
|
||||
/// pre-mutation readers of `GameStateResource` (e.g. the stats
|
||||
/// abandon-recorder) order themselves `.after(PreMutation)` (#143).
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct PreMutation;
|
||||
|
||||
/// Persistence path for the in-progress game state file. `None` disables I/O.
|
||||
#[derive(Resource, Debug, Clone)]
|
||||
pub struct GameStatePath(pub Option<PathBuf>);
|
||||
@@ -267,7 +299,14 @@ impl Plugin for GamePlugin {
|
||||
.in_set(InfoToastWriters)
|
||||
.ambiguous_with(InfoToastWriters),
|
||||
)
|
||||
.add_systems(Update, record_replay_on_win.after(GameMutation))
|
||||
.add_systems(
|
||||
Update,
|
||||
record_replay_on_win
|
||||
.after(GameMutation)
|
||||
// Before the playback skip-recorder (which runs after
|
||||
// AutoComplete) — both touch RecordingReplay (#143).
|
||||
.before(crate::auto_complete_plugin::AutoComplete),
|
||||
)
|
||||
.add_systems(
|
||||
Update,
|
||||
(
|
||||
@@ -301,9 +340,20 @@ impl Plugin for GamePlugin {
|
||||
.ambiguous_with(NewGameRequestWriters),
|
||||
)
|
||||
.chain()
|
||||
.in_set(PreMutation),
|
||||
)
|
||||
.configure_sets(
|
||||
Update,
|
||||
PreMutation
|
||||
.after(crate::settings_plugin::SettingsMutation)
|
||||
.before(GameMutation),
|
||||
)
|
||||
.configure_sets(
|
||||
Update,
|
||||
ModeStart
|
||||
.after(crate::stats_plugin::AbandonRecord)
|
||||
.before(GameMutation),
|
||||
)
|
||||
.init_resource::<AutoSaveTimer>()
|
||||
.add_systems(Update, auto_save_game_state.after(GameMutation))
|
||||
.add_systems(Last, save_game_state_on_exit);
|
||||
|
||||
Reference in New Issue
Block a user