Skip to content

Commit

Permalink
refactor(core): scope JS resources to the webview (#9272)
Browse files Browse the repository at this point in the history
* refactor(core): scope JS resources to the webview

* clippy

* change files

* swap args order

* more clippy

* just add them on each type

* clippy

* macro docs

* Update mod.rs

* use random rid

* revert resource table arg change

---------

Co-authored-by: Lucas Nogueira <lucas@tauri.app>
  • Loading branch information
amrbashir and lucasfernog committed Apr 2, 2024
1 parent 8276ab7 commit 284eca9
Show file tree
Hide file tree
Showing 17 changed files with 357 additions and 295 deletions.
5 changes: 5 additions & 0 deletions .changes/resources_table_access.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'tauri': 'patch:breaking'
---

`Manager::resources_table` is now scoped so each `App/AppHandle/Window/Webview/WebviewWindow` has its own resource collection.
12 changes: 6 additions & 6 deletions core/tauri-macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,19 @@ pub fn default_runtime(attributes: TokenStream, input: TokenStream) -> TokenStre
/// Accepts a closure-like syntax to call arbitrary code on a menu item
/// after matching against `kind` and retrieving it from `resources_table` using `rid`.
///
/// You can optionally pass a third parameter to select which item kinds
/// You can optionally pass a 5th parameter to select which item kinds
/// to match against, by providing a `|` separated list of item kinds
/// ```ignore
/// do_menu_item!(|i| i.set_text(text), Check | Submenu);
/// do_menu_item!(resources_table, rid, kind, |i| i.set_text(text), Check | Submenu);
/// ```
/// You could also provide a negated list
/// ```ignore
/// do_menu_item!(|i| i.set_text(text), !Check);
/// do_menu_item!(|i| i.set_text(text), !Check | !Submenu);
/// do_menu_item!(resources_table, rid, kind, |i| i.set_text(text), !Check);
/// do_menu_item!(resources_table, rid, kind, |i| i.set_text(text), !Check | !Submenu);
/// ```
/// but you can't have mixed negations and positive kinds.
/// ```ignore
/// do_menu_item!(|i| i.set_text(text), !Check | Submeun);
/// do_menu_item!(resources_table, rid, kind, |i| i.set_text(text), !Check | Submeun);
/// ```
///
/// #### Example
Expand All @@ -115,7 +115,7 @@ pub fn default_runtime(attributes: TokenStream, input: TokenStream) -> TokenStre
/// let rid = 23;
/// let kind = ItemKind::Check;
/// let resources_table = app.resources_table();
/// do_menu_item!(|i| i.set_text(text))
/// do_menu_item!(resources_table, rid, kind, |i| i.set_text(text))
/// ```
/// which will expand into:
/// ```ignore
Expand Down
48 changes: 33 additions & 15 deletions core/tauri-macros/src/menu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,32 @@ pub struct DoMenuItemInput {
}

#[derive(Clone)]
struct NegatedIdent(bool, Ident);
struct NegatedIdent {
negated: bool,
ident: Ident,
}

impl NegatedIdent {
fn new(ident: &str) -> Self {
Self {
negated: false,
ident: Ident::new(ident, Span::call_site()),
}
}

fn is_negated(&self) -> bool {
self.negated
}
}

impl Parse for NegatedIdent {
fn parse(input: ParseStream) -> syn::Result<Self> {
let t = input.parse::<Token![!]>();
let i: Ident = input.parse()?;
Ok(NegatedIdent(t.is_ok(), i))
let negated_token = input.parse::<Token![!]>();
let ident: Ident = input.parse()?;
Ok(NegatedIdent {
negated: negated_token.is_ok(),
ident,
})
}
}

Expand Down Expand Up @@ -67,32 +86,31 @@ pub fn do_menu_item(input: DoMenuItemInput) -> TokenStream {
} = input;

let defaults = vec![
NegatedIdent(false, Ident::new("Submenu", Span::call_site())),
NegatedIdent(false, Ident::new("MenuItem", Span::call_site())),
NegatedIdent(false, Ident::new("Predefined", Span::call_site())),
NegatedIdent(false, Ident::new("Check", Span::call_site())),
NegatedIdent(false, Ident::new("Icon", Span::call_site())),
NegatedIdent::new("Submenu"),
NegatedIdent::new("MenuItem"),
NegatedIdent::new("Predefined"),
NegatedIdent::new("Check"),
NegatedIdent::new("Icon"),
];

if kinds.is_empty() {
kinds.extend(defaults.clone());
}

let has_negated = kinds.iter().any(|n| n.0);

let has_negated = kinds.iter().any(|n| n.is_negated());
if has_negated {
kinds.extend(defaults);
kinds.sort_by(|a, b| a.1.cmp(&b.1));
kinds.dedup_by(|a, b| a.1 == b.1);
kinds.sort_by(|a, b| a.ident.cmp(&b.ident));
kinds.dedup_by(|a, b| a.ident == b.ident);
}

let (kinds, types): (Vec<Ident>, Vec<Ident>) = kinds
.into_iter()
.filter_map(|nident| {
if nident.0 {
if nident.is_negated() {
None
} else {
match nident.1 {
match nident.ident {
i if i == "MenuItem" => Some((i, Ident::new("MenuItem", Span::call_site()))),
i if i == "Submenu" => Some((i, Ident::new("Submenu", Span::call_site()))),
i if i == "Predefined" => Some((i, Ident::new("PredefinedMenuItem", Span::call_site()))),
Expand Down
18 changes: 14 additions & 4 deletions core/tauri/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use crate::{
AppManager, Asset,
},
plugin::{Plugin, PluginStore},
resources::ResourceTable,
runtime::{
window::{WebviewEvent as RuntimeWebviewEvent, WindowEvent as RuntimeWindowEvent},
ExitRequestedEventAction, RunEvent as RuntimeRunEvent,
Expand Down Expand Up @@ -45,7 +46,7 @@ use std::{
borrow::Cow,
collections::HashMap,
fmt,
sync::{mpsc::Sender, Arc},
sync::{mpsc::Sender, Arc, MutexGuard},
};

use crate::{event::EventId, runtime::RuntimeHandle, Event, EventTarget};
Expand Down Expand Up @@ -416,7 +417,12 @@ impl<R: Runtime> AppHandle<R> {
}
}

impl<R: Runtime> Manager<R> for AppHandle<R> {}
impl<R: Runtime> Manager<R> for AppHandle<R> {
fn resources_table(&self) -> MutexGuard<'_, ResourceTable> {
self.manager.resources_table()
}
}

impl<R: Runtime> ManagerBase<R> for AppHandle<R> {
fn manager(&self) -> &AppManager<R> {
&self.manager
Expand Down Expand Up @@ -457,7 +463,12 @@ impl<R: Runtime> fmt::Debug for App<R> {
}
}

impl<R: Runtime> Manager<R> for App<R> {}
impl<R: Runtime> Manager<R> for App<R> {
fn resources_table(&self) -> MutexGuard<'_, ResourceTable> {
self.manager.resources_table()
}
}

impl<R: Runtime> ManagerBase<R> for App<R> {
fn manager(&self) -> &AppManager<R> {
&self.manager
Expand Down Expand Up @@ -743,7 +754,6 @@ macro_rules! shared_app_impl {
pub fn cleanup_before_exit(&self) {
#[cfg(all(desktop, feature = "tray-icon"))]
self.manager.tray.icons.lock().unwrap().clear();
self.resources_table().clear();
}
}

Expand Down
7 changes: 2 additions & 5 deletions core/tauri/src/image/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,9 @@ pub enum JsImage {

impl JsImage {
/// Converts this intermediate image format into an actual [`Image`].
pub fn into_img<R: Runtime, M: Manager<R>>(self, app: &M) -> crate::Result<Arc<Image<'_>>> {
pub fn into_img<R: Runtime, M: Manager<R>>(self, manager: &M) -> crate::Result<Arc<Image<'_>>> {
match self {
Self::Resource(rid) => {
let resources_table = app.resources_table();
resources_table.get::<Image<'static>>(rid)
}
Self::Resource(rid) => manager.resources_table().get::<Image<'static>>(rid),
#[cfg(any(feature = "image-ico", feature = "image-png"))]
Self::Path(path) => Image::from_path(path).map(Arc::new).map_err(Into::into),

Expand Down
26 changes: 15 additions & 11 deletions core/tauri/src/image/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,27 @@
use serde::Serialize;

use crate::plugin::{Builder, TauriPlugin};
use crate::{command, image::Image, AppHandle, Manager, ResourceId, Runtime};
use crate::Manager;
use crate::{command, image::Image, ResourceId, Runtime, Webview};

#[command(root = "crate")]
fn new<R: Runtime>(
app: AppHandle<R>,
webview: Webview<R>,
rgba: Vec<u8>,
width: u32,
height: u32,
) -> crate::Result<ResourceId> {
let image = Image::new_owned(rgba, width, height);
let mut resources_table = app.resources_table();
let mut resources_table = webview.resources_table();
let rid = resources_table.add(image);
Ok(rid)
}

#[cfg(any(feature = "image-ico", feature = "image-png"))]
#[command(root = "crate")]
fn from_bytes<R: Runtime>(app: AppHandle<R>, bytes: Vec<u8>) -> crate::Result<ResourceId> {
fn from_bytes<R: Runtime>(webview: Webview<R>, bytes: Vec<u8>) -> crate::Result<ResourceId> {
let image = Image::from_bytes(&bytes)?.to_owned();
let mut resources_table = app.resources_table();
let mut resources_table = webview.resources_table();
let rid = resources_table.add(image);
Ok(rid)
}
Expand All @@ -37,9 +38,12 @@ fn from_bytes() -> std::result::Result<(), &'static str> {

#[cfg(any(feature = "image-ico", feature = "image-png"))]
#[command(root = "crate")]
fn from_path<R: Runtime>(app: AppHandle<R>, path: std::path::PathBuf) -> crate::Result<ResourceId> {
fn from_path<R: Runtime>(
webview: Webview<R>,
path: std::path::PathBuf,
) -> crate::Result<ResourceId> {
let image = Image::from_path(path)?.to_owned();
let mut resources_table = app.resources_table();
let mut resources_table = webview.resources_table();
let rid = resources_table.add(image);
Ok(rid)
}
Expand All @@ -51,8 +55,8 @@ fn from_path() -> std::result::Result<(), &'static str> {
}

#[command(root = "crate")]
fn rgba<R: Runtime>(app: AppHandle<R>, rid: ResourceId) -> crate::Result<Vec<u8>> {
let resources_table = app.resources_table();
fn rgba<R: Runtime>(webview: Webview<R>, rid: ResourceId) -> crate::Result<Vec<u8>> {
let resources_table = webview.resources_table();
let image = resources_table.get::<Image<'_>>(rid)?;
Ok(image.rgba().to_vec())
}
Expand All @@ -64,8 +68,8 @@ struct Size {
}

#[command(root = "crate")]
fn size<R: Runtime>(app: AppHandle<R>, rid: ResourceId) -> crate::Result<Size> {
let resources_table = app.resources_table();
fn size<R: Runtime>(webview: Webview<R>, rid: ResourceId) -> crate::Result<Size> {
let resources_table = webview.resources_table();
let image = resources_table.get::<Image<'_>>(rid)?;
Ok(Size {
width: image.width(),
Expand Down
6 changes: 2 additions & 4 deletions core/tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -895,10 +895,8 @@ pub trait Manager<R: Runtime>: sealed::ManagerBase<R> {
self.manager().state.try_get()
}

/// Get a reference to the resources table.
fn resources_table(&self) -> MutexGuard<'_, ResourceTable> {
self.manager().resources_table()
}
/// Get a reference to the resources table of this manager.
fn resources_table(&self) -> MutexGuard<'_, ResourceTable>;

/// Gets the managed [`Env`].
fn env(&self) -> Env {
Expand Down
1 change: 0 additions & 1 deletion core/tauri/src/manager/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,6 @@ impl<R: Runtime> AppManager<R> {
self.webview.webviews_lock().clone()
}

/// Resources table managed by the application.
pub(crate) fn resources_table(&self) -> MutexGuard<'_, ResourceTable> {
self
.resources_table
Expand Down
Loading

0 comments on commit 284eca9

Please sign in to comment.