Replace AssetHandlerId with slab and usize

This commit is contained in:
Will Crichton committed 2023-12-16 21:44:39 -08:00
1 parent 7bede0be59
commit 1002bc955b
3 files changed
+20 -38

No files matched your search

+6 -5
View File
@@ -5,7 +5,6 @@ use std::rc::Weak;
use crate::create_new_window; use crate::create_new_window;
use crate::events::IpcMessage; use crate::events::IpcMessage;
use crate::protocol::AssetFuture; use crate::protocol::AssetFuture;
use crate::protocol::AssetHandlerId;
use crate::protocol::AssetHandlerRegistry; use crate::protocol::AssetHandlerRegistry;
use crate::query::QueryEngine; use crate::query::QueryEngine;
use crate::shortcut::{HotKey, ShortcutId, ShortcutRegistry, ShortcutRegistryError}; use crate::shortcut::{HotKey, ShortcutId, ShortcutRegistry, ShortcutRegistryError};
@@ -258,13 +257,15 @@ impl DesktopService {
/// Provide a callback to handle asset loading yourself. /// Provide a callback to handle asset loading yourself.
/// ///
/// See [`use_asset_handle`](crate::use_asset_handle) for a convenient hook. /// See [`use_asset_handle`](crate::use_asset_handle) for a convenient hook.
pub async fn register_asset_handler<F: AssetFuture>(&self, f: impl AssetHandler<F>) { pub async fn register_asset_handler<F: AssetFuture>(&self, f: impl AssetHandler<F>) -> usize {
self.asset_handlers.register_handler(f).await; self.asset_handlers.register_handler(f).await
} }
/// Removes an asset handler by its identifier. /// 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 /// Push an objc view to the window
+1 -1
View File
@@ -32,7 +32,7 @@ use dioxus_html::{native_bind::NativeFileEngine, FormData, HtmlEvent};
use element::DesktopElement; use element::DesktopElement;
use eval::init_eval; use eval::init_eval;
use futures_util::{pin_mut, FutureExt}; 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; use shortcut::ShortcutRegistry;
pub use shortcut::{use_global_shortcut, ShortcutHandle, ShortcutId, ShortcutRegistryError}; pub use shortcut::{use_global_shortcut, ShortcutHandle, ShortcutId, ShortcutRegistryError};
use std::cell::Cell; use std::cell::Cell;
+13 -32
View File
@@ -1,5 +1,6 @@
use dioxus_core::ScopeState; use dioxus_core::ScopeState;
use dioxus_interpreter_js::{COMMON_JS, INTERPRETER_JS}; use dioxus_interpreter_js::{COMMON_JS, INTERPRETER_JS};
use slab::Slab;
use std::{ use std::{
borrow::Cow, borrow::Cow,
collections::HashMap, collections::HashMap,
@@ -76,50 +77,30 @@ impl<T: Future<Output = Option<AssetResponse>> + Send + Sync + 'static> AssetFut
pub trait AssetHandler<F: AssetFuture>: Fn(&Path) -> F + Send + Sync + 'static {} pub trait AssetHandler<F: AssetFuture>: Fn(&Path) -> F + Send + Sync + 'static {}
impl<F: AssetFuture, T: Fn(&Path) -> F + Send + Sync + 'static> AssetHandler<F> for T {} impl<F: AssetFuture, T: Fn(&Path) -> F + Send + Sync + 'static> AssetHandler<F> for T {}
/// An identifier for a registered asset handler, returned by [`AssetHandlerRegistry::register_handler`]. type AssetHandlerRegistryInner =
#[derive(PartialEq, Eq, Hash, Clone, Copy, Debug)] Slab<Box<dyn Fn(&Path) -> Pin<Box<dyn AssetFuture>> + Send + Sync + 'static>>;
pub struct AssetHandlerId(usize);
struct AssetHandlerRegistryInner {
handlers: HashMap<
AssetHandlerId,
Box<dyn Fn(&Path) -> Pin<Box<dyn AssetFuture>> + Send + Sync + 'static>,
>,
counter: AssetHandlerId,
}
#[derive(Clone)] #[derive(Clone)]
pub struct AssetHandlerRegistry(Arc<RwLock<AssetHandlerRegistryInner>>); pub struct AssetHandlerRegistry(Arc<RwLock<AssetHandlerRegistryInner>>);
impl AssetHandlerRegistry { impl AssetHandlerRegistry {
pub fn new() -> Self { pub fn new() -> Self {
AssetHandlerRegistry(Arc::new(RwLock::new(AssetHandlerRegistryInner { AssetHandlerRegistry(Arc::new(RwLock::new(Slab::new())))
handlers: HashMap::new(),
counter: AssetHandlerId(0),
})))
} }
pub async fn register_handler<F: AssetFuture>( pub async fn register_handler<F: AssetFuture>(&self, f: impl AssetHandler<F>) -> usize {
&self,
f: impl AssetHandler<F>,
) -> AssetHandlerId {
let mut registry = self.0.write().await; let mut registry = self.0.write().await;
let id = registry.counter; registry.insert(Box::new(move |path| Box::pin(f(path))))
registry
.handlers
.insert(id, Box::new(move |path| Box::pin(f(path))));
registry.counter.0 += 1;
id
} }
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; 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<AssetResponse> { pub async fn try_handlers(&self, path: &Path) -> Option<AssetResponse> {
let registry = self.0.read().await; let registry = self.0.read().await;
for handler in registry.handlers.values() { for (_, handler) in registry.iter() {
if let Some(response) = handler(path).await { if let Some(response) = handler(path).await {
return Some(response); return Some(response);
} }
@@ -131,15 +112,15 @@ impl AssetHandlerRegistry {
/// A handle to a registered asset handler. /// A handle to a registered asset handler.
pub struct AssetHandlerHandle { pub struct AssetHandlerHandle {
desktop: DesktopContext, desktop: DesktopContext,
handler_id: Rc<OnceCell<AssetHandlerId>>, handler_id: Rc<OnceCell<usize>>,
} }
impl AssetHandlerHandle { 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 /// Because registering an ID is asynchronous, this may return `None` if the
/// registration has not completed yet. /// registration has not completed yet.
pub fn handler_id(&self) -> Option<AssetHandlerId> { pub fn handler_id(&self) -> Option<usize> {
self.handler_id.get().copied() self.handler_id.get().copied()
} }
} }
@@ -166,7 +147,7 @@ pub fn use_asset_handler<F: AssetFuture>(
cx: &ScopeState, cx: &ScopeState,
handler: impl AssetHandler<F>, handler: impl AssetHandler<F>,
) -> &AssetHandlerHandle { ) -> &AssetHandlerHandle {
let desktop = Rc::clone(&use_window(cx)); let desktop = Rc::clone(use_window(cx));
cx.use_hook(|| { cx.use_hook(|| {
let handler_id = Rc::new(OnceCell::new()); let handler_id = Rc::new(OnceCell::new());
let handler_id_ref = Rc::clone(&handler_id); let handler_id_ref = Rc::clone(&handler_id);