// file: crates/apps/game-reflex-poc-wasm/src/runtime.rs // version: 1 /// WebAssembly-owned Reflex game state consumed by the Tauri WebView. #[wasm_bindgen::prelude::wasm_bindgen] pub struct ReflexWasmGame { runner: engine_v1_common::FixedStepRunner, state: game_reflex_poc::ReflexState, } #[wasm_bindgen::prelude::wasm_bindgen] impl ReflexWasmGame { /// Creates a fresh Reflex POC session using the shared gameplay crate. #[wasm_bindgen::prelude::wasm_bindgen(constructor)] pub fn new() -> Self { return Self { runner: engine_v1_common::FixedStepRunner::new(std::time::Duration::from_millis(16)), state: game_reflex_poc::ReflexState::new(), }; } /// Advances one deterministic update without an input impulse. pub fn tick(&mut self) { self.runner.tick(&mut self.state, engine_v1_common::InputState::none()); return; } /// Delivers one normalized primary-pointer impulse to the shared Reflex gameplay state. pub fn pointer_down(&mut self, x: f32, y: f32) { let pointer = engine_v1_common::PointerState::normalized(true, x, y); let input = engine_v1_common::InputState::none().with_pointer(pointer).with_action(engine_v1_common::GameAction::Primary, true); self.runner.tick(&mut self.state, input); return; } /// Returns the current gameplay score. pub fn score(&self) -> u32 { return self.state.score().min(u32::MAX as u64) as u32; } /// Returns the current scene background red channel. pub fn background_red(&self) -> u8 { return self.scene().background().red(); } /// Returns the current scene background green channel. pub fn background_green(&self) -> u8 { return self.scene().background().green(); } /// Returns the current scene background blue channel. pub fn background_blue(&self) -> u8 { return self.scene().background().blue(); } /// Returns the number of occupied rectangle slots in the current scene. pub fn rectangle_count(&self) -> u32 { let scene = self.scene(); let mut count = 0_u32; for slot in scene.rectangles() { if slot.is_some() { count = count.saturating_add(1); } } return count; } /// Returns one rectangle's normalized left coordinate or `-1.0` if absent. pub fn rectangle_x(&self, index: u32) -> f32 { return match self.rectangle(index) { Some(rectangle) => rectangle.rect().x(), None => -1.0, }; } /// Returns one rectangle's normalized top coordinate or `-1.0` if absent. pub fn rectangle_y(&self, index: u32) -> f32 { return match self.rectangle(index) { Some(rectangle) => rectangle.rect().y(), None => -1.0, }; } /// Returns one rectangle's normalized width or `0.0` if absent. pub fn rectangle_width(&self, index: u32) -> f32 { return match self.rectangle(index) { Some(rectangle) => rectangle.rect().width(), None => 0.0, }; } /// Returns one rectangle's normalized height or `0.0` if absent. pub fn rectangle_height(&self, index: u32) -> f32 { return match self.rectangle(index) { Some(rectangle) => rectangle.rect().height(), None => 0.0, }; } /// Returns one rectangle's red channel or zero if absent. pub fn rectangle_red(&self, index: u32) -> u8 { return match self.rectangle(index) { Some(rectangle) => rectangle.color().red(), None => 0, }; } /// Returns one rectangle's green channel or zero if absent. pub fn rectangle_green(&self, index: u32) -> u8 { return match self.rectangle(index) { Some(rectangle) => rectangle.color().green(), None => 0, }; } /// Returns one rectangle's blue channel or zero if absent. pub fn rectangle_blue(&self, index: u32) -> u8 { return match self.rectangle(index) { Some(rectangle) => rectangle.color().blue(), None => 0, }; } } impl Default for ReflexWasmGame { fn default() -> Self { return Self::new(); } } impl ReflexWasmGame { fn scene(&self) -> engine_v1_common::EngineScene { return engine_v1_common::EngineGame::scene(&self.state); } fn rectangle(&self, requested_index: u32) -> Option { let scene = self.scene(); let mut occupied_index = 0_u32; for slot in scene.rectangles() { match slot { Some(rectangle) => { if occupied_index == requested_index { return Some(*rectangle); } occupied_index = occupied_index.saturating_add(1); }, None => {}, } } return None; } }