Replace AssetHandlerId with slab and usize
This commit is contained in:
1 parent
7bede0be59
commit
1002bc955b
3 files changed
+20
-38
No files matched your search
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in new issue
Block a user