From 1002bc955b5f569eb9e74da90b62b16c45d43bc6 Mon Sep 17 00:00:00 2001 From: Will Crichton Date: Sat, 16 Dec 2023 21:44:39 -0800 Subject: [PATCH] Replace AssetHandlerId with slab and usize --- packages/desktop/src/desktop_context.rs | 11 +++--- packages/desktop/src/lib.rs | 2 +- packages/desktop/src/protocol.rs | 45 +++++++------------------ 3 files changed, 20 insertions(+), 38 deletions(-) diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs index cab3b4589..fb0615900 100644 --- a/packages/desktop/src/desktop_context.rs +++ b/packages/desktop/src/desktop_context.rs @@ -5,7 +5,6 @@ use std::rc::Weak; use crate::create_new_window; use crate::events::IpcMessage; use crate::protocol::AssetFuture; -use crate::protocol::AssetHandlerId; use crate::protocol::AssetHandlerRegistry; use crate::query::QueryEngine; use crate::shortcut::{HotKey, ShortcutId, ShortcutRegistry, ShortcutRegistryError}; @@ -258,13 +257,15 @@ impl DesktopService { /// Provide a callback to handle asset loading yourself. /// /// See [`use_asset_handle`](crate::use_asset_handle) for a convenient hook. - pub async fn register_asset_handler(&self, f: impl AssetHandler) { - self.asset_handlers.register_handler(f).await; + pub async fn register_asset_handler(&self, f: impl AssetHandler) -> usize { + self.asset_handlers.register_handler(f).await } /// Removes an asset handler by its identifier. - pub async fn remove_asset_handler(&self, id: AssetHandlerId) { - self.asset_handlers.remove_handler(id).await; + /// + /// Returns `None` if the handler did not exist. + pub async fn remove_asset_handler(&self, id: usize) -> Option<()> { + self.asset_handlers.remove_handler(id).await } /// Push an objc view to the window diff --git a/packages/desktop/src/lib.rs b/packages/desktop/src/lib.rs index f8155c333..515c26009 100644 --- a/packages/desktop/src/lib.rs +++ b/packages/desktop/src/lib.rs @@ -32,7 +32,7 @@ use dioxus_html::{native_bind::NativeFileEngine, FormData, HtmlEvent}; use element::DesktopElement; use eval::init_eval; use futures_util::{pin_mut, FutureExt}; -pub use protocol::{use_asset_handler, AssetFuture, AssetHandler, AssetHandlerId, AssetResponse}; +pub use protocol::{use_asset_handler, AssetFuture, AssetHandler, AssetResponse}; use shortcut::ShortcutRegistry; pub use shortcut::{use_global_shortcut, ShortcutHandle, ShortcutId, ShortcutRegistryError}; use std::cell::Cell; diff --git a/packages/desktop/src/protocol.rs b/packages/desktop/src/protocol.rs index 774c0900a..cb21245f8 100644 --- a/packages/desktop/src/protocol.rs +++ b/packages/desktop/src/protocol.rs @@ -1,5 +1,6 @@ use dioxus_core::ScopeState; use dioxus_interpreter_js::{COMMON_JS, INTERPRETER_JS}; +use slab::Slab; use std::{ borrow::Cow, collections::HashMap, @@ -76,50 +77,30 @@ impl> + Send + Sync + 'static> AssetFut pub trait AssetHandler: Fn(&Path) -> F + Send + Sync + 'static {} impl F + Send + Sync + 'static> AssetHandler for T {} -/// An identifier for a registered asset handler, returned by [`AssetHandlerRegistry::register_handler`]. -#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] -pub struct AssetHandlerId(usize); - -struct AssetHandlerRegistryInner { - handlers: HashMap< - AssetHandlerId, - Box Pin> + Send + Sync + 'static>, - >, - counter: AssetHandlerId, -} +type AssetHandlerRegistryInner = + Slab Pin> + Send + Sync + 'static>>; #[derive(Clone)] pub struct AssetHandlerRegistry(Arc>); impl AssetHandlerRegistry { pub fn new() -> Self { - AssetHandlerRegistry(Arc::new(RwLock::new(AssetHandlerRegistryInner { - handlers: HashMap::new(), - counter: AssetHandlerId(0), - }))) + AssetHandlerRegistry(Arc::new(RwLock::new(Slab::new()))) } - pub async fn register_handler( - &self, - f: impl AssetHandler, - ) -> AssetHandlerId { + pub async fn register_handler(&self, f: impl AssetHandler) -> usize { let mut registry = self.0.write().await; - let id = registry.counter; - registry - .handlers - .insert(id, Box::new(move |path| Box::pin(f(path)))); - registry.counter.0 += 1; - id + registry.insert(Box::new(move |path| Box::pin(f(path)))) } - pub async fn remove_handler(&self, id: AssetHandlerId) -> Option<()> { + pub async fn remove_handler(&self, id: usize) -> Option<()> { let mut registry = self.0.write().await; - registry.handlers.remove(&id).map(|_| ()) + registry.try_remove(id).map(|_| ()) } pub async fn try_handlers(&self, path: &Path) -> Option { let registry = self.0.read().await; - for handler in registry.handlers.values() { + for (_, handler) in registry.iter() { if let Some(response) = handler(path).await { return Some(response); } @@ -131,15 +112,15 @@ impl AssetHandlerRegistry { /// A handle to a registered asset handler. pub struct AssetHandlerHandle { desktop: DesktopContext, - handler_id: Rc>, + handler_id: Rc>, } impl AssetHandlerHandle { - /// Returns the [`AssetHandlerId`] for this handle. + /// Returns the ID for this handle. /// /// Because registering an ID is asynchronous, this may return `None` if the /// registration has not completed yet. - pub fn handler_id(&self) -> Option { + pub fn handler_id(&self) -> Option { self.handler_id.get().copied() } } @@ -166,7 +147,7 @@ pub fn use_asset_handler( cx: &ScopeState, handler: impl AssetHandler, ) -> &AssetHandlerHandle { - let desktop = Rc::clone(&use_window(cx)); + let desktop = Rc::clone(use_window(cx)); cx.use_hook(|| { let handler_id = Rc::new(OnceCell::new()); let handler_id_ref = Rc::clone(&handler_id);