diff --git a/packages/core-macro/src/lib.rs b/packages/core-macro/src/lib.rs index 4e4f5600a..501c38e7b 100644 --- a/packages/core-macro/src/lib.rs +++ b/packages/core-macro/src/lib.rs @@ -1,5 +1,6 @@ use proc_macro::TokenStream; use quote::ToTokens; +use rsx::RenderCallBody; use syn::parse_macro_input; mod inlineprops; @@ -41,10 +42,7 @@ pub fn rsx(s: TokenStream) -> TokenStream { pub fn render(s: TokenStream) -> TokenStream { match syn::parse::(s) { Err(err) => err.to_compile_error().into(), - Ok(mut body) => { - body.inline_cx = true; - body.into_token_stream().into() - } + Ok(body) => RenderCallBody(body).into_token_stream().into(), } } diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs index 6b6d02ba3..943fbf91e 100644 --- a/packages/desktop/src/desktop_context.rs +++ b/packages/desktop/src/desktop_context.rs @@ -7,6 +7,7 @@ use serde_json::Value; use std::future::Future; use std::future::IntoFuture; use std::pin::Pin; +use wry::application::dpi::LogicalSize; use wry::application::event_loop::ControlFlow; use wry::application::event_loop::EventLoopProxy; #[cfg(target_os = "ios")] @@ -136,6 +137,11 @@ impl DesktopContext { let _ = self.proxy.send_event(SetZoomLevel(scale_factor)); } + /// modifies the inner size of the window + pub fn set_inner_size(&self, logical_size: LogicalSize) { + let _ = self.proxy.send_event(SetInnerSize(logical_size)); + } + /// launch print modal pub fn print(&self) { let _ = self.proxy.send_event(Print); @@ -188,6 +194,7 @@ pub enum UserWindowEvent { SetDecorations(bool), SetZoomLevel(f64), + SetInnerSize(LogicalSize), Print, DevTool, @@ -259,6 +266,7 @@ impl DesktopController { SetDecorations(state) => window.set_decorations(state), SetZoomLevel(scale_factor) => webview.zoom(scale_factor), + SetInnerSize(logical_size) => window.set_inner_size(logical_size), Print => { if let Err(e) = webview.print() { diff --git a/packages/rsx/src/component.rs b/packages/rsx/src/component.rs index 4100aac39..0439108e2 100644 --- a/packages/rsx/src/component.rs +++ b/packages/rsx/src/component.rs @@ -11,8 +11,6 @@ //! - [ ] Keys //! - [ ] Properties spreading with with `..` syntax -use std::marker::PhantomData; - use super::*; use proc_macro2::TokenStream as TokenStream2; @@ -169,7 +167,6 @@ impl ToTokens for Component { if !self.children.is_empty() { let renderer: TemplateRenderer = TemplateRenderer { roots: &self.children, - phantom: PhantomData, }; toks.append_all(quote! { diff --git a/packages/rsx/src/hot_reload/hot_reloading_file_map.rs b/packages/rsx/src/hot_reload/hot_reloading_file_map.rs index f978f0869..be4f5d828 100644 --- a/packages/rsx/src/hot_reload/hot_reloading_file_map.rs +++ b/packages/rsx/src/hot_reload/hot_reloading_file_map.rs @@ -69,8 +69,8 @@ impl FileMap { let old_start = old.span().start(); if let (Ok(old_call_body), Ok(new_call_body)) = ( - syn::parse2::>(old.tokens), - syn::parse2::>(new), + syn::parse2::(old.tokens), + syn::parse2::(new), ) { if let Ok(file) = file_path.strip_prefix(crate_dir) { let line = old_start.line; @@ -83,10 +83,12 @@ impl FileMap { // the byte index doesn't matter, but dioxus needs it + ":0"; - if let Some(template) = new_call_body.update_template( - Some(old_call_body), - Box::leak(location.into_boxed_str()), - ) { + if let Some(template) = new_call_body + .update_template::( + Some(old_call_body), + Box::leak(location.into_boxed_str()), + ) + { // dioxus cannot handle empty templates if template.roots.is_empty() { return UpdateResult::NeedsRebuild; diff --git a/packages/rsx/src/lib.rs b/packages/rsx/src/lib.rs index a30225a00..d22b122e9 100644 --- a/packages/rsx/src/lib.rs +++ b/packages/rsx/src/lib.rs @@ -25,7 +25,6 @@ use std::{collections::HashMap, fmt::Debug, hash::Hash}; pub use component::*; use dioxus_core::{Template, TemplateAttribute, TemplateNode}; pub use element::*; -use hot_reload::Empty; pub use hot_reload::HotReloadingContext; pub use ifmt::*; use internment::Intern; @@ -46,34 +45,26 @@ fn intern(s: impl Into> /// Fundametnally, every CallBody is a template #[derive(Default, Debug)] -pub struct CallBody { +pub struct CallBody { pub roots: Vec, - - // set this after - pub inline_cx: bool, - - phantom: std::marker::PhantomData, } -impl CallBody { +impl CallBody { /// This will try to create a new template from the current body and the previous body. This will return None if the rsx has some dynamic part that has changed. /// This function intentionally leaks memory to create a static template. /// Keeping the template static allows us to simplify the core of dioxus and leaking memory in dev mode is less of an issue. /// the previous_location is the location of the previous template at the time the template was originally compiled. - pub fn update_template( + pub fn update_template( &self, - template: Option>, + template: Option, location: &'static str, ) -> Option> { - let mut renderer: TemplateRenderer = TemplateRenderer { - roots: &self.roots, - phantom: std::marker::PhantomData, - }; - renderer.update_template(template, location) + let mut renderer: TemplateRenderer = TemplateRenderer { roots: &self.roots }; + renderer.update_template::(template, location) } } -impl Parse for CallBody { +impl Parse for CallBody { fn parse(input: ParseStream) -> Result { let mut roots = Vec::new(); @@ -87,58 +78,59 @@ impl Parse for CallBody { roots.push(node); } - Ok(Self { - roots, - inline_cx: false, - phantom: std::marker::PhantomData, - }) + Ok(Self { roots }) } } /// Serialize the same way, regardless of flavor -impl ToTokens for CallBody { +impl ToTokens for CallBody { fn to_tokens(&self, out_tokens: &mut TokenStream2) { - let body: TemplateRenderer = TemplateRenderer { - roots: &self.roots, - phantom: std::marker::PhantomData, - }; + let body = TemplateRenderer { roots: &self.roots }; - if self.inline_cx { - out_tokens.append_all(quote! { - Some({ - let __cx = cx; - #body - }) + out_tokens.append_all(quote! { + ::dioxus::core::LazyNodes::new( move | __cx: &::dioxus::core::ScopeState| -> ::dioxus::core::VNode { + #body }) - } else { - out_tokens.append_all(quote! { - ::dioxus::core::LazyNodes::new( move | __cx: &::dioxus::core::ScopeState| -> ::dioxus::core::VNode { - #body - }) - }) - } + }) } } -pub struct TemplateRenderer<'a, Ctx: HotReloadingContext = Empty> { - pub roots: &'a [BodyNode], - phantom: std::marker::PhantomData, +#[derive(Default, Debug)] +pub struct RenderCallBody(pub CallBody); + +impl ToTokens for RenderCallBody { + fn to_tokens(&self, out_tokens: &mut TokenStream2) { + let body: TemplateRenderer = TemplateRenderer { + roots: &self.0.roots, + }; + + out_tokens.append_all(quote! { + Some({ + let __cx = cx; + #body + }) + }) + } } -impl<'a, Ctx: HotReloadingContext> TemplateRenderer<'a, Ctx> { - fn update_template( +pub struct TemplateRenderer<'a> { + pub roots: &'a [BodyNode], +} + +impl<'a> TemplateRenderer<'a> { + fn update_template( &mut self, - previous_call: Option>, + previous_call: Option, location: &'static str, ) -> Option> { let mut mapping = previous_call.map(|call| DynamicMapping::from(call.roots)); - let mut context: DynamicContext = DynamicContext::default(); + let mut context = DynamicContext::default(); let mut roots = Vec::new(); for (idx, root) in self.roots.iter().enumerate() { context.current_path.push(idx as u8); - roots.push(context.update_node(root, &mut mapping)?); + roots.push(context.update_node::(root, &mut mapping)?); context.current_path.pop(); } @@ -165,9 +157,9 @@ impl<'a, Ctx: HotReloadingContext> TemplateRenderer<'a, Ctx> { } } -impl<'a, Ctx: HotReloadingContext> ToTokens for TemplateRenderer<'a, Ctx> { +impl<'a> ToTokens for TemplateRenderer<'a> { fn to_tokens(&self, out_tokens: &mut TokenStream2) { - let mut context: DynamicContext = DynamicContext::default(); + let mut context = DynamicContext::default(); let key = match self.roots.get(0) { Some(BodyNode::Element(el)) if self.roots.len() == 1 => el.key.clone(), @@ -180,6 +172,12 @@ impl<'a, Ctx: HotReloadingContext> ToTokens for TemplateRenderer<'a, Ctx> { None => quote! { None }, }; + let spndbg = format!("{:?}", self.roots[0].span()); + let root_col = spndbg + .rsplit_once("..") + .and_then(|(_, after)| after.split_once(')').map(|(before, _)| before)) + .unwrap_or_default(); + let root_printer = self.roots.iter().enumerate().map(|(idx, root)| { context.current_path.push(idx as u8); let out = context.render_static_node(root); @@ -187,12 +185,6 @@ impl<'a, Ctx: HotReloadingContext> ToTokens for TemplateRenderer<'a, Ctx> { out }); - let spndbg = format!("{:?}", self.roots[0].span()); - let root_col = spndbg - .rsplit_once("..") - .and_then(|(_, after)| after.split_once(')').map(|(before, _)| before)) - .unwrap_or_default(); - // Render and release the mutable borrow on context let roots = quote! { #( #root_printer ),* }; let node_printer = &context.dynamic_nodes; @@ -220,7 +212,6 @@ impl<'a, Ctx: HotReloadingContext> ToTokens for TemplateRenderer<'a, Ctx> { key: #key_tokens, template: std::cell::Cell::new(TEMPLATE), root_ids: Default::default(), - // root_ids: std::cell::Cell::from_mut( __cx.bump().alloc([None; #num_roots]) as &mut [::dioxus::core::ElementId]).as_slice_of_cells(), dynamic_nodes: __cx.bump().alloc([ #( #node_printer ),* ]), dynamic_attrs: __cx.bump().alloc([ #( #dyn_attr_printer ),* ]), } @@ -318,32 +309,18 @@ impl DynamicMapping { // As we create the dynamic nodes, we want to keep track of them in a linear fashion // We'll use the size of the vecs to determine the index of the dynamic node in the final output -pub struct DynamicContext<'a, Ctx: HotReloadingContext> { +#[derive(Default, Debug)] +pub struct DynamicContext<'a> { dynamic_nodes: Vec<&'a BodyNode>, dynamic_attributes: Vec<&'a ElementAttrNamed>, current_path: Vec, node_paths: Vec>, attr_paths: Vec>, - - phantom: std::marker::PhantomData, } -impl<'a, Ctx: HotReloadingContext> Default for DynamicContext<'a, Ctx> { - fn default() -> Self { - Self { - dynamic_nodes: Vec::new(), - dynamic_attributes: Vec::new(), - current_path: Vec::new(), - node_paths: Vec::new(), - attr_paths: Vec::new(), - phantom: std::marker::PhantomData, - } - } -} - -impl<'a, Ctx: HotReloadingContext> DynamicContext<'a, Ctx> { - fn update_node( +impl<'a> DynamicContext<'a> { + fn update_node( &mut self, root: &'a BodyNode, mapping: &mut Option, @@ -400,7 +377,7 @@ impl<'a, Ctx: HotReloadingContext> DynamicContext<'a, Ctx> { let mut children = Vec::new(); for (idx, root) in el.children.iter().enumerate() { self.current_path.push(idx as u8); - children.push(self.update_node(root, mapping)?); + children.push(self.update_node::(root, mapping)?); self.current_path.pop(); } @@ -577,9 +554,9 @@ fn create_template() { } } - let call_body: CallBody = syn::parse2(input).unwrap(); + let call_body: CallBody = syn::parse2(input).unwrap(); - let template = call_body.update_template(None, "testing").unwrap(); + let template = call_body.update_template::(None, "testing").unwrap(); dbg!(template); @@ -672,9 +649,9 @@ fn diff_template() { } } - let call_body1: CallBody = syn::parse2(input).unwrap(); + let call_body1: CallBody = syn::parse2(input).unwrap(); - let template = call_body1.update_template(None, "testing").unwrap(); + let template = call_body1.update_template::(None, "testing").unwrap(); dbg!(template); // scrambling the attributes should not cause a full rebuild @@ -694,10 +671,10 @@ fn diff_template() { } }; - let call_body2: CallBody = syn::parse2(input).unwrap(); + let call_body2: CallBody = syn::parse2(input).unwrap(); let template = call_body2 - .update_template(Some(call_body1), "testing") + .update_template::(Some(call_body1), "testing") .unwrap(); dbg!(template); diff --git a/packages/rsx/src/node.rs b/packages/rsx/src/node.rs index e31648fb3..9c156f567 100644 --- a/packages/rsx/src/node.rs +++ b/packages/rsx/src/node.rs @@ -1,4 +1,3 @@ -use std::marker::PhantomData; use super::*; @@ -143,10 +142,7 @@ impl ToTokens for BodyNode { pat, expr, body, .. } = exp; - let renderer: TemplateRenderer = TemplateRenderer { - roots: body, - phantom: PhantomData, - }; + let renderer: TemplateRenderer = TemplateRenderer { roots: body }; tokens.append_all(quote! { __cx.make_node(