Simplify asset code a bit

This commit is contained in:
Jonathan Kelley 2024-01-04 18:01:13 -08:00
parent fef7b83b79
commit 7444796a85
No known key found for this signature in database
GPG key ID: 1FBB50F7EB0A08BE
8 changed files with 84 additions and 96 deletions

View file

@ -11,7 +11,7 @@ use crate::hooks::*;
use crate::query::QueryResult;
use crate::shortcut::GlobalHotKeyEvent;
use crate::shortcut::ShortcutRegistry;
pub use crate::shortcut::{use_global_shortcut, ShortcutHandle, ShortcutId, ShortcutRegistryError};
pub use crate::shortcut::{ShortcutHandle, ShortcutId, ShortcutRegistryError};
use crate::{
desktop_context::{EventData, UserWindowEvent, WindowEventHandlers},
webview::WebviewHandler,
@ -171,9 +171,9 @@ impl<P: 'static> App<P> {
let handler = crate::webview::create_new_window(
cfg,
dom,
target,
&self.proxy,
dom,
&self.queue,
&self.event_handlers,
self.shortcut_manager.clone(),
@ -212,10 +212,6 @@ impl<P: 'static> App<P> {
}
}
pub fn handle_poll_msg(&mut self, id: WindowId) {
self.poll_vdom(id);
}
pub fn handle_query_msg(&mut self, msg: IpcMessage, id: WindowId) {
let Ok(result) = serde_json::from_value::<QueryResult>(msg.params()) else {
return;

View file

@ -75,8 +75,10 @@ impl<F: AssetFuture, T: Fn(&AssetRequest) -> F + Send + Sync + 'static> AssetHan
}
}
type AssetHandlerRegistryInner =
Slab<Box<dyn Fn(&AssetRequest) -> Pin<Box<dyn AssetFuture>> + Send + Sync + 'static>>;
type UserAssetHandler =
Box<dyn Fn(&AssetRequest) -> Pin<Box<dyn AssetFuture>> + Send + Sync + 'static>;
type AssetHandlerRegistryInner = Slab<UserAssetHandler>;
#[derive(Clone)]
pub struct AssetHandlerRegistry(Arc<RwLock<AssetHandlerRegistryInner>>);

View file

