0.1.0-1-alpha.2

This commit is contained in:
2026-09-16 23:28:33 +02:00
parent 2ad0c5a379
commit 9256e9e2d5
24 changed files with 762 additions and 14 deletions

View File

@@ -0,0 +1,32 @@
# file: crates/apps/game-reflex-poc-tauri/Cargo.toml
# version: 1
[package]
name = "game-reflex-poc-tauri"
version.workspace = true
edition.workspace = true
license.workspace = true
repository.workspace = true
authors.workspace = true
publish.workspace = true
build = "build.rs"
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
engine-v1-common = { path = "../../engines/engine-v1-common" }
engine-v1-platform-api = { path = "../../engines/engine-v1-platform-api" }
game-reflex-poc = { path = "../../games/game-reflex-poc" }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
tauri.workspace = true
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen.workspace = true
[build-dependencies]
tauri-build.workspace = true
[lints]
workspace = true

View File

@@ -0,0 +1,12 @@
// file: crates/apps/game-reflex-poc-tauri/build.rs
// version: 1
fn main() {
let target_arch = std::env::var("CARGO_CFG_TARGET_ARCH");
match target_arch {
std::result::Result::Ok(value) if value == "wasm32" => return,
_ => {},
}
tauri_build::build();
return;
}

View File

@@ -0,0 +1,15 @@
// file: crates/apps/game-reflex-poc-tauri/src/lib.rs
// version: 1
#![warn(missing_docs)]
#![deny(unreachable_pub)]
#![forbid(unsafe_code)]
//! WebAssembly adapter for the Reflex POC when hosted by the Tauri variant.
#[cfg(target_arch = "wasm32")]
mod wasm_runtime;
#[cfg(target_arch = "wasm32")]
/// Re-export of the Reflex WebAssembly runtime adapter.
pub use self::wasm_runtime::ReflexWasmGame;

View File

@@ -0,0 +1,25 @@
// file: crates/apps/game-reflex-poc-tauri/src/main.rs
// version: 1
#![warn(missing_docs)]
#![deny(unreachable_pub)]
#![forbid(unsafe_code)]
//! 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(()) => {},
std::result::Result::Err(error) => {
eprintln!("Reflex POC Tauri runner failed: {error}");
},
}
return;
}
#[cfg(target_arch = "wasm32")]
fn main() {
return;
}

View File

@@ -0,0 +1,152 @@
// 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;
}
}

View File

@@ -0,0 +1,25 @@
{
"$schema": "https://schema.tauri.app/config/2",
"productName": "Reflex POC Tauri",
"version": "0.1.0-1-alpha.2",
"identifier": "com.sasedev.games.reflex.tauri",
"build": {
"frontendDist": "../../../Tauri/game-reflex-poc/frontend"
},
"app": {
"windows": [
{
"title": "Reflex POC Tauri",
"width": 405,
"height": 720,
"resizable": true
}
],
"security": {
"csp": "default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' ipc: http://ipc.localhost"
}
},
"bundle": {
"active": false
}
}