Hook up request animation frame plumbing to decouple execution

This commit is contained in:
Dennis Kobert 2023-05-11 22:12:44 +02:00 committed by Keavon Chambers
parent fffbaa6de2
commit c648e25e8c
8 changed files with 108 additions and 8 deletions

View file

@ -23,15 +23,23 @@ editor = { path = "../../editor", package = "graphite-editor" }
document-legacy = { path = "../../document-legacy", package = "graphite-document-legacy" }
graph-craft = { path = "../../node-graph/graph-craft" }
log = "0.4"
graphene-core = { path = "../../node-graph/gcore", features = ["async", "std", "alloc"] }
graphene-core = { path = "../../node-graph/gcore", features = [
"async",
"std",
"alloc",
] }
serde = { version = "1.0", features = ["derive"] }
wasm-bindgen = { version = "0.2.84" }
serde-wasm-bindgen = "0.4.1"
js-sys = "0.3.55"
wasm-bindgen-futures = "0.4.33"
ron = {version = "0.8", optional = true}
ron = { version = "0.8", optional = true }
bezier-rs = { path = "../../libraries/bezier-rs" }
[dependencies.web-sys]
version = "0.3.4"
features = ['Window']
[dev-dependencies]
wasm-bindgen-test = "0.3.22"

View file

@ -18,6 +18,7 @@ use graphene_core::raster::color::Color;
use serde::Serialize;
use serde_wasm_bindgen::{self, from_value};
use std::cell::RefCell;
use std::sync::atomic::Ordering;
use wasm_bindgen::prelude::*;
@ -53,6 +54,50 @@ pub struct JsEditorHandle {
frontend_message_handler_callback: js_sys::Function,
}
fn window() -> web_sys::Window {
web_sys::window().expect("no global `window` exists")
}
fn request_animation_frame(f: &Closure<dyn FnMut()>) {
window().request_animation_frame(f.as_ref().unchecked_ref()).expect("should register `requestAnimationFrame` OK");
}
// Sends a message to the dispatcher in the Editor Backend
fn poll_node_graph_evaluation() {
// Process no further messages after a crash to avoid spamming the console
if EDITOR_HAS_CRASHED.load(Ordering::SeqCst) {
return;
}
editor::node_graph_executor::run_node_graph();
// Get the editor instances, dispatch the message, and store the `FrontendMessage` queue response
EDITOR_INSTANCES.with(|instances| {
JS_EDITOR_HANDLES.with(|handles| {
// Mutably borrow the editors, and if successful, we can access them in the closure
instances.try_borrow_mut().map(|mut editors| {
// Get the editor instance for this editor ID, then dispatch the message to the backend, and return its response `FrontendMessage` queue
for (id, editor) in editors.iter_mut() {
let handles = handles.borrow_mut();
let handle = handles.get(id).unwrap();
let mut messages = VecDeque::new();
editor.poll_node_graph_evaluation(&mut messages);
// Send each `FrontendMessage` to the JavaScript frontend
let mut responses = Vec::new();
for message in messages.into_iter() {
responses.extend(editor.handle_message(message));
}
for response in responses.into_iter() {
handle.send_frontend_message_to_js(response);
}
// If the editor cannot be borrowed then it has encountered a panic - we should just ignore new dispatches
}
})
})
});
}
#[wasm_bindgen]
#[allow(clippy::too_many_arguments)]
impl JsEditorHandle {
@ -165,6 +210,18 @@ impl JsEditorHandle {
self.dispatch(GlobalsMessage::SetPlatform { platform });
self.dispatch(Message::Init);
let f = std::rc::Rc::new(RefCell::new(None));
let g = f.clone();
*g.borrow_mut() = Some(Closure::new(move || {
poll_node_graph_evaluation();
// Schedule ourself for another requestAnimationFrame callback.
request_animation_frame(f.borrow().as_ref().unwrap());
}));
request_animation_frame(g.borrow().as_ref().unwrap());
}
#[wasm_bindgen(js_name = tauriResponse)]