feat(engine): reactive render — animations drive RequestRedraw, focused_mode reactive on Android

All per-frame animation tick systems now write MessageWriter<RequestRedraw>
each frame they have active work, allowing WinitSettings focused_mode to
switch from Continuous to reactive_low_power(100 ms) on Android.

Systems updated:
- advance_card_animations (CardAnimationPlugin)
- advance_card_anims (AnimationPlugin — deal/win cascade)
- tick_shake_anim, tick_settle_anim, tick_foundation_flourish (FeedbackAnimPlugin)
- drive_toast_display (AnimationPlugin — toast countdown)
- drive_auto_complete (AutoCompletePlugin — step interval keepalive)

The 100 ms low-power ceiling means the game timer still ticks ~10×/s
with no input; animations self-sustain via the redraw chain at full
frame rate while active; and the GPU is completely idle between frames
when the board is static.

Each plugin registers add_message::<RequestRedraw>() so the message
type is available under MinimalPlugins in unit tests.

Closes #78, #79

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
funman300
2026-05-29 13:54:54 -07:00
parent ccf280ea50
commit 38e4c0341e
5 changed files with 18 additions and 6 deletions
+4 -1
View File
@@ -9,6 +9,7 @@
//! returns `None` (e.g. a transient state), the plugin retries next tick.
use bevy::prelude::*;
use bevy::window::RequestRedraw;
use crate::audio_plugin::{AudioState, SoundLibrary};
use crate::events::{MoveRequestEvent, StateChangedEvent};
@@ -39,7 +40,9 @@ pub struct AutoCompletePlugin;
impl Plugin for AutoCompletePlugin {
fn build(&self, app: &mut App) {
app.init_resource::<AutoCompleteState>().add_systems(
app.init_resource::<AutoCompleteState>()
.add_message::<RequestRedraw>()
.add_systems(
Update,
(
detect_auto_complete,