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:
@@ -550,6 +550,14 @@ fn fire_state_changed_on_completion(
|
||||
*last_was_completed = now_completed;
|
||||
}
|
||||
|
||||
/// Set wrapping the replay playback driver chain (tick → auto-clear →
|
||||
/// completion `StateChangedEvent`). The tick feeds `MoveRequestEvent` /
|
||||
/// `DrawRequestEvent` into this frame's [`GameMutation`], so the set sits
|
||||
/// on the pre-mutation spine; the overlay UI (`replay_overlay`) orders
|
||||
/// itself after this set so its painters render the post-tick state (#143).
|
||||
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ReplayPlayback;
|
||||
|
||||
/// Bevy plugin that initialises [`ReplayPlaybackState`] and drives
|
||||
/// playback ticks, completion linger, and the recording-pause guard.
|
||||
///
|
||||
@@ -562,18 +570,46 @@ impl Plugin for ReplayPlaybackPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_resource::<ReplayPlaybackState>()
|
||||
.add_message::<StateChangedEvent>()
|
||||
.add_systems(
|
||||
.configure_sets(
|
||||
Update,
|
||||
(
|
||||
tick_replay_playback,
|
||||
auto_clear_completed_replay,
|
||||
fire_state_changed_on_completion,
|
||||
)
|
||||
.chain(),
|
||||
ReplayPlayback
|
||||
.after(crate::game_plugin::PreMutation)
|
||||
// Input first: a stop/pause press or a drag-emitted
|
||||
// request this frame is observed before the tick fires
|
||||
// the next scripted move (#143).
|
||||
.after(crate::input_plugin::PointerInput)
|
||||
.before(GameMutation),
|
||||
)
|
||||
.add_systems(
|
||||
Update,
|
||||
record_replay_skip_during_playback.after(GameMutation),
|
||||
(
|
||||
// The tick shares the move/draw request streams with the
|
||||
// pointer/keyboard writers (drained wholesale at
|
||||
// GameMutation) and reads playback speed from settings.
|
||||
tick_replay_playback
|
||||
.in_set(crate::game_plugin::MoveRequestWriters)
|
||||
.ambiguous_with(crate::game_plugin::MoveRequestWriters)
|
||||
.in_set(crate::game_plugin::DrawRequestWriters)
|
||||
.ambiguous_with(crate::game_plugin::DrawRequestWriters)
|
||||
.in_set(crate::settings_plugin::SettingsAccess)
|
||||
.ambiguous_with(crate::settings_plugin::SettingsAccess),
|
||||
auto_clear_completed_replay,
|
||||
// Chained before GameMutation: explicit order against the
|
||||
// mutation systems' StateChangedEvent writes; readers
|
||||
// drain the whole queue after GameMutation.
|
||||
fire_state_changed_on_completion,
|
||||
)
|
||||
.chain()
|
||||
.in_set(ReplayPlayback),
|
||||
)
|
||||
.add_systems(
|
||||
Update,
|
||||
record_replay_skip_during_playback
|
||||
.after(GameMutation)
|
||||
// After AutoComplete so the stats overlay's watch-replay
|
||||
// handler (which resets ReplayPlaybackState) and the
|
||||
// win-path recorder have both settled (#143).
|
||||
.after(crate::auto_complete_plugin::AutoComplete),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user