diff --git a/packages/core/examples/alternative.rs b/packages/core/examples/alternative.rs index 1de1c1e79..3f2fa9790 100644 --- a/packages/core/examples/alternative.rs +++ b/packages/core/examples/alternative.rs @@ -17,7 +17,7 @@ pub static EXAMPLE: FC<()> = |(cx, _)| { }); // let list = (0..10).map(|_f| Some(Box::new(move |_f| todo!()))); - cx.render(Some(Box::new(move |cx| { + cx.render(Some(LazyNodes::new(move |cx| { cx.raw_element( "div", None, diff --git a/packages/core/examples/syntax2.rs b/packages/core/examples/syntax2.rs index 8ae715728..4cbd22ab5 100644 --- a/packages/core/examples/syntax2.rs +++ b/packages/core/examples/syntax2.rs @@ -4,7 +4,7 @@ use std::marker::PhantomData; use dioxus::component::Scope; use dioxus::events::on::MouseEvent; -use dioxus::nodes::{annotate_lazy, IntoVNode, VComponent, VFragment, VText}; +use dioxus::nodes::{IntoVNode, VComponent, VFragment, VText}; use dioxus_core as dioxus; use dioxus_core::prelude::*; use dioxus_core_macro::*; diff --git a/packages/core/examples/vdom_usage.rs b/packages/core/examples/vdom_usage.rs index 07ec5f205..8f5d278b1 100644 --- a/packages/core/examples/vdom_usage.rs +++ b/packages/core/examples/vdom_usage.rs @@ -1,11 +1,11 @@ use std::time::Duration; -use dioxus_core::prelude::*; +use dioxus_core::{lazynodes::LazyNodes, prelude::*}; // #[async_std::main] fn main() { static App: FC<()> = - |(cx, props)| cx.render(Some(Box::new(move |f| f.text(format_args!("hello"))))); + |(cx, props)| cx.render(Some(LazyNodes::new(move |f| f.text(format_args!("hello"))))); let mut dom = VirtualDom::new(App); diff --git a/packages/core/src/context.rs b/packages/core/src/context.rs index b9661b294..8e3389761 100644 --- a/packages/core/src/context.rs +++ b/packages/core/src/context.rs @@ -6,7 +6,7 @@ use bumpalo::Bump; -use crate::innerlude::*; +use crate::{innerlude::*, lazynodes::LazyNodes}; use std::{any::TypeId, ops::Deref, rc::Rc}; /// Components in Dioxus use the "Context" object to interact with their lifecycle. @@ -103,11 +103,12 @@ impl<'src> Context<'src> { ///``` pub fn render( self, - lazy_nodes: Option) -> VNode<'src> + '_>>, + lazy_nodes: Option>, + // lazy_nodes: Option) -> VNode<'src> + '_>>, ) -> Option> { let bump = &self.scope.frames.wip_frame().bump; let factory = NodeFactory { bump }; - lazy_nodes.map(|f| f(factory)) + lazy_nodes.map(|f| f.call(factory)) } /// `submit_task` will submit the future to be polled. diff --git a/packages/core/src/lazynodes.rs b/packages/core/src/lazynodes.rs index 3662d12ff..78d7093c7 100644 --- a/packages/core/src/lazynodes.rs +++ b/packages/core/src/lazynodes.rs @@ -26,29 +26,37 @@ use crate::innerlude::{IntoVNode, NodeFactory, VNode}; /// ```rust /// LazyNodes::new(|f| f.element("div", [], [], [] None)) /// ``` -// pub struct LazyNodes<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> { -// inner: Box, -// _p: PhantomData<&'a ()>, -// // inner: StackNodeStorage<'a>, -// // inner: StackNodeStorage<'a>, -// } -// pub type LazyNodes<'b> = Box FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>; +pub struct LazyNodes<'a, 'b> { + inner: StackNodeStorage<'a, 'b>, +} -// pub fn to_lazy_nodes<'b>( -// f: impl for<'a> FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b, -// ) -> Option> { -// Some(Box::new(f)) -// } +impl<'a, 'b> LazyNodes<'a, 'b> { + pub fn new(f: F) -> Self + where + F: FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b, + { + Self { + inner: StackNodeStorage::Heap(Box::new(f)), + } + } + + pub fn call(self, f: NodeFactory<'a>) -> VNode<'a> { + match self.inner { + StackNodeStorage::Heap(lazy) => lazy(f), + _ => todo!(), + } + } +} type StackHeapSize = [usize; 12]; -enum StackNodeStorage<'a> { +enum StackNodeStorage<'a, 'b> { Stack { next_ofs: usize, buf: StackHeapSize, width: usize, }, - Heap(Box) -> VNode<'a>>), + Heap(Box) -> VNode<'a> + 'b>), } // impl<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> LazyNodes<'a, F> { diff --git a/packages/core/src/lib.rs b/packages/core/src/lib.rs index fc009b285..043e321e2 100644 --- a/packages/core/src/lib.rs +++ b/packages/core/src/lib.rs @@ -19,7 +19,6 @@ pub mod context; pub mod diff; pub mod diff_stack; pub mod events; -// pub mod events2; pub mod heuristics; pub mod hooklist; pub mod hooks; @@ -46,6 +45,7 @@ pub(crate) mod innerlude { pub use crate::heuristics::*; pub(crate) use crate::hooklist::*; pub use crate::hooks::*; + pub use crate::lazynodes::*; pub use crate::mutations::*; pub use crate::nodes::*; pub(crate) use crate::resources::*; @@ -56,7 +56,7 @@ pub(crate) mod innerlude { pub use crate::threadsafe::*; pub use crate::util::*; pub use crate::virtual_dom::*; - // pub type Element<'a> = Option>; + pub type Element<'a> = Option>; pub type FC

