0.1.0-1-alpha.2
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -63,3 +63,6 @@ __pycache__/
|
|||||||
*.jks
|
*.jks
|
||||||
*.keystore
|
*.keystore
|
||||||
local.properties
|
local.properties
|
||||||
|
# Generated by scripts/build_reflex_tauri_wasm.py.
|
||||||
|
Tauri/game-reflex-poc/frontend/game_reflex_poc_tauri.js
|
||||||
|
Tauri/game-reflex-poc/frontend/game_reflex_poc_tauri_bg.wasm
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: Android/game-reflex-poc/build.gradle
|
// file: Android/game-reflex-poc/build.gradle
|
||||||
// version: 10
|
// version: 11
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
@@ -18,7 +18,7 @@ android {
|
|||||||
minSdk 21
|
minSdk 21
|
||||||
targetSdk 36
|
targetSdk 36
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName '0.1.0-1-alpha.1'
|
versionName '0.1.0-1-alpha.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// file: Android/game-snake-poc/build.gradle
|
// file: Android/game-snake-poc/build.gradle
|
||||||
// version: 10
|
// version: 11
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'com.android.application'
|
id 'com.android.application'
|
||||||
@@ -18,7 +18,7 @@ android {
|
|||||||
minSdk 21
|
minSdk 21
|
||||||
targetSdk 36
|
targetSdk 36
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName '0.1.0-1-alpha.1'
|
versionName '0.1.0-1-alpha.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
# file: Cargo.toml
|
# file: Cargo.toml
|
||||||
# version: 27
|
# version: 28
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
resolver = "3"
|
resolver = "3"
|
||||||
@@ -14,10 +14,11 @@ members = [
|
|||||||
"crates/common/game-assets-lib",
|
"crates/common/game-assets-lib",
|
||||||
"crates/common/game-logging-lib",
|
"crates/common/game-logging-lib",
|
||||||
"crates/apps/game-android-entrypoint",
|
"crates/apps/game-android-entrypoint",
|
||||||
|
"crates/apps/game-reflex-poc-tauri",
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.1.0-1-alpha.1"
|
version = "0.1.0-1-alpha.2"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
repository = "https://git.sasedev.com/Sasedev/games"
|
repository = "https://git.sasedev.com/Sasedev/games"
|
||||||
@@ -29,6 +30,9 @@ sdl3 = "^0.20"
|
|||||||
tracing = "0.1.44"
|
tracing = "0.1.44"
|
||||||
tracing-appender = "0.2.5"
|
tracing-appender = "0.2.5"
|
||||||
tracing-subscriber = "0.3.23"
|
tracing-subscriber = "0.3.23"
|
||||||
|
tauri = "2"
|
||||||
|
tauri-build = "2"
|
||||||
|
wasm-bindgen = "0.2"
|
||||||
|
|
||||||
[workspace.lints.rust]
|
[workspace.lints.rust]
|
||||||
missing_docs = "warn"
|
missing_docs = "warn"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: ROADMAP.md -->
|
<!-- file: ROADMAP.md -->
|
||||||
<!-- version: 10 -->
|
<!-- version: 11 -->
|
||||||
|
|
||||||
# Roadmap
|
# Roadmap
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@
|
|||||||
- [x] `0-pre.9` — assets communs + spécifiques empaquetés sans copie dans les crates.
|
- [x] `0-pre.9` — assets communs + spécifiques empaquetés sans copie dans les crates.
|
||||||
- [x] `0-pre.10` — POC Reflex jouable Desktop + Android.
|
- [x] `0-pre.10` — POC Reflex jouable Desktop + Android.
|
||||||
- [x] `0-pre.11` — POC Snake jouable et validation de la réutilisation du moteur.
|
- [x] `0-pre.11` — POC Snake jouable et validation de la réutilisation du moteur.
|
||||||
- [ ] `1-alpha.1` — première API moteur V1 volontairement stabilisée et provenance runtime/input pour les futures sessions et scores.
|
- [x] `1-alpha.1` — première API moteur V1 volontairement stabilisée et provenance runtime/input pour les futures sessions et scores.
|
||||||
- [ ] `1-alpha.2` — POC Web/WASM embarqué dans Tauri, sans site distant, et validation de la frontière des services Web/ads.
|
- [ ] `1-alpha.2` — POC Web/WASM embarqué dans Tauri, sans site distant, et validation de la frontière des services Web/ads.
|
||||||
- [ ] `2-beta.1` — stabilisation, packaging, tests multi-appareils.
|
- [ ] `2-beta.1` — stabilisation, packaging, tests multi-appareils.
|
||||||
- [ ] `3-rc.1` — candidat de release du socle 0.1.0.
|
- [ ] `3-rc.1` — candidat de release du socle 0.1.0.
|
||||||
|
|||||||
10
Tauri/README.md
Normal file
10
Tauri/README.md
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<!-- file: Tauri/README.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Tauri
|
||||||
|
|
||||||
|
Cette arborescence contient les frontends statiques des variantes Desktop Tauri.
|
||||||
|
|
||||||
|
Le backend Rust reste une crate sous `crates/apps/`, conformément à la règle du workspace Cargo unique.
|
||||||
|
|
||||||
|
Les fichiers générés par `wasm-bindgen` ne sont pas versionnés.
|
||||||
17
Tauri/game-reflex-poc/frontend/index.html
Normal file
17
Tauri/game-reflex-poc/frontend/index.html
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="fr">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||||||
|
<title>Reflex POC Tauri</title>
|
||||||
|
<link rel="stylesheet" href="./style.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<main id="app">
|
||||||
|
<canvas id="game" aria-label="Reflex POC"></canvas>
|
||||||
|
<output id="score">Score : 0</output>
|
||||||
|
<output id="runtime">Tauri · WebView · WASM</output>
|
||||||
|
</main>
|
||||||
|
<script type="module" src="./main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
76
Tauri/game-reflex-poc/frontend/main.js
Normal file
76
Tauri/game-reflex-poc/frontend/main.js
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
// file: Tauri/game-reflex-poc/frontend/main.js
|
||||||
|
// version: 1
|
||||||
|
|
||||||
|
import init, { ReflexWasmGame } from "./game_reflex_poc_tauri.js";
|
||||||
|
|
||||||
|
const FRAME_MS = 16;
|
||||||
|
|
||||||
|
function color(red, green, blue) {
|
||||||
|
return `rgb(${red} ${green} ${blue})`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resizeCanvas(canvas) {
|
||||||
|
const ratio = window.devicePixelRatio || 1;
|
||||||
|
const width = Math.max(1, Math.floor(canvas.clientWidth * ratio));
|
||||||
|
const height = Math.max(1, Math.floor(canvas.clientHeight * ratio));
|
||||||
|
if (canvas.width !== width || canvas.height !== height) {
|
||||||
|
canvas.width = width;
|
||||||
|
canvas.height = height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function render(game, canvas, context, score) {
|
||||||
|
resizeCanvas(canvas);
|
||||||
|
context.fillStyle = color(game.background_red(), game.background_green(), game.background_blue());
|
||||||
|
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
|
||||||
|
const count = game.rectangle_count();
|
||||||
|
for (let index = 0; index < count; index += 1) {
|
||||||
|
context.fillStyle = color(game.rectangle_red(index), game.rectangle_green(index), game.rectangle_blue(index));
|
||||||
|
context.fillRect(
|
||||||
|
game.rectangle_x(index) * canvas.width,
|
||||||
|
game.rectangle_y(index) * canvas.height,
|
||||||
|
game.rectangle_width(index) * canvas.width,
|
||||||
|
game.rectangle_height(index) * canvas.height,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
score.value = `Score : ${game.score()}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function start() {
|
||||||
|
await init();
|
||||||
|
|
||||||
|
const canvas = document.querySelector("#game");
|
||||||
|
const score = document.querySelector("#score");
|
||||||
|
const context = canvas.getContext("2d");
|
||||||
|
if (!(canvas instanceof HTMLCanvasElement) || !(score instanceof HTMLOutputElement) || context === null) {
|
||||||
|
throw new Error("Reflex Tauri frontend DOM is incomplete");
|
||||||
|
}
|
||||||
|
|
||||||
|
const game = new ReflexWasmGame();
|
||||||
|
canvas.addEventListener("pointerdown", (event) => {
|
||||||
|
const bounds = canvas.getBoundingClientRect();
|
||||||
|
const x = (event.clientX - bounds.left) / bounds.width;
|
||||||
|
const y = (event.clientY - bounds.top) / bounds.height;
|
||||||
|
game.pointer_down(x, y);
|
||||||
|
render(game, canvas, context, score);
|
||||||
|
});
|
||||||
|
|
||||||
|
let previous = performance.now();
|
||||||
|
function frame(now) {
|
||||||
|
while (now - previous >= FRAME_MS) {
|
||||||
|
game.tick();
|
||||||
|
previous += FRAME_MS;
|
||||||
|
}
|
||||||
|
render(game, canvas, context, score);
|
||||||
|
window.requestAnimationFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
render(game, canvas, context, score);
|
||||||
|
window.requestAnimationFrame(frame);
|
||||||
|
}
|
||||||
|
|
||||||
|
start().catch((error) => {
|
||||||
|
console.error("Reflex Tauri WASM startup failed", error);
|
||||||
|
});
|
||||||
45
Tauri/game-reflex-poc/frontend/style.css
Normal file
45
Tauri/game-reflex-poc/frontend/style.css
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/* file: Tauri/game-reflex-poc/frontend/style.css */
|
||||||
|
/* version: 1 */
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
background: rgb(18 18 24);
|
||||||
|
font-family: sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#app {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#game {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
touch-action: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#score,
|
||||||
|
#runtime {
|
||||||
|
position: absolute;
|
||||||
|
left: 12px;
|
||||||
|
padding: 6px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: rgb(0 0 0 / 55%);
|
||||||
|
color: white;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#score {
|
||||||
|
top: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#runtime {
|
||||||
|
bottom: 12px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
32
crates/apps/game-reflex-poc-tauri/Cargo.toml
Normal file
32
crates/apps/game-reflex-poc-tauri/Cargo.toml
Normal 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
|
||||||
12
crates/apps/game-reflex-poc-tauri/build.rs
Normal file
12
crates/apps/game-reflex-poc-tauri/build.rs
Normal 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;
|
||||||
|
}
|
||||||
15
crates/apps/game-reflex-poc-tauri/src/lib.rs
Normal file
15
crates/apps/game-reflex-poc-tauri/src/lib.rs
Normal 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;
|
||||||
25
crates/apps/game-reflex-poc-tauri/src/main.rs
Normal file
25
crates/apps/game-reflex-poc-tauri/src/main.rs
Normal 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;
|
||||||
|
}
|
||||||
152
crates/apps/game-reflex-poc-tauri/src/wasm_runtime.rs
Normal file
152
crates/apps/game-reflex-poc-tauri/src/wasm_runtime.rs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
crates/apps/game-reflex-poc-tauri/tauri.conf.json
Normal file
25
crates/apps/game-reflex-poc-tauri/tauri.conf.json
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
129
deltas/0.1.0/1-alpha.2.md
Normal file
129
deltas/0.1.0/1-alpha.2.md
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
<!-- file: deltas/0.1.0/1-alpha.2.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Delta 0.1.0-1-alpha.2
|
||||||
|
|
||||||
|
## Base
|
||||||
|
|
||||||
|
Base validée : `0.1.0-1-alpha.1`.
|
||||||
|
|
||||||
|
## Objectif
|
||||||
|
|
||||||
|
Valider un POC Reflex WebAssembly embarqué dans une fenêtre Tauri locale, sans site distant, tout en réutilisant `game-reflex-poc`.
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
La nouvelle crate :
|
||||||
|
|
||||||
|
```text
|
||||||
|
crates/apps/game-reflex-poc-tauri
|
||||||
|
```
|
||||||
|
|
||||||
|
porte :
|
||||||
|
|
||||||
|
- une face native Tauri ;
|
||||||
|
- une face bibliothèque WASM pour `wasm32-unknown-unknown`.
|
||||||
|
|
||||||
|
Le frontend statique réside sous :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Tauri/game-reflex-poc/frontend
|
||||||
|
```
|
||||||
|
|
||||||
|
Le JavaScript orchestre Canvas et pointeur mais ne contient aucune règle gameplay.
|
||||||
|
|
||||||
|
## Build WebAssembly
|
||||||
|
|
||||||
|
Préparer une fois :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rustup target add wasm32-unknown-unknown
|
||||||
|
cargo install wasm-bindgen-cli --locked
|
||||||
|
```
|
||||||
|
|
||||||
|
Construire :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 scripts/build_reflex_tauri_wasm.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Prérequis Tauri Debian
|
||||||
|
|
||||||
|
Si nécessaire :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt update
|
||||||
|
sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev
|
||||||
|
cargo install tauri-cli --version "^2.0.0" --locked
|
||||||
|
```
|
||||||
|
|
||||||
|
## Validation Rust
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo fmt --all
|
||||||
|
cargo fmt --all -- --check
|
||||||
|
|
||||||
|
python3 scripts/audit_rust_workspace_rules.py
|
||||||
|
python3 scripts/audit_markdown_tables.py README.md RULES.md ROADMAP.md CHANGELOG.md docs prompts crates Tauri Android deltas history
|
||||||
|
|
||||||
|
cargo check --workspace
|
||||||
|
cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||||
|
|
||||||
|
cargo test -p engine-v1-platform-api --all-targets --all-features
|
||||||
|
cargo test -p game-reflex-poc --all-targets --all-features
|
||||||
|
```
|
||||||
|
|
||||||
|
## Gate WASM
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 scripts/build_reflex_tauri_wasm.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Vérifier :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
test -f Tauri/game-reflex-poc/frontend/game_reflex_poc_tauri.js
|
||||||
|
test -f Tauri/game-reflex-poc/frontend/game_reflex_poc_tauri_bg.wasm
|
||||||
|
```
|
||||||
|
|
||||||
|
## Smoke Tauri
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd crates/apps/game-reflex-poc-tauri
|
||||||
|
cargo tauri dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Critères :
|
||||||
|
|
||||||
|
- fenêtre Tauri locale ;
|
||||||
|
- cible Reflex visible ;
|
||||||
|
- clic sur cible comptabilisé ;
|
||||||
|
- cible déplacée après succès ;
|
||||||
|
- score visible ;
|
||||||
|
- aucun site distant requis.
|
||||||
|
|
||||||
|
## Provenance attendue
|
||||||
|
|
||||||
|
La variante correspond conceptuellement à :
|
||||||
|
|
||||||
|
```text
|
||||||
|
PlatformFamily::Desktop
|
||||||
|
DeviceClass::Desktop
|
||||||
|
ExecutionModel::Wasm
|
||||||
|
RuntimeHost::TauriWebView
|
||||||
|
InputProfile::KeyboardMouse
|
||||||
|
```
|
||||||
|
|
||||||
|
La connexion effective de cette provenance à une session/score fera partie d'une tranche ultérieure.
|
||||||
|
|
||||||
|
## Services Web
|
||||||
|
|
||||||
|
Aucune régie Ads n'est intégrée dans cette alpha.
|
||||||
|
|
||||||
|
Le POC valide uniquement la capacité structurelle à disposer d'une frontière Web locale dans Tauri. Les APIs de publicité, rewarded/revive et analytics resteront derrière les contrats plateforme.
|
||||||
|
|
||||||
|
## Transition
|
||||||
|
|
||||||
|
Si les gates passent, `0.1.0-1-alpha.2` valide la coexistence Desktop SDL3 natif + Tauri/WASM.
|
||||||
|
|
||||||
|
En cas d'échec imputable au projet, produire `0.1.0-1-alpha.2.fix.1`.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/000-README.md -->
|
<!-- file: docs/000-README.md -->
|
||||||
<!-- version: 13 -->
|
<!-- version: 14 -->
|
||||||
|
|
||||||
# Documentation games.sasedev
|
# Documentation games.sasedev
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/architecture/001-WORKSPACE_ARCHITECTURE.md -->
|
<!-- file: docs/architecture/001-WORKSPACE_ARCHITECTURE.md -->
|
||||||
<!-- version: 3 -->
|
<!-- version: 4 -->
|
||||||
|
|
||||||
# Architecture du workspace
|
# Architecture du workspace
|
||||||
|
|
||||||
@@ -20,11 +20,14 @@ games.sasedev/
|
|||||||
│ │ └── game-snake-poc/
|
│ │ └── game-snake-poc/
|
||||||
│ └── apps/
|
│ └── apps/
|
||||||
│ ├── game-reflex-poc-desktop/
|
│ ├── game-reflex-poc-desktop/
|
||||||
│ └── game-snake-poc-desktop/
|
│ ├── game-snake-poc-desktop/
|
||||||
|
│ └── game-reflex-poc-tauri/
|
||||||
├── assets/
|
├── assets/
|
||||||
│ ├── common/
|
│ ├── common/
|
||||||
│ ├── game-reflex-poc/
|
│ ├── game-reflex-poc/
|
||||||
│ └── game-snake-poc/
|
│ └── game-snake-poc/
|
||||||
|
├── Tauri/
|
||||||
|
│ └── game-reflex-poc/
|
||||||
├── Android/
|
├── Android/
|
||||||
│ ├── common/
|
│ ├── common/
|
||||||
│ ├── game-reflex-poc/
|
│ ├── game-reflex-poc/
|
||||||
@@ -66,3 +69,14 @@ Le runtime devra conserver une distinction logique entre ressources communes et
|
|||||||
## Runners Desktop
|
## Runners Desktop
|
||||||
|
|
||||||
Chaque crate de jeu reste une bibliothèque. Une crate binaire Desktop séparée sous `crates/apps/` la consomme pour permettre les itérations locales rapides. Cette séparation évite d’introduire `main`, des choix de plateforme ou du code de lancement dans le gameplay réutilisable.
|
Chaque crate de jeu reste une bibliothèque. Une crate binaire Desktop séparée sous `crates/apps/` la consomme pour permettre les itérations locales rapides. Cette séparation évite d’introduire `main`, des choix de plateforme ou du code de lancement dans le gameplay réutilisable.
|
||||||
|
|
||||||
|
## Variante Tauri / WebAssembly
|
||||||
|
|
||||||
|
La variante Tauri est distincte du runner SDL3 natif.
|
||||||
|
|
||||||
|
`game-reflex-poc-tauri` porte deux faces du même launcher :
|
||||||
|
|
||||||
|
- une bibliothèque `wasm32-unknown-unknown` qui adapte `game-reflex-poc` à `wasm-bindgen` ;
|
||||||
|
- un binaire natif Tauri qui héberge la WebView locale.
|
||||||
|
|
||||||
|
Le frontend statique sous `Tauri/game-reflex-poc/frontend/` pilote un Canvas et appelle l'adaptateur WASM. Les règles Reflex restent exclusivement dans `game-reflex-poc`.
|
||||||
|
|||||||
97
docs/development/008-WASM_TAURI_POC.md
Normal file
97
docs/development/008-WASM_TAURI_POC.md
Normal file
@@ -0,0 +1,97 @@
|
|||||||
|
<!-- file: docs/development/008-WASM_TAURI_POC.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# POC WebAssembly embarqué dans Tauri
|
||||||
|
|
||||||
|
## Objectif
|
||||||
|
|
||||||
|
Le POC vérifie qu'une même crate de gameplay Rust peut fonctionner :
|
||||||
|
|
||||||
|
- dans le runner Desktop SDL3 natif ;
|
||||||
|
- compilée en WebAssembly ;
|
||||||
|
- dans une WebView Tauri locale ;
|
||||||
|
- sans site distant ni serveur applicatif.
|
||||||
|
|
||||||
|
Le POC ne remplace pas le runner SDL3 natif.
|
||||||
|
|
||||||
|
## Découpage
|
||||||
|
|
||||||
|
```text
|
||||||
|
game-reflex-poc
|
||||||
|
|
|
||||||
|
+--> game-reflex-poc-desktop --> engine-v1-sdl --> SDL3 natif
|
||||||
|
|
|
||||||
|
+--> game-reflex-poc-tauri --wasm32--> wasm-bindgen --> Canvas Web
|
||||||
|
|
|
||||||
|
+--natif--> Tauri WebView
|
||||||
|
```
|
||||||
|
|
||||||
|
Le JavaScript ne contient aucune règle Reflex. Il traduit les événements pointeur vers l'adaptateur WASM et dessine la scène générique exposée par le moteur.
|
||||||
|
|
||||||
|
## Frontend local
|
||||||
|
|
||||||
|
Tauri agit comme hôte de fichiers Web statiques locaux. `frontendDist` pointe sur :
|
||||||
|
|
||||||
|
```text
|
||||||
|
Tauri/game-reflex-poc/frontend/
|
||||||
|
```
|
||||||
|
|
||||||
|
Aucun site, CDN, Vite ou gestionnaire de paquets JavaScript n'est requis par ce POC.
|
||||||
|
|
||||||
|
## Sécurité
|
||||||
|
|
||||||
|
La CSP reste locale. `wasm-unsafe-eval` est autorisé uniquement parce que la WebView charge du WebAssembly.
|
||||||
|
|
||||||
|
Aucun script distant n'est autorisé.
|
||||||
|
|
||||||
|
## Build WASM
|
||||||
|
|
||||||
|
Préparer une fois :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rustup target add wasm32-unknown-unknown
|
||||||
|
cargo install wasm-bindgen-cli --locked
|
||||||
|
```
|
||||||
|
|
||||||
|
Puis :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
python3 scripts/build_reflex_tauri_wasm.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Les fichiers générés sont ignorés par Git.
|
||||||
|
|
||||||
|
## Prérequis Tauri Linux
|
||||||
|
|
||||||
|
Le développement Tauri v2 requiert les bibliothèques système WebKitGTK/GTK correspondantes.
|
||||||
|
|
||||||
|
Sur Debian, vérifier notamment la présence de `libwebkit2gtk-4.1-dev` et des autres prérequis documentés par Tauri avant la gate Tauri.
|
||||||
|
|
||||||
|
Installer une fois le CLI si nécessaire :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cargo install tauri-cli --version "^2.0.0" --locked
|
||||||
|
```
|
||||||
|
|
||||||
|
## Exécution
|
||||||
|
|
||||||
|
Après génération du WASM :
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd crates/apps/game-reflex-poc-tauri
|
||||||
|
cargo tauri dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Critères :
|
||||||
|
|
||||||
|
- une fenêtre locale 405 × 720 s'ouvre ;
|
||||||
|
- le Canvas affiche le même fond et la même cible que Reflex SDL3 ;
|
||||||
|
- cliquer sur la cible incrémente le score et déplace la cible ;
|
||||||
|
- aucun site distant n'est requis ;
|
||||||
|
- le runtime est identifiable comme `Desktop + Wasm + TauriWebView + KeyboardMouse`.
|
||||||
|
|
||||||
|
## Frontière services Web
|
||||||
|
|
||||||
|
Ce POC ne choisit aucune régie publicitaire.
|
||||||
|
|
||||||
|
Il valide seulement qu'une variante Tauri possède une WebView capable d'héberger une frontière Web distincte. Ads, rewarded ads, revive, analytics et autres services resteront derrière `engine-v1-platform-api` et feront l'objet de tranches dédiées.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/rules/FILE_CONTRACTS.md -->
|
<!-- file: docs/rules/FILE_CONTRACTS.md -->
|
||||||
<!-- version: 3 -->
|
<!-- version: 4 -->
|
||||||
|
|
||||||
# Contrats des fichiers principaux
|
# Contrats des fichiers principaux
|
||||||
|
|
||||||
@@ -24,3 +24,9 @@
|
|||||||
- `assets/` contient les ressources runtime communes et spécifiques aux jeux ; aucune ressource runtime n'est placée dans une crate Rust.
|
- `assets/` contient les ressources runtime communes et spécifiques aux jeux ; aucune ressource runtime n'est placée dans une crate Rust.
|
||||||
- `Android/` contient le projet Gradle multi-module et son code Java commun/spécifique.
|
- `Android/` contient le projet Gradle multi-module et son code Java commun/spécifique.
|
||||||
- `crates/apps/` contient les exécutables de développement et launchers Rust, notamment les runners Desktop par jeu.
|
- `crates/apps/` contient les exécutables de développement et launchers Rust, notamment les runners Desktop par jeu.
|
||||||
|
|
||||||
|
## Tauri
|
||||||
|
|
||||||
|
- `Tauri/<game>/frontend/` contient le frontend Web statique versionné d'une variante Tauri.
|
||||||
|
- Les bindings JavaScript et modules `.wasm` générés restent ignorés par Git.
|
||||||
|
- Le backend Rust Tauri reste sous `crates/apps/`.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/rules/RULES_COMMANDS.md -->
|
<!-- file: docs/rules/RULES_COMMANDS.md -->
|
||||||
<!-- version: 4 -->
|
<!-- version: 5 -->
|
||||||
|
|
||||||
# Règles d'exécution des commandes
|
# Règles d'exécution des commandes
|
||||||
|
|
||||||
@@ -53,6 +53,8 @@
|
|||||||
|
|
||||||
- **CMD-WEB-001** — Aucun gestionnaire de paquets JavaScript ni build Web n'est exécuté tant qu'un frontend Web réel n'a pas été introduit dans le dépôt.
|
- **CMD-WEB-001** — Aucun gestionnaire de paquets JavaScript ni build Web n'est exécuté tant qu'un frontend Web réel n'a pas été introduit dans le dépôt.
|
||||||
- **CMD-WEB-002** — Lorsqu'une cible Web existe, ses commandes de build et test sont documentées avant d'être ajoutées aux gates.
|
- **CMD-WEB-002** — Lorsqu'une cible Web existe, ses commandes de build et test sont documentées avant d'être ajoutées aux gates.
|
||||||
|
- **CMD-WEB-003** — Le POC Tauri/WASM utilise `scripts/build_reflex_tauri_wasm.py`; aucun gestionnaire de paquets JavaScript ni serveur Web externe n'est requis pour cette variante.
|
||||||
|
- **CMD-WEB-004** — Les fichiers produits par `wasm-bindgen` sont générés localement et ne sont pas commités.
|
||||||
|
|
||||||
## Git et fichiers générés
|
## Git et fichiers générés
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<!-- file: docs/rules/RULES_PROJECT.md -->
|
<!-- file: docs/rules/RULES_PROJECT.md -->
|
||||||
<!-- version: 4 -->
|
<!-- version: 5 -->
|
||||||
|
|
||||||
# Règles spécifiques games.sasedev
|
# Règles spécifiques games.sasedev
|
||||||
|
|
||||||
@@ -49,6 +49,8 @@
|
|||||||
- **GAME-PLATFORM-004** — Ads et Billing sont des capacités optionnelles ; le gameplay reste fonctionnel lorsqu'elles sont disponibles, désactivées ou non supportées.
|
- **GAME-PLATFORM-004** — Ads et Billing sont des capacités optionnelles ; le gameplay reste fonctionnel lorsqu'elles sont disponibles, désactivées ou non supportées.
|
||||||
- **GAME-PLATFORM-005** — Un backend de monétisation est spécifique à sa plateforme et à sa distribution ; une intégration Android n'est pas réutilisée implicitement sur Web ou Desktop.
|
- **GAME-PLATFORM-005** — Un backend de monétisation est spécifique à sa plateforme et à sa distribution ; une intégration Android n'est pas réutilisée implicitement sur Web ou Desktop.
|
||||||
- **GAME-PLATFORM-006** — Le runner Desktop natif SDL3 est la forme Desktop par défaut. Une variante Tauri peut coexister uniquement lorsqu'un besoin explicite le justifie et consomme la même crate lib de jeu.
|
- **GAME-PLATFORM-006** — Le runner Desktop natif SDL3 est la forme Desktop par défaut. Une variante Tauri peut coexister uniquement lorsqu'un besoin explicite le justifie et consomme la même crate lib de jeu.
|
||||||
|
- **GAME-PLATFORM-007** — Une variante Tauri conserve son backend Rust sous `crates/apps/`; son frontend Web statique réside sous `Tauri/<game>/` et ne duplique pas le gameplay Rust.
|
||||||
|
- **GAME-PLATFORM-008** — Le gameplay compilé en WebAssembly est adapté par une frontière dédiée ; le code JavaScript orchestre la WebView, les événements et le rendu Canvas mais ne réimplémente pas les règles du jeu.
|
||||||
|
|
||||||
## POC
|
## POC
|
||||||
|
|
||||||
|
|||||||
26
history/0.1.0/1-alpha.1.md
Normal file
26
history/0.1.0/1-alpha.1.md
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<!-- file: history/0.1.0/1-alpha.1.md -->
|
||||||
|
<!-- version: 1 -->
|
||||||
|
|
||||||
|
# Historique 0.1.0-1-alpha.1
|
||||||
|
|
||||||
|
## Statut
|
||||||
|
|
||||||
|
Validé par l'utilisateur le 2026-09-16.
|
||||||
|
|
||||||
|
## Gates
|
||||||
|
|
||||||
|
- audits Rust/workspace propres ;
|
||||||
|
- audit Markdown : `1 table(s), 80 file(s)` ;
|
||||||
|
- `cargo check --workspace` propre ;
|
||||||
|
- Clippy workspace strict propre ;
|
||||||
|
- `engine-v1-platform-api` : 3/3 tests ;
|
||||||
|
- `engine-v1-common` : 8/8 tests ;
|
||||||
|
- `engine-v1-sdl` : 5/5 tests ;
|
||||||
|
- `game-reflex-poc` : 4/4 tests ;
|
||||||
|
- `game-snake-poc` : 5/5 tests ;
|
||||||
|
- smoke Desktop Snake propre ;
|
||||||
|
- smoke Desktop Reflex propre.
|
||||||
|
|
||||||
|
## Portée validée
|
||||||
|
|
||||||
|
La provenance runtime/input est disponible comme donnée descriptive indépendante de la politique de classement.
|
||||||
56
scripts/build_reflex_tauri_wasm.py
Normal file
56
scripts/build_reflex_tauri_wasm.py
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
# file: scripts/build_reflex_tauri_wasm.py
|
||||||
|
# version: 1
|
||||||
|
|
||||||
|
"""Build the Reflex WASM adapter and generate browser bindings for the local Tauri frontend."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import pathlib
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
"""Build the WASM library and run wasm-bindgen into the committed Tauri frontend directory."""
|
||||||
|
|
||||||
|
root = pathlib.Path(__file__).resolve().parent.parent
|
||||||
|
target_dir = root.parent / "builds" / "sasedev-games" / "target"
|
||||||
|
wasm_path = target_dir / "wasm32-unknown-unknown" / "debug" / "game_reflex_poc_tauri.wasm"
|
||||||
|
output_dir = root / "Tauri" / "game-reflex-poc" / "frontend"
|
||||||
|
|
||||||
|
build = subprocess.run(
|
||||||
|
["cargo", "build", "-p", "game-reflex-poc-tauri", "--lib", "--target", "wasm32-unknown-unknown"],
|
||||||
|
cwd=root,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
if build.returncode != 0:
|
||||||
|
return build.returncode
|
||||||
|
if not wasm_path.is_file():
|
||||||
|
print(f"WASM artifact not found: {wasm_path}", file=sys.stderr)
|
||||||
|
return 2
|
||||||
|
|
||||||
|
bindings = subprocess.run(
|
||||||
|
[
|
||||||
|
"wasm-bindgen",
|
||||||
|
str(wasm_path),
|
||||||
|
"--target",
|
||||||
|
"web",
|
||||||
|
"--out-dir",
|
||||||
|
str(output_dir),
|
||||||
|
"--out-name",
|
||||||
|
"game_reflex_poc_tauri",
|
||||||
|
"--no-typescript",
|
||||||
|
],
|
||||||
|
cwd=root,
|
||||||
|
check=False,
|
||||||
|
)
|
||||||
|
if bindings.returncode != 0:
|
||||||
|
return bindings.returncode
|
||||||
|
|
||||||
|
print(f"Reflex Tauri WASM frontend generated in {output_dir}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
raise SystemExit(main())
|
||||||
Reference in New Issue
Block a user