Skip to content

Commit

Permalink
Move JavaScript bindings into bindings.js and bindings.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
white-axe committed Oct 7, 2023
1 parent 0e331ce commit 6091710
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 91 deletions.
65 changes: 7 additions & 58 deletions src/filesystem/web.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down Expand Up @@ -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<JsValue, JsValue>;
}

#[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<JsValue, JsValue>;
}

#[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<JsValue, JsValue>;
}

#[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<JsValue, JsValue>;
}

#[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<FileSystemCommand>) {
wasm_bindgen_futures::spawn_local(async move {
web_sys::window().expect("cannot run `setup_main_thread_hooks()` outside of main thread");
Expand Down Expand Up @@ -411,7 +363,7 @@ pub fn setup_main_thread_hooks(mut filesystem_rx: mpsc::UnboundedReceiver<FileSy

match command.0 {
FileSystemCommandInner::Supported(oneshot_tx) => {
oneshot_tx.send(filesystem_supported()).unwrap();
oneshot_tx.send(bindings::filesystem_supported()).unwrap();
}

FileSystemCommandInner::Metadata(key, path, oneshot_tx) => {
Expand Down Expand Up @@ -465,10 +417,7 @@ pub fn setup_main_thread_hooks(mut filesystem_rx: mpsc::UnboundedReceiver<FileSy
}

FileSystemCommandInner::DirPicker(oneshot_tx) => {
if let Ok(dir) = show_directory_picker()
.await
.map(|x| x.unchecked_into::<web_sys::FileSystemDirectoryHandle>())
{
if let Ok(dir) = bindings::show_directory_picker().await {
let name = dir.name();
oneshot_tx.send(Some((dirs.insert(dir), name))).unwrap();
} else {
Expand Down Expand Up @@ -664,7 +613,7 @@ pub fn setup_main_thread_hooks(mut filesystem_rx: mpsc::UnboundedReceiver<FileSy
)
.await
{
if remove_dir(&dir).await.is_ok() {
if bindings::remove_dir(&dir).await.is_ok() {
oneshot_tx.send(Ok(())).unwrap();
} else {
oneshot_tx
Expand Down Expand Up @@ -696,7 +645,7 @@ pub fn setup_main_thread_hooks(mut filesystem_rx: mpsc::UnboundedReceiver<FileSy
to_future::<web_sys::FileSystemFileHandle>(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
Expand Down Expand Up @@ -727,7 +676,7 @@ pub fn setup_main_thread_hooks(mut filesystem_rx: mpsc::UnboundedReceiver<FileSy
oneshot_tx.send(Err(Error::NotExist)).unwrap();
continue;
};
let entry_iter = dir_values(&subdir);
let entry_iter = bindings::dir_values(&subdir);
let mut vec = Vec::new();
loop {
let entry = to_future::<js_sys::IteratorNext>(entry_iter.next().unwrap())
Expand Down
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down
8 changes: 1 addition & 7 deletions src/web/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@
//
// You should have received a copy of the GNU General Public License
// along with Luminol. If not, see <http://www.gnu.org/licenses/>.
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;
}
38 changes: 13 additions & 25 deletions src/web/web_worker_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,11 @@
//
// You should have received a copy of the GNU General Public License
// along with Luminol. If not, see <http://www.gnu.org/licenses/>.
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<web_sys::Performance>;
}

#[derive(Debug, Default)]
struct Storage {}

Expand Down Expand Up @@ -85,12 +71,11 @@ impl WebWorkerRunner {
screen_resize_rx: Option<mpsc::UnboundedReceiver<(u32, u32)>>,
event_rx: Option<mpsc::UnboundedReceiver<egui::Event>>,
) -> 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,
Expand Down Expand Up @@ -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();
});
}

Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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(
Expand All @@ -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,
),
Expand Down Expand Up @@ -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();
}
}
Expand Down

0 comments on commit 6091710

Please sign in to comment.