@ -1,26 +1,22 @@
use crate::events::IpcMessage;
use crate::query::QueryEngine;
use crate::shortcut::{HotKey, ShortcutId, ShortcutRegistry, ShortcutRegistryError};
use crate::AssetHandler;
use crate::Config;
use crate::{assets::AssetFuture, edits::WebviewQueue};
use crate::{assets::AssetHandlerRegistry, edits::EditQueue};
use crate::{events::IpcMessage, webview::WebviewHandler};
use dioxus_core::Mutations;
use dioxus_core::VirtualDom;
use dioxus_core::{Mutations, ScopeState};
use dioxus_interpreter_js::binary_protocol::Channel;
use rustc_hash::FxHashMap;
use slab::Slab;
use std::{
cell::RefCell, fmt::Debug, fmt::Formatter, rc::Rc, rc::Weak, sync::atomic::AtomicU16,
sync::Arc, sync::Mutex,
};
use std::{cell::RefCell, fmt::Debug, rc::Rc, rc::Weak, sync::atomic::AtomicU16};
use tao::{
event::Event,
event_loop::{EventLoopProxy, EventLoopWindowTarget},
window::{Fullscreen as WryFullscreen, Window, WindowId},
};
use wry::{RequestAsyncResponder, WebView};
use wry::WebView;
#[cfg(target_os = "ios")]
use tao::platform::ios::WindowExtIOS;
@ -123,16 +119,13 @@ impl DesktopService {
/// Send a list of mutations to the webview
pub(crate) fn send_edits(&self, edits: Mutations) {
let mut channel = self.channel.borrow_mut();
let mut templates = self.templates.borrow_mut();
if let Some(bytes) = crate::edits::apply_edits(
crate::edits::apply_edits(
edits,
&mut channel,
&mut templates,
&mut self.channel.borrow_mut(),
&mut self.templates.borrow_mut(),
&self.max_template_count,
) {
self.edit_queue.add_edits(bytes)
}
)
.map(|bytes| self.edit_queue.add_edits(bytes));
}
/// Create a new window using the props and window builder
@ -145,9 +138,9 @@ impl DesktopService {
pub fn new_window(&self, dom: VirtualDom, cfg: Config) -> Weak<DesktopService> {
let window = crate::webview::create_new_window(
cfg,
dom,
&self.event_loop,
&self.proxy,
dom,
&self.pending_windows,
&self.event_handlers,
self.shortcut_manager.clone(),

View file

@ -1,12 +1,6 @@
use crate::query::QueryEngine;
use crate::shortcut::{HotKey, ShortcutId, ShortcutRegistry, ShortcutRegistryError};
use crate::AssetHandler;
use crate::Config;
use crate::{assets::AssetFuture, DesktopContext};
use crate::{assets::AssetHandlerRegistry, DesktopService};
use crate::{events::IpcMessage, webview::WebviewHandler};
use dioxus_core::{BorrowedAttributeValue, Template, TemplateAttribute, TemplateNode, VirtualDom};
use dioxus_core::{Mutations, ScopeState};
use crate::webview::WebviewHandler;
use dioxus_core::Mutations;
use dioxus_core::{BorrowedAttributeValue, Template, TemplateAttribute, TemplateNode};
use dioxus_html::event_bubbles;
use dioxus_interpreter_js::binary_protocol::Channel;
use rustc_hash::FxHashMap;
@ -18,12 +12,16 @@ use std::{
sync::{atomic::Ordering, Mutex},
};
use wry::{RequestAsyncResponder, WebView};
use wry::RequestAsyncResponder;
pub(crate) type WebviewQueue = Rc<RefCell<Vec<WebviewHandler>>>;
/// This handles communication between the requests that the webview makes and the interpreter. The interpreter constantly makes long running requests to the webview to get any edits that should be made to the DOM almost like server side events.
/// It will hold onto the requests until the interpreter is ready to handle them and hold onto any pending edits until a new request is made.
/// This handles communication between the requests that the webview makes and the interpreter. The interpreter
/// constantly makes long running requests to the webview to get any edits that should be made to the DOM almost like
/// server side events.
///
/// It will hold onto the requests until the interpreter is ready to handle them and hold onto any pending edits until
/// a new request is made.
#[derive(Default, Clone)]
pub(crate) struct EditQueue {
queue: Arc<Mutex<Vec<Vec<u8>>>>,

View file

@ -1,6 +1,6 @@
use std::rc::Rc;
use crate::assets::*;
use crate::{assets::*, shortcut::IntoAccelerator, ShortcutHandle, ShortcutRegistryError};
use crate::{desktop_context::UserWindowEvent, window, DesktopContext, WryEventHandler};
use dioxus_core::ScopeState;
use tao::{event::Event, event_loop::EventLoopWindowTarget};
@ -52,3 +52,21 @@ pub fn use_asset_handler<F: AssetFuture>(
}
})
}
/// Get a closure that executes any JavaScript in the WebView context.
pub fn use_global_shortcut(
cx: &ScopeState,
accelerator: impl IntoAccelerator,
handler: impl FnMut() + 'static,
) -> &Result<ShortcutHandle, ShortcutRegistryError> {
cx.use_hook(move || {
let desktop = window();
let id = desktop.create_shortcut(accelerator.accelerator(), handler);
Ok(ShortcutHandle {
desktop,
shortcut_id: id?,
})
})
}

View file

@ -37,9 +37,9 @@ pub use cfg::{Config, WindowCloseBehaviour};
pub use desktop_context::{
window, DesktopContext, DesktopService, WryEventHandler, WryEventHandlerId,
};
pub use hooks::{use_asset_handler, use_window, use_wry_event_handler};
pub use hooks::{use_asset_handler, use_global_shortcut, use_window, use_wry_event_handler};
pub use menubar::build_default_menu_bar;
pub use shortcut::{use_global_shortcut, ShortcutHandle, ShortcutId, ShortcutRegistryError};
pub use shortcut::{ShortcutHandle, ShortcutId, ShortcutRegistryError};
#[allow(deprecated)]
use desktop_context::{EventData, UserWindowEvent};
@ -139,7 +139,7 @@ pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config)
_ => {}
},
Event::UserEvent(UserWindowEvent(event, id)) => match event {
EventData::Poll => app.handle_poll_msg(id),
EventData::Poll => app.poll_vdom(id),
EventData::NewWindow => app.handle_new_window(),
EventData::CloseWindow => app.handle_close_msg(id),
EventData::HotReloadEvent(msg) => app.handle_hot_reload_msg(msg),

View file

@ -1,11 +1,10 @@
use std::{cell::RefCell, collections::HashMap, rc::Rc, str::FromStr};
use dioxus_core::ScopeState;
use dioxus_html::input_data::keyboard_types::Modifiers;
use slab::Slab;
use tao::keyboard::ModifiersState;
use crate::{desktop_context::DesktopContext, window};
use crate::desktop_context::DesktopContext;
#[cfg(any(
target_os = "windows",
@ -26,7 +25,7 @@ pub use crate::mobile_shortcut::*;
#[derive(Clone)]
pub(crate) struct ShortcutRegistry {
manager: Rc<RefCell<GlobalHotKeyManager>>,
manager: Rc<GlobalHotKeyManager>,
shortcuts: ShortcutMap,
}
@ -55,7 +54,7 @@ impl Shortcut {
impl ShortcutRegistry {
pub fn new() -> Self {
Self {
manager: Rc::new(RefCell::new(GlobalHotKeyManager::new().unwrap())),
manager: Rc::new(GlobalHotKeyManager::new().unwrap()),
shortcuts: Rc::new(RefCell::new(HashMap::new())),
}
}
@ -74,36 +73,36 @@ impl ShortcutRegistry {
callback: Box<dyn FnMut()>,
) -> Result<ShortcutId, ShortcutRegistryError> {
let accelerator_id = hotkey.clone().id();
let mut shortcuts = self.shortcuts.borrow_mut();
Ok(
if let Some(callbacks) = shortcuts.get_mut(&accelerator_id) {
let id = callbacks.insert(callback);
ShortcutId {
id: accelerator_id,
number: id,
}
} else {
match self.manager.borrow_mut().register(hotkey) {
Ok(_) => {
let mut slab = Slab::new();
let id = slab.insert(callback);
let shortcut = Shortcut {
shortcut: hotkey,
callbacks: slab,
};
shortcuts.insert(accelerator_id, shortcut);
ShortcutId {
id: accelerator_id,
number: id,
}
}
Err(HotkeyError::HotKeyParseError(shortcut)) => {
return Err(ShortcutRegistryError::InvalidShortcut(shortcut))
}
Err(err) => return Err(ShortcutRegistryError::Other(Box::new(err))),
}
},
)
if let Some(callbacks) = shortcuts.get_mut(&accelerator_id) {
return Ok(ShortcutId {
id: accelerator_id,
number: callbacks.insert(callback),
});
};
self.manager.register(hotkey).map_err(|e| match e {
HotkeyError::HotKeyParseError(shortcut) => {
ShortcutRegistryError::InvalidShortcut(shortcut)
}
err => ShortcutRegistryError::Other(Box::new(err)),
})?;
let mut shortcut = Shortcut {
shortcut: hotkey,
callbacks: Slab::new(),
};
let id = shortcut.callbacks.insert(callback);
shortcuts.insert(accelerator_id, shortcut);
Ok(ShortcutId {
id: accelerator_id,
number: id,
})
}
pub(crate) fn remove_shortcut(&self, id: ShortcutId) {
@ -112,7 +111,7 @@ impl ShortcutRegistry {
callbacks.remove(id.number);
if callbacks.is_empty() {
if let Some(_shortcut) = shortcuts.remove(&id.id) {
let _ = self.manager.borrow_mut().unregister(_shortcut.shortcut);
let _ = self.manager.unregister(_shortcut.shortcut);
}
}
}
@ -121,7 +120,7 @@ impl ShortcutRegistry {
pub(crate) fn remove_all(&self) {
let mut shortcuts = self.shortcuts.borrow_mut();
let hotkeys: Vec<_> = shortcuts.drain().map(|(_, v)| v.shortcut).collect();
let _ = self.manager.borrow_mut().unregister_all(&hotkeys);
let _ = self.manager.unregister_all(&hotkeys);
}
}
@ -144,7 +143,7 @@ pub struct ShortcutId {
/// A global shortcut. This will be automatically removed when it is dropped.
pub struct ShortcutHandle {
desktop: DesktopContext,
pub(crate) desktop: DesktopContext,
/// The id of the shortcut
pub shortcut_id: ShortcutId,
}
@ -177,24 +176,6 @@ impl IntoAccelerator for &str {
}
}
/// Get a closure that executes any JavaScript in the WebView context.
pub fn use_global_shortcut(
cx: &ScopeState,
accelerator: impl IntoAccelerator,
handler: impl FnMut() + 'static,
) -> &Result<ShortcutHandle, ShortcutRegistryError> {
cx.use_hook(move || {
let desktop = window();
let id = desktop.create_shortcut(accelerator.accelerator(), handler);
Ok(ShortcutHandle {
desktop,
shortcut_id: id?,
})
})
}
impl ShortcutHandle {
/// Remove the shortcut.
pub fn remove(&self) {

View file

@ -30,9 +30,9 @@ pub struct WebviewHandler {
pub fn create_new_window(
mut cfg: Config,
dom: VirtualDom,
event_loop: &EventLoopWindowTarget<UserWindowEvent>,
proxy: &EventLoopProxy<UserWindowEvent>,
dom: VirtualDom,
queue: &WebviewQueue,
event_handlers: &WindowEventHandlers,
shortcut_manager: ShortcutRegistry,