Desktop: Remove editor from wasm wrapper (#3023)

* Add a few useful npm scripts for native

* Allow compiler to prune editor from wasm wrapper in native builds

* Fix warnings

* Review cleanup

* Fix npm desktop build script names
This commit is contained in:
Timon 2025-08-07 18:26:20 +02:00 committed by GitHub
parent 1164359c59
commit 81abfe147a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 34 additions and 10 deletions

View File

@ -11,16 +11,18 @@
"profiling": "npm run setup && npm run wasm:build-profiling && concurrently -k -n \"VITE,RUST\" \"vite\" \"npm run wasm:watch-profiling\"", "profiling": "npm run setup && npm run wasm:build-profiling && concurrently -k -n \"VITE,RUST\" \"vite\" \"npm run wasm:watch-profiling\"",
"production": "npm run setup && npm run wasm:build-production && concurrently -k -n \"VITE,RUST\" \"vite\" \"npm run wasm:watch-production\"", "production": "npm run setup && npm run wasm:build-production && concurrently -k -n \"VITE,RUST\" \"vite\" \"npm run wasm:watch-production\"",
"---------- BUILDS ----------": "", "---------- BUILDS ----------": "",
"build-dev": "npm run wasm:build-dev && vite build",
"build-native": "npm run native:build-dev && vite build",
"build-profiling": "npm run wasm:build-profiling && vite build",
"build": "npm run wasm:build-production && vite build", "build": "npm run wasm:build-production && vite build",
"build-dev": "npm run wasm:build-dev && vite build",
"build-native": "npm run native:build-production && vite build",
"build-native-dev": "npm run native:build-dev && vite build",
"build-profiling": "npm run wasm:build-profiling && vite build",
"---------- UTILITIES ----------": "", "---------- UTILITIES ----------": "",
"lint": "eslint . && tsc --noEmit", "lint": "eslint . && tsc --noEmit",
"lint-fix": "eslint . --fix && tsc --noEmit", "lint-fix": "eslint . --fix && tsc --noEmit",
"---------- INTERNAL ----------": "", "---------- INTERNAL ----------": "",
"setup": "node package-installer.js", "setup": "node package-installer.js",
"native:build-dev": "wasm-pack build ./wasm --dev --target=web --features native", "native:build-dev": "wasm-pack build ./wasm --dev --target=web --features native",
"native:build-production": "wasm-pack build ./wasm --release --target=web --features native",
"wasm:build-dev": "wasm-pack build ./wasm --dev --target=web", "wasm:build-dev": "wasm-pack build ./wasm --dev --target=web",
"wasm:build-profiling": "wasm-pack build ./wasm --profiling --target=web", "wasm:build-profiling": "wasm-pack build ./wasm --profiling --target=web",
"wasm:build-production": "wasm-pack build ./wasm --release --target=web", "wasm:build-production": "wasm-pack build ./wasm --release --target=web",

View File

@ -5,8 +5,7 @@
// on the dispatcher messaging system and more complex Rust data types. // on the dispatcher messaging system and more complex Rust data types.
// //
use crate::helpers::translate_key; use crate::helpers::translate_key;
use crate::{EDITOR, EDITOR_HANDLE, EDITOR_HAS_CRASHED, Error, MESSAGE_BUFFER}; use crate::{EDITOR_HANDLE, EDITOR_HAS_CRASHED, Error, MESSAGE_BUFFER};
use editor::application::Editor;
use editor::consts::FILE_SAVE_SUFFIX; use editor::consts::FILE_SAVE_SUFFIX;
use editor::messages::input_mapper::utility_types::input_keyboard::ModifierKeys; use editor::messages::input_mapper::utility_types::input_keyboard::ModifierKeys;
use editor::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, ScrollDelta, ViewportBounds}; use editor::messages::input_mapper::utility_types::input_mouse::{EditorMouseState, ScrollDelta, ViewportBounds};
@ -28,6 +27,11 @@ use wasm_bindgen::JsCast;
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement, ImageData, window}; use web_sys::{CanvasRenderingContext2d, HtmlCanvasElement, ImageData, window};
#[cfg(not(feature = "native"))]
use crate::EDITOR;
#[cfg(not(feature = "native"))]
use editor::application::Editor;
static IMAGE_DATA_HASH: AtomicU64 = AtomicU64::new(0); static IMAGE_DATA_HASH: AtomicU64 = AtomicU64::new(0);
fn calculate_hash<T: std::hash::Hash>(t: &T) -> u64 { fn calculate_hash<T: std::hash::Hash>(t: &T) -> u64 {
@ -140,6 +144,7 @@ impl EditorHandle {
#[wasm_bindgen] #[wasm_bindgen]
impl EditorHandle { impl EditorHandle {
#[cfg(not(feature = "native"))]
#[wasm_bindgen(constructor)] #[wasm_bindgen(constructor)]
pub fn new(frontend_message_handler_callback: js_sys::Function) -> Self { pub fn new(frontend_message_handler_callback: js_sys::Function) -> Self {
let editor = Editor::new(); let editor = Editor::new();
@ -153,6 +158,16 @@ impl EditorHandle {
editor_handle editor_handle
} }
#[cfg(feature = "native")]
#[wasm_bindgen(constructor)]
pub fn new(frontend_message_handler_callback: js_sys::Function) -> Self {
let editor_handle = EditorHandle { frontend_message_handler_callback };
if EDITOR_HANDLE.with(|handle| handle.lock().ok().map(|mut guard| *guard = Some(editor_handle.clone()))).is_none() {
log::error!("Attempted to initialize the editor handle more than once");
}
editor_handle
}
// Sends a message to the dispatcher in the Editor Backend // Sends a message to the dispatcher in the Editor Backend
#[cfg(not(feature = "native"))] #[cfg(not(feature = "native"))]
fn dispatch<T: Into<Message>>(&self, message: T) { fn dispatch<T: Into<Message>>(&self, message: T) {
@ -247,6 +262,7 @@ impl EditorHandle {
let g = f.clone(); let g = f.clone();
*g.borrow_mut() = Some(Closure::new(move |_timestamp| { *g.borrow_mut() = Some(Closure::new(move |_timestamp| {
#[cfg(not(feature = "native"))]
wasm_bindgen_futures::spawn_local(poll_node_graph_evaluation()); wasm_bindgen_futures::spawn_local(poll_node_graph_evaluation());
if !EDITOR_HAS_CRASHED.load(Ordering::SeqCst) { if !EDITOR_HAS_CRASHED.load(Ordering::SeqCst) {
@ -929,6 +945,7 @@ fn set_timeout(f: &Closure<dyn FnMut()>, delay: Duration) {
} }
/// Provides access to the `Editor` by calling the given closure with it as an argument. /// Provides access to the `Editor` by calling the given closure with it as an argument.
#[cfg(not(feature = "native"))]
fn editor<T: Default>(callback: impl FnOnce(&mut editor::application::Editor) -> T) -> T { fn editor<T: Default>(callback: impl FnOnce(&mut editor::application::Editor) -> T) -> T {
EDITOR.with(|editor| { EDITOR.with(|editor| {
let mut guard = editor.try_lock(); let mut guard = editor.try_lock();
@ -942,6 +959,7 @@ fn editor<T: Default>(callback: impl FnOnce(&mut editor::application::Editor) ->
} }
/// Provides access to the `Editor` and its `EditorHandle` by calling the given closure with them as arguments. /// Provides access to the `Editor` and its `EditorHandle` by calling the given closure with them as arguments.
#[cfg(not(feature = "native"))]
pub(crate) fn editor_and_handle(callback: impl FnOnce(&mut Editor, &mut EditorHandle)) { pub(crate) fn editor_and_handle(callback: impl FnOnce(&mut Editor, &mut EditorHandle)) {
handle(|editor_handle| { handle(|editor_handle| {
editor(|editor| { editor(|editor| {
@ -964,6 +982,7 @@ pub(crate) fn handle(callback: impl FnOnce(&mut EditorHandle)) {
}); });
} }
#[cfg(not(feature = "native"))]
async fn poll_node_graph_evaluation() { async fn poll_node_graph_evaluation() {
// Process no further messages after a crash to avoid spamming the console // Process no further messages after a crash to avoid spamming the console
if EDITOR_HAS_CRASHED.load(Ordering::SeqCst) { if EDITOR_HAS_CRASHED.load(Ordering::SeqCst) {

View File

@ -20,6 +20,7 @@ pub static NODE_GRAPH_ERROR_DISPLAYED: AtomicBool = AtomicBool::new(false);
pub static LOGGER: WasmLog = WasmLog; pub static LOGGER: WasmLog = WasmLog;
thread_local! { thread_local! {
#[cfg(not(feature = "native"))]
pub static EDITOR: Mutex<Option<editor::application::Editor>> = const { Mutex::new(None) }; pub static EDITOR: Mutex<Option<editor::application::Editor>> = const { Mutex::new(None) };
pub static MESSAGE_BUFFER: std::cell::RefCell<Vec<Message>> = const { std::cell::RefCell::new(Vec::new()) }; pub static MESSAGE_BUFFER: std::cell::RefCell<Vec<Message>> = const { std::cell::RefCell::new(Vec::new()) };
pub static EDITOR_HANDLE: Mutex<Option<editor_api::EditorHandle>> = const { Mutex::new(None) }; pub static EDITOR_HANDLE: Mutex<Option<editor_api::EditorHandle>> = const { Mutex::new(None) };
@ -50,7 +51,7 @@ pub fn panic_hook(info: &panic::PanicHookInfo) {
if !NODE_GRAPH_ERROR_DISPLAYED.load(Ordering::SeqCst) { if !NODE_GRAPH_ERROR_DISPLAYED.load(Ordering::SeqCst) {
NODE_GRAPH_ERROR_DISPLAYED.store(true, Ordering::SeqCst); NODE_GRAPH_ERROR_DISPLAYED.store(true, Ordering::SeqCst);
editor_api::editor_and_handle(|_, handle| { editor_api::handle(|handle| {
let error = r#" let error = r#"
<rect x="50%" y="50%" width="600" height="100" transform="translate(-300 -50)" rx="4" fill="var(--color-error-red)" /> <rect x="50%" y="50%" width="600" height="100" transform="translate(-300 -50)" rx="4" fill="var(--color-error-red)" />
<text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-size="18" fill="var(--color-2-mildblack)"> <text x="50%" y="50%" dominant-baseline="middle" text-anchor="middle" font-size="18" fill="var(--color-2-mildblack)">

View File

@ -1,4 +1,4 @@
use editor::{application::Editor, messages::prelude::FrontendMessage}; use editor::messages::prelude::FrontendMessage;
use js_sys::{ArrayBuffer, Uint8Array}; use js_sys::{ArrayBuffer, Uint8Array};
use wasm_bindgen::prelude::*; use wasm_bindgen::prelude::*;
@ -9,12 +9,12 @@ pub fn receive_native_message(buffer: ArrayBuffer) {
let buffer = Uint8Array::new(buffer.as_ref()).to_vec(); let buffer = Uint8Array::new(buffer.as_ref()).to_vec();
match ron::from_str::<Vec<FrontendMessage>>(str::from_utf8(buffer.as_slice()).unwrap()) { match ron::from_str::<Vec<FrontendMessage>>(str::from_utf8(buffer.as_slice()).unwrap()) {
Ok(messages) => { Ok(messages) => {
let callback = move |_: &mut Editor, handle: &mut EditorHandle| { let callback = move |handle: &mut EditorHandle| {
for message in messages { for message in messages {
handle.send_frontend_message_to_js_rust_proxy(message); handle.send_frontend_message_to_js_rust_proxy(message);
} }
}; };
editor_api::editor_and_handle(callback); editor_api::handle(callback);
} }
Err(e) => log::error!("Failed to deserialize frontend messages: {e:?}"), Err(e) => log::error!("Failed to deserialize frontend messages: {e:?}"),
} }

View File

@ -4,13 +4,15 @@
"scripts": { "scripts": {
"---------- DEV SERVER ----------": "", "---------- DEV SERVER ----------": "",
"start": "cd frontend && npm start", "start": "cd frontend && npm start",
"start-desktop": "cd frontend && npm run build-native && cargo run -p graphite-desktop", "start-desktop": "cd frontend && npm run build-native-dev && cargo run -p graphite-desktop",
"profiling": "cd frontend && npm run profiling", "profiling": "cd frontend && npm run profiling",
"production": "cd frontend && npm run production", "production": "cd frontend && npm run production",
"---------- BUILDS ----------": "", "---------- BUILDS ----------": "",
"build-dev": "cd frontend && npm run build-dev", "build-dev": "cd frontend && npm run build-dev",
"build-profiling": "cd frontend && npm run build-profiling", "build-profiling": "cd frontend && npm run build-profiling",
"build": "cd frontend && npm run build", "build": "cd frontend && npm run build",
"build-desktop": "cd frontend && npm run build-native && cargo build -r -p graphite-desktop",
"build-desktop-dev": "cd frontend && npm run build-native-dev && cargo build -p graphite-desktop",
"---------- UTILITIES ----------": "", "---------- UTILITIES ----------": "",
"lint": "cd frontend && npm run lint", "lint": "cd frontend && npm run lint",
"lint-fix": "cd frontend && npm run lint-fix" "lint-fix": "cd frontend && npm run lint-fix"