Ok so I found a way. Perhaps not efficient, but it works.
in main.rs:
use wasm_bindgen::{prelude::wasm_bindgen, JsValue}; use serde::{Serialize, Deserialize}; use std::sync::Mutex; #[derive(Serialize, Deserialize)] pub struct CursorState { pub state: bool, } pub static JS_EVENT_QUEUE: Mutex<Vec<JsEvent>> = Mutex::new(Vec::new()); #[derive(Debug, Serialize, Clone)] pub struct JsEvent(pub bool); #[wasm_bindgen] pub fn send_state_to_js() -> JsValue { let state = CursorState{ state: false }; info!("alert getting states"); serde_wasm_bindgen::to_value(&state).unwrap() } #[wasm_bindgen] pub fn lock_change_alert(val: JsValue) { let state: CursorState = serde_wasm_bindgen::from_value(val).unwrap(); info!("alert from rust: {}", state.state); JS_EVENT_QUEUE.lock().unwrap().push(JsEvent(state.state)); }
And then in a Update system:
let mut event_queue = JS_EVENT_QUEUE.lock().unwrap(); let events = event_queue.drain(..).collect::<Vec<_>>(); for event in events { if !event.0{ info!("alert cursor event"); window.cursor = Cursor { visible: true, grab_mode: bevy::window::CursorGrabMode::None, ..default() }; } }
And because for now I went for simplicity, in your index.html:
<script type="module"> import {send_state_to_js, lock_change_alert} from './GameName.js'; document.addEventListener("pointerlockchange", lockChangeAlert, false); function lockChangeAlert() { const locked = document.pointerLockElement; Boolean(locked); console.log("lock change alert"); let state = send_state_to_js(); state.state = Boolean(locked); lock_change_alert(state); } </script>
Have fun,
Kam
edit: place code in code blocks