0.1.0-1-alpha.2-fix.2
This commit is contained in:
@@ -1,15 +1,19 @@
|
||||
// file: crates/apps/game-reflex-poc-tauri/src/lib.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Tauri desktop application facade for the Reflex WebAssembly POC.
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(unreachable_pub)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
//! WebAssembly adapter for the Reflex POC when hosted by the Tauri variant.
|
||||
mod runtime;
|
||||
mod tauri;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
mod wasm_runtime;
|
||||
/// Runs the Reflex Tauri desktop application.
|
||||
pub use self::tauri::run;
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
/// Re-export of the Reflex WebAssembly runtime adapter.
|
||||
pub use self::wasm_runtime::ReflexWasmGame;
|
||||
/// Records that the Vite/TypeScript frontend reached its ready state.
|
||||
pub(crate) use self::runtime::record_frontend_ready;
|
||||
/// Returns the runtime label exposed by the Tauri bridge.
|
||||
pub(crate) use self::runtime::runtime_label;
|
||||
|
||||
@@ -1,25 +1,20 @@
|
||||
// file: crates/apps/game-reflex-poc-tauri/src/main.rs
|
||||
// version: 1
|
||||
// version: 2
|
||||
|
||||
//! Binary entry point for the Reflex Tauri desktop application.
|
||||
|
||||
#![warn(missing_docs)]
|
||||
#![deny(unreachable_pub)]
|
||||
#![forbid(unsafe_code)]
|
||||
#![deny(unreachable_pub)]
|
||||
#![warn(missing_docs)]
|
||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||
|
||||
//! Native Tauri host for the local Reflex WebAssembly POC.
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
fn main() {
|
||||
let result = tauri::Builder::default().run(tauri::generate_context!());
|
||||
match result {
|
||||
std::result::Result::Ok(()) => {},
|
||||
fn main() -> std::process::ExitCode {
|
||||
let result = game_reflex_poc_tauri_lib::run();
|
||||
return match result {
|
||||
std::result::Result::Ok(()) => std::process::ExitCode::SUCCESS,
|
||||
std::result::Result::Err(error) => {
|
||||
eprintln!("Reflex POC Tauri runner failed: {error}");
|
||||
eprintln!("Reflex Tauri application error: {error}");
|
||||
std::process::ExitCode::FAILURE
|
||||
},
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
fn main() {
|
||||
return;
|
||||
};
|
||||
}
|
||||
|
||||
18
crates/apps/game-reflex-poc-tauri/src/runtime.rs
Normal file
18
crates/apps/game-reflex-poc-tauri/src/runtime.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
// file: crates/apps/game-reflex-poc-tauri/src/runtime.rs
|
||||
// version: 1
|
||||
|
||||
/// Stable label for the current Tauri/WASM runtime combination.
|
||||
pub(crate) fn runtime_label() -> &'static str {
|
||||
return "Desktop / TauriWebView / Wasm / KeyboardMouse";
|
||||
}
|
||||
|
||||
/// Records that the frontend completed its startup sequence.
|
||||
pub(crate) fn record_frontend_ready() {
|
||||
tracing::info!(
|
||||
target: "games::tauri::reflex",
|
||||
action = "frontend_ready",
|
||||
runtime = crate::runtime_label(),
|
||||
"Reflex Tauri frontend ready"
|
||||
);
|
||||
return;
|
||||
}
|
||||
39
crates/apps/game-reflex-poc-tauri/src/tauri.rs
Normal file
39
crates/apps/game-reflex-poc-tauri/src/tauri.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
// file: crates/apps/game-reflex-poc-tauri/src/tauri.rs
|
||||
// version: 1
|
||||
|
||||
#[tauri::command]
|
||||
fn get_runtime_label() -> String {
|
||||
return crate::runtime_label().to_string();
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn frontend_ready() {
|
||||
crate::record_frontend_ready();
|
||||
return;
|
||||
}
|
||||
|
||||
fn configure_plugins(builder: tauri::Builder<tauri::Wry>) -> tauri::Builder<tauri::Wry> {
|
||||
let tracing_plugin = tauri_plugin_tracing::Builder::new().build::<tauri::Wry>();
|
||||
return builder.plugin(tracing_plugin);
|
||||
}
|
||||
|
||||
#[allow(clippy::question_mark_used)] // Tauri generates the question-mark operator internally for command dispatch.
|
||||
fn configure_commands(builder: tauri::Builder<tauri::Wry>) -> tauri::Builder<tauri::Wry> {
|
||||
return builder.invoke_handler(tauri::generate_handler![get_runtime_label, frontend_ready]);
|
||||
}
|
||||
|
||||
/// Runs the Reflex Tauri desktop application.
|
||||
pub fn run() -> std::result::Result<(), String> {
|
||||
tracing::info!(
|
||||
target: "games::tauri::reflex",
|
||||
action = "runtime_start",
|
||||
"Starting Reflex Tauri runtime"
|
||||
);
|
||||
let builder = tauri::Builder::default();
|
||||
let builder = configure_plugins(builder);
|
||||
let builder = configure_commands(builder);
|
||||
return match builder.run(tauri::generate_context!()) {
|
||||
std::result::Result::Ok(()) => std::result::Result::Ok(()),
|
||||
std::result::Result::Err(error) => std::result::Result::Err(error.to_string()),
|
||||
};
|
||||
}
|
||||
@@ -1,152 +0,0 @@
|
||||
// file: crates/apps/game-reflex-poc-tauri/src/wasm_runtime.rs
|
||||
// version: 1
|
||||
|
||||
/// WebAssembly-owned Reflex game state consumed by the local 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 same gameplay crate as native Desktop.
|
||||
#[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 the index is 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 the index is 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 the index is 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 the index is 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 the index is 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 the index is 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 the index is 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<engine_v1_common::RenderRect> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user