From 60917106ab0135b41cd3675d78b3b9ee0bc18170 Mon Sep 17 00:00:00 2001 From: white-axe Date: Sat, 7 Oct 2023 00:50:29 +0000 Subject: [PATCH] Move JavaScript bindings into bindings.js and bindings.rs --- src/filesystem/web.rs | 65 ++++-------------------------------- src/main.rs | 3 +- src/web/mod.rs | 8 +---- src/web/web_worker_runner.rs | 38 ++++++++------------- 4 files changed, 23 insertions(+), 91 deletions(-) diff --git a/src/filesystem/web.rs b/src/filesystem/web.rs index 9bb2cb33..ab72f92e 100644 --- a/src/filesystem/web.rs +++ b/src/filesystem/web.rs @@ -17,6 +17,8 @@ use crate::prelude::*; use wasm_bindgen::prelude::*; +use crate::web::bindings; + use super::FileSystem as FileSystemTrait; use super::{DirEntry, Error, Metadata, OpenFlags}; @@ -309,56 +311,6 @@ impl std::io::Seek for File { } } -#[wasm_bindgen(inline_js = " -export function filesystem_supported() { - return typeof window?.showOpenFilePicker === 'function' - && typeof window?.showDirectoryPicker === 'function' - && typeof FileSystemFileHandle === 'function' - && typeof FileSystemWritableFileStream === 'function' - && typeof FileSystemFileHandle?.prototype?.remove === 'function' - && typeof FileSystemDirectoryHandle?.prototype?.remove === 'function'; -}")] -extern "C" { - fn filesystem_supported() -> bool; -} - -#[wasm_bindgen( - inline_js = "export async function show_directory_picker() { return await showDirectoryPicker({ mode: 'readwrite' }); }" -)] -extern "C" { - #[wasm_bindgen(catch)] - async fn show_directory_picker() -> Result; -} - -#[wasm_bindgen( - inline_js = "export async function move_file(file, dir, filename) { await file.move(dir, filename); }" -)] -extern "C" { - #[wasm_bindgen(catch)] - async fn move_file( - file: &web_sys::FileSystemFileHandle, - dir: &web_sys::FileSystemDirectoryHandle, - filename: &str, - ) -> Result; -} - -#[wasm_bindgen(inline_js = "export async function remove_file(file) { await file.remove(); }")] -extern "C" { - #[wasm_bindgen(catch)] - async fn remove_file(file: &web_sys::FileSystemFileHandle) -> Result; -} - -#[wasm_bindgen(inline_js = "export async function remove_dir(dir) { await dir.remove(); }")] -extern "C" { - #[wasm_bindgen(catch)] - async fn remove_dir(dir: &web_sys::FileSystemDirectoryHandle) -> Result; -} - -#[wasm_bindgen(inline_js = "export function dir_values(dir) { return dir.values(); }")] -extern "C" { - fn dir_values(dir: &web_sys::FileSystemDirectoryHandle) -> js_sys::AsyncIterator; -} - pub fn setup_main_thread_hooks(mut filesystem_rx: mpsc::UnboundedReceiver) { wasm_bindgen_futures::spawn_local(async move { web_sys::window().expect("cannot run `setup_main_thread_hooks()` outside of main thread"); @@ -411,7 +363,7 @@ pub fn setup_main_thread_hooks(mut filesystem_rx: mpsc::UnboundedReceiver { - oneshot_tx.send(filesystem_supported()).unwrap(); + oneshot_tx.send(bindings::filesystem_supported()).unwrap(); } FileSystemCommandInner::Metadata(key, path, oneshot_tx) => { @@ -465,10 +417,7 @@ pub fn setup_main_thread_hooks(mut filesystem_rx: mpsc::UnboundedReceiver { - if let Ok(dir) = show_directory_picker() - .await - .map(|x| x.unchecked_into::()) - { + if let Ok(dir) = bindings::show_directory_picker().await { let name = dir.name(); oneshot_tx.send(Some((dirs.insert(dir), name))).unwrap(); } else { @@ -664,7 +613,7 @@ pub fn setup_main_thread_hooks(mut filesystem_rx: mpsc::UnboundedReceiver(subdir.get_file_handle(filename)) .await { - if remove_file(&file).await.is_ok() { + if bindings::remove_file(&file).await.is_ok() { oneshot_tx.send(Ok(())).unwrap(); } else { oneshot_tx @@ -727,7 +676,7 @@ pub fn setup_main_thread_hooks(mut filesystem_rx: mpsc::UnboundedReceiver(entry_iter.next().unwrap()) diff --git a/src/main.rs b/src/main.rs index 8427933b..38fd7719 100644 --- a/src/main.rs +++ b/src/main.rs @@ -217,7 +217,8 @@ pub async fn luminol_worker_start(canvas: web_sys::OffscreenCanvas) { panic!("failed to initialize global callback variables"); } - luminol::web::get_worker() + luminol::web::bindings::worker() + .unwrap() .post_message(&JsValue::null()) .expect("failed to post callback message from web worker to main thread"); diff --git a/src/web/mod.rs b/src/web/mod.rs index d75446e0..ef3edf4a 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -14,12 +14,6 @@ // // You should have received a copy of the GNU General Public License // along with Luminol. If not, see . +pub mod bindings; pub mod web_worker_runner; pub use web_worker_runner::WebWorkerRunner; - -use wasm_bindgen::prelude::*; - -#[wasm_bindgen(inline_js = "export function get_worker() { return self; }")] -extern "C" { - pub fn get_worker() -> web_sys::DedicatedWorkerGlobalScope; -} diff --git a/src/web/web_worker_runner.rs b/src/web/web_worker_runner.rs index 941c284a..8c030430 100644 --- a/src/web/web_worker_runner.rs +++ b/src/web/web_worker_runner.rs @@ -14,25 +14,11 @@ // // You should have received a copy of the GNU General Public License // along with Luminol. If not, see . -use super::get_worker; +use super::bindings; use crate::prelude::*; use eframe::{egui_wgpu, wgpu}; use wasm_bindgen::prelude::*; -#[wasm_bindgen( - inline_js = "export function is_worker() { return self instanceof DedicatedWorkerGlobalScope; }" -)] -extern "C" { - fn is_worker() -> bool; -} - -// A binding for this attribute was added in July 2023 but hasn't made its way into a release of -// web-sys as of September 2023 -#[wasm_bindgen(inline_js = "export function performance(w) { return w.performance; }")] -extern "C" { - fn performance(worker: &web_sys::DedicatedWorkerGlobalScope) -> Option; -} - #[derive(Debug, Default)] struct Storage {} @@ -85,12 +71,11 @@ impl WebWorkerRunner { screen_resize_rx: Option>, event_rx: Option>, ) -> Self { - if !is_worker() { + let Some(worker) = bindings::worker() else { panic!("cannot use `WebWorkerRunner::new()` outside of a web worker"); - } + }; let time_lock = Arc::new(RwLock::new(0.)); - let worker = get_worker(); let instance = wgpu::Instance::new(wgpu::InstanceDescriptor { backends: web_options.wgpu_options.supported_backends, @@ -175,8 +160,9 @@ impl WebWorkerRunner { { let time_lock = time_lock.clone(); context.set_request_repaint_callback(move |i| { - *time_lock.write() = - performance(&get_worker()).unwrap().now() / 1000. + i.after.as_secs_f64(); + *time_lock.write() = bindings::performance(&bindings::worker().unwrap()).now() + / 1000. + + i.after.as_secs_f64(); }); } @@ -205,7 +191,7 @@ impl WebWorkerRunner { pub fn setup_render_hooks(self) { let callback = Closure::once(move || { let mut state = self.state.borrow_mut(); - let worker = get_worker(); + let worker = bindings::worker().unwrap(); // Resize the canvas if the screen size has changed if let Some(screen_resize_rx) = &mut state.screen_resize_rx { @@ -240,7 +226,7 @@ impl WebWorkerRunner { } // Render only if sufficient time has passed since the last render - if performance(&worker).unwrap().now() / 1000. >= *self.time_lock.read() { + if bindings::performance(&worker).now() / 1000. >= *self.time_lock.read() { // Ask the app to paint the next frame let input = egui::RawInput { screen_rect: Some(egui::Rect::from_min_max( @@ -251,7 +237,7 @@ impl WebWorkerRunner { ), )), pixels_per_point: state.native_pixels_per_point, - time: Some(performance(&worker).unwrap().now() / 1000.), + time: Some(bindings::performance(&worker).now() / 1000.), max_texture_side: Some( state.render_state.device.limits().max_texture_dimension_2d as usize, ), @@ -342,14 +328,16 @@ impl WebWorkerRunner { ); state.surface.get_current_texture().unwrap().present(); - *self.time_lock.write() = performance(&worker).unwrap().now() / 1000. + *self.time_lock.write() = bindings::performance(&worker).now() / 1000. + output.repaint_after.as_secs_f64(); } self.clone().setup_render_hooks(); }); - let _ = get_worker().request_animation_frame(callback.as_ref().unchecked_ref()); + let _ = bindings::worker() + .unwrap() + .request_animation_frame(callback.as_ref().unchecked_ref()); callback.forget(); } }