mirror of
https://github.com/Xevion/smart-rgb.git
synced 2025-12-06 05:16:35 -06:00
69 lines
2.6 KiB
Rust
69 lines
2.6 KiB
Rust
//! WASM-specific frontend transport using JavaScript callbacks
|
|
//!
|
|
//! This module provides the WASM implementation of FrontendTransport,
|
|
//! sending render messages and UI events through JavaScript callbacks to the browser frontend.
|
|
|
|
use std::cell::RefCell;
|
|
use std::collections::VecDeque;
|
|
|
|
use borders_core::ui::FrontendTransport;
|
|
use borders_core::ui::protocol::{BackendMessage, FrontendMessage};
|
|
use wasm_bindgen::prelude::*;
|
|
|
|
// Thread-local storage for callbacks and inbound messages
|
|
thread_local! {
|
|
static BACKEND_MESSAGE_CALLBACK: RefCell<Option<js_sys::Function>> = const { RefCell::new(None) };
|
|
static INBOUND_MESSAGES: RefCell<VecDeque<FrontendMessage>> = const { RefCell::new(VecDeque::new()) };
|
|
}
|
|
|
|
/// Register a callback for backend messages (all messages from backend to frontend)
|
|
#[wasm_bindgen]
|
|
pub fn register_backend_message_callback(callback: js_sys::Function) {
|
|
BACKEND_MESSAGE_CALLBACK.with(|cb| {
|
|
*cb.borrow_mut() = Some(callback);
|
|
});
|
|
}
|
|
|
|
/// Send a frontend message from JavaScript to the game core
|
|
#[wasm_bindgen]
|
|
pub fn send_frontend_message(msg: JsValue) -> Result<(), JsValue> {
|
|
let message: FrontendMessage = serde_wasm_bindgen::from_value(msg).map_err(|e| JsValue::from_str(&format!("Failed to deserialize frontend message: {}", e)))?;
|
|
|
|
INBOUND_MESSAGES.with(|messages_cell| {
|
|
messages_cell.borrow_mut().push_back(message);
|
|
});
|
|
|
|
Ok(())
|
|
}
|
|
|
|
/// WASM-specific frontend transport using JavaScript callbacks
|
|
#[derive(Clone)]
|
|
pub struct WasmRenderBridgeTransport;
|
|
|
|
impl FrontendTransport for WasmRenderBridgeTransport {
|
|
fn send_backend_message(&self, message: &BackendMessage) -> Result<(), String> {
|
|
BACKEND_MESSAGE_CALLBACK.with(|cb_cell| {
|
|
if let Some(cb) = cb_cell.borrow().as_ref() {
|
|
match serde_wasm_bindgen::to_value(message) {
|
|
Ok(js_payload) => {
|
|
let this = JsValue::null();
|
|
if let Err(e) = cb.call1(&this, &js_payload) {
|
|
return Err(format!("Backend message callback failed: {:?}", e));
|
|
}
|
|
Ok(())
|
|
}
|
|
Err(e) => Err(format!("Failed to serialize backend message: {}", e)),
|
|
}
|
|
} else {
|
|
Err("No backend message callback registered".to_string())
|
|
}
|
|
})
|
|
}
|
|
|
|
fn try_recv_frontend_message(&self) -> Option<FrontendMessage> {
|
|
INBOUND_MESSAGES.with(|messages_cell| messages_cell.borrow_mut().pop_front())
|
|
}
|
|
|
|
// WASM uses structured messages only, no binary streaming
|
|
}
|