From d1e87765afd1d270a8b879ffba7e48ca000cfd41 Mon Sep 17 00:00:00 2001 From: funman300 Date: Mon, 6 Jul 2026 14:01:10 -0700 Subject: [PATCH] refactor(engine): split card_plugin runtime code into submodules MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Final runtime split for #118: the 2,536-line mod.rs becomes seven focused submodules along existing system boundaries — mod.rs 574 fan-step helpers, CardImageSet, markers, plugin build sync.rs 748 asset loading + card entity lifecycle (spawn/update/position) layout.rs 351 resize snapping, in-place resize, tableau fan spread stock.rs 291 empty-stock recycle hint + count badge highlights.rs 276 hint/right-click highlights, cursor hit-testing labels.rs 208 desktop text labels + Android corner labels anim.rs 200 flip animation, drag shadows Moved items are pub(super); code moved verbatim apart from relocating the two stock colour constants next to their consumers. No behaviour change; all 70 card tests pass unchanged. Refs #118 Co-Authored-By: Claude Fable 5 --- solitaire_engine/src/card_plugin/anim.rs | 200 ++ .../src/card_plugin/highlights.rs | 276 +++ solitaire_engine/src/card_plugin/labels.rs | 208 ++ solitaire_engine/src/card_plugin/layout.rs | 351 +++ solitaire_engine/src/card_plugin/mod.rs | 2008 +---------------- solitaire_engine/src/card_plugin/stock.rs | 291 +++ solitaire_engine/src/card_plugin/sync.rs | 748 ++++++ solitaire_engine/src/card_plugin/tests.rs | 9 + 8 files changed, 2106 insertions(+), 1985 deletions(-) create mode 100644 solitaire_engine/src/card_plugin/anim.rs create mode 100644 solitaire_engine/src/card_plugin/highlights.rs create mode 100644 solitaire_engine/src/card_plugin/labels.rs create mode 100644 solitaire_engine/src/card_plugin/layout.rs create mode 100644 solitaire_engine/src/card_plugin/stock.rs create mode 100644 solitaire_engine/src/card_plugin/sync.rs diff --git a/solitaire_engine/src/card_plugin/anim.rs b/solitaire_engine/src/card_plugin/anim.rs new file mode 100644 index 0000000..ea7c073 --- /dev/null +++ b/solitaire_engine/src/card_plugin/anim.rs @@ -0,0 +1,200 @@ +//! Card flip animation and drag shadows. + +use super::*; + +use std::collections::HashSet; + +use solitaire_core::Card; + +use crate::animation_plugin::EffectiveSlideDuration; +use crate::events::{CardFaceRevealedEvent, CardFlippedEvent}; +use crate::layout::LayoutResource; +use crate::resources::DragState; +use crate::ui_theme::{ + CARD_SHADOW_ALPHA_DRAG, CARD_SHADOW_COLOR, CARD_SHADOW_LOCAL_Z, +}; + +/// Listens for `CardFlippedEvent` and inserts a `CardFlipAnim` on the entity. +/// +/// Skipped when `EffectiveSlideDuration::slide_secs == 0.0` (Instant speed). +pub(super) fn start_flip_anim( + mut events: MessageReader, + slide_dur: Option>, + mut commands: Commands, + card_entities: Query<(Entity, &CardEntity)>, +) { + if slide_dur.is_some_and(|d| d.slide_secs == 0.0) { + // Instant animation speed — skip the flip effect entirely. + events.clear(); + return; + } + + for CardFlippedEvent(flipped_card) in events.read() { + for (entity, marker) in &card_entities { + if marker.card == *flipped_card { + commands.entity(entity).insert(CardFlipAnim { + timer: 0.0, + phase: FlipPhase::ScalingDown, + }); + break; + } + } + } +} + +/// Advances `CardFlipAnim` each frame, modifying `Transform::scale.x`. +/// +/// - Phase `ScalingDown`: lerps scale.x from 1.0 → 0.0 over `FLIP_HALF_SECS`. +/// - At the midpoint the phase switches to `ScalingUp`, scale.x resets to 0, +/// and a `CardFaceRevealedEvent` is fired so audio plays in sync with the reveal. +/// - Phase `ScalingUp`: lerps scale.x from 0.0 → 1.0 over `FLIP_HALF_SECS`. +/// - When complete the component is removed and scale.x is restored to 1.0. +pub(super) fn tick_flip_anim( + mut commands: Commands, + time: Res