= for<'a> fn(Scope<'a, P>) -> Element<'a>; } @@ -71,7 +71,7 @@ pub mod prelude { pub use crate::component::{fc_to_builder, Fragment, Properties, Scope}; pub use crate::context::Context; pub use crate::hooks::*; - pub use crate::innerlude::{DioxusElement, Element, Mutations, NodeFactory, FC}; + pub use crate::innerlude::{DioxusElement, Element, LazyNodes, NodeFactory, FC}; pub use crate::nodes::VNode; pub use crate::VirtualDom; } diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index 894210dac..7e23af372 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -3,9 +3,12 @@ //! VNodes represent lazily-constructed VDom trees that support diffing and event handlers. These VNodes should be *very* //! cheap and *very* fast to construct - building a full tree should be quick. -use crate::innerlude::{ - empty_cell, Context, Element, ElementId, Properties, Scope, ScopeId, ScopeInner, - SuspendedContext, FC, +use crate::{ + innerlude::{ + empty_cell, Context, Element, ElementId, Properties, Scope, ScopeId, ScopeInner, + SuspendedContext, + }, + lazynodes::LazyNodes, }; use bumpalo::{boxed::Box as BumpBox, Bump}; use std::{ @@ -328,14 +331,6 @@ impl<'a> NodeFactory<'a> { self.bump } - pub(crate) fn unstable_place_holder(&self) -> VNode { - VNode::Text(self.bump.alloc(VText { - text: "", - dom_id: empty_cell(), - is_static: true, - })) - } - /// Directly pass in text blocks without the need to use the format_args macro. pub fn static_text(&self, text: &'static str) -> VNode<'a> { VNode::Text(self.bump.alloc(VText { @@ -449,23 +444,6 @@ impl<'a> NodeFactory<'a> { } } - pub fn component_v2_borrowed( - self, - f: impl Fn(Context<'a>) -> Option> + 'a, - fc: fn(Scope<'a, P>) -> Element<'a>, - p: &'a P, - ) -> VNode<'a> { - // - todo!() - } - // pub fn component_v2_memoized( - // self, - // f: impl for<'b> Fn(Context<'b>) -> Option> + 'static, - // ) -> VNode<'a> { - // // - // todo!() - // } - pub fn component( &self, component: fn(Scope<'a, P>) -> Element<'a>, @@ -609,13 +587,11 @@ impl<'a> NodeFactory<'a> { }) } - pub fn annotate_lazy<'z, 'b, F>( - f: F, - ) -> Option) -> VNode<'z> + 'b>> + pub fn annotate_lazy<'z, 'b, F>(f: F) -> Option> where F: FnOnce(NodeFactory<'z>) -> VNode<'z> + 'b, { - Some(Box::new(f)) + Some(LazyNodes::new(f)) } } @@ -675,17 +651,11 @@ impl<'a> IntoVNode<'a> for Option> { } } -pub fn annotate_lazy<'a, 'b, F>(f: F) -> Option) -> VNode<'a> + 'b>> -where - F: FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b, -{ - Some(Box::new(f)) -} - -impl<'a> IntoVNode<'a> for Option) -> VNode<'a> + '_>> { +impl<'a> IntoVNode<'a> for Option> { + // impl<'a> IntoVNode<'a> for Option) -> VNode<'a> + '_>> { fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> { match self { - Some(lazy) => lazy(cx), + Some(lazy) => lazy.call(cx), None => VNode::Fragment(VFragment { children: &[], is_static: false, @@ -695,9 +665,10 @@ impl<'a> IntoVNode<'a> for Option) -> VNode<'a> + } } -impl<'a> IntoVNode<'a> for Box) -> VNode<'a> + '_> { +impl<'a> IntoVNode<'a> for LazyNodes<'a, '_> { + // impl<'a> IntoVNode<'a> for Box) -> VNode<'a> + '_> { fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> { - self(cx) + self.call(cx) } }