diff --git a/examples/borrowed.rs b/examples/borrowed.rs index e74254905..c9de40d89 100644 --- a/examples/borrowed.rs +++ b/examples/borrowed.rs @@ -20,7 +20,7 @@ fn main() { dioxus::desktop::launch(App, |c| c); } -fn App((cx, props): Component<()>) -> DomTree { +fn App((cx, props): Component<()>) -> Element { let text: &mut Vec = cx.use_hook(|_| vec![String::from("abc=def")], |f| f, |_| {}); let first = text.get_mut(0).unwrap(); @@ -43,7 +43,7 @@ impl<'a> Drop for C1Props<'a> { fn drop(&mut self) {} } -fn Child1<'a>((cx, props): Component<'a, C1Props>) -> DomTree<'a> { +fn Child1<'a>((cx, props): Component<'a, C1Props>) -> Element<'a> { let (left, right) = props.text.split_once("=").unwrap(); cx.render(rsx! { @@ -59,7 +59,7 @@ struct C2Props<'a> { text: &'a str, } -fn Child2<'a>((cx, props): Component<'a, C2Props>) -> DomTree<'a> { +fn Child2<'a>((cx, props): Component<'a, C2Props>) -> Element<'a> { cx.render(rsx! { Child3 { text: props.text @@ -72,7 +72,7 @@ struct C3Props<'a> { text: &'a str, } -fn Child3<'a>((cx, props): Component<'a, C3Props>) -> DomTree<'a> { +fn Child3<'a>((cx, props): Component<'a, C3Props>) -> Element<'a> { cx.render(rsx! { div { "{props.text}"} }) diff --git a/examples/calculator.rs b/examples/calculator.rs index deabb0d34..6d2d9b2ed 100644 --- a/examples/calculator.rs +++ b/examples/calculator.rs @@ -116,7 +116,7 @@ struct CalculatorKeyProps<'a> { onclick: &'a dyn Fn(MouseEvent), } -fn CalculatorKey<'a>((cx, props): Component<'a, CalculatorKeyProps>) -> DomTree<'a> { +fn CalculatorKey<'a>((cx, props): Component<'a, CalculatorKeyProps>) -> Element<'a> { rsx!(cx, button { class: "calculator-key {props.name}" onclick: {props.onclick} diff --git a/examples/framework_benchmark.rs b/examples/framework_benchmark.rs index 5a5b2f8cc..b63b1e98d 100644 --- a/examples/framework_benchmark.rs +++ b/examples/framework_benchmark.rs @@ -80,7 +80,7 @@ struct ActionButtonProps<'a> { onclick: &'a dyn Fn(MouseEvent), } -fn ActionButton<'a>((cx, props): Component<'a, ActionButtonProps>) -> DomTree<'a> { +fn ActionButton<'a>((cx, props): Component<'a, ActionButtonProps>) -> Element<'a> { rsx!(cx, div { class: "col-sm-6 smallpad" button { class:"btn btn-primary btn-block", r#type: "button", id: "{props.id}", onclick: {props.onclick}, "{props.name}" @@ -93,7 +93,7 @@ struct RowProps { row_id: usize, label: Rc, } -fn Row((cx, props): Component) -> DomTree { +fn Row((cx, props): Component) -> Element { rsx!(cx, tr { td { class:"col-md-1", "{props.row_id}" } td { class:"col-md-1", onclick: move |_| { /* run onselect */ } diff --git a/examples/hello_world.rs b/examples/hello_world.rs index db9e22899..1115b7e60 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -4,7 +4,7 @@ fn main() { dioxus::desktop::launch(App, |c| c); } -fn App((cx, props): Component<()>) -> DomTree { +fn App((cx, props): Component<()>) -> Element { cx.render(rsx! ( div { "Hello, world!" } )) diff --git a/examples/pattern_model.rs b/examples/pattern_model.rs index 1d046a76f..7c24d80de 100644 --- a/examples/pattern_model.rs +++ b/examples/pattern_model.rs @@ -76,7 +76,7 @@ struct CalculatorKeyProps<'a> { onclick: &'a dyn Fn(MouseEvent), } -fn CalculatorKey<'a>((cx, props): Component<'a, CalculatorKeyProps>) -> DomTree<'a> { +fn CalculatorKey<'a>((cx, props): Component<'a, CalculatorKeyProps>) -> Element<'a> { cx.render(rsx! { button { class: "calculator-key {props.name}" diff --git a/examples/rsx_usage.rs b/examples/rsx_usage.rs index f9c6a45a7..b14ced9e2 100644 --- a/examples/rsx_usage.rs +++ b/examples/rsx_usage.rs @@ -184,7 +184,7 @@ mod baller { pub struct BallerProps {} /// This component totally balls - pub fn Baller(_: Component) -> DomTree { + pub fn Baller(_: Component) -> Element { todo!() } } @@ -195,7 +195,7 @@ pub struct TallerProps { } /// This component is taller than most :) -pub fn Taller(_: Component) -> DomTree { +pub fn Taller(_: Component) -> Element { let b = true; todo!() } diff --git a/examples/ssr.rs b/examples/ssr.rs index 0991e53e4..2823e00fc 100644 --- a/examples/ssr.rs +++ b/examples/ssr.rs @@ -21,6 +21,6 @@ static App: FC<()> = |(cx, props)| { struct MyProps<'a> { text: &'a str, } -fn App2<'a>(cx: Context<'a>, props: &'a MyProps) -> DomTree<'a> { +fn App2<'a>(cx: Context<'a>, props: &'a MyProps) -> Element<'a> { None } diff --git a/examples/todomvc.rs b/examples/todomvc.rs index 6a39220ef..f0da8d256 100644 --- a/examples/todomvc.rs +++ b/examples/todomvc.rs @@ -85,7 +85,7 @@ pub struct TodoEntryProps { todo: Rc, } -pub fn TodoEntry((cx, props): Component) -> DomTree { +pub fn TodoEntry((cx, props): Component) -> Element { let is_editing = use_state(cx, || false); let contents = use_state(cx, || String::from("")); let todo = &props.todo; diff --git a/examples/web_tick.rs b/examples/web_tick.rs index 5ff18adf5..f0c9d40df 100644 --- a/examples/web_tick.rs +++ b/examples/web_tick.rs @@ -45,7 +45,7 @@ struct RowProps { row_id: usize, label: Label, } -fn Row((cx, props): Component) -> DomTree { +fn Row((cx, props): Component) -> Element { let [adj, col, noun] = props.label.0; cx.render(rsx! { tr { diff --git a/packages/core-macro/src/rsx/body.rs b/packages/core-macro/src/rsx/body.rs index b5b487459..3e28e481e 100644 --- a/packages/core-macro/src/rsx/body.rs +++ b/packages/core-macro/src/rsx/body.rs @@ -57,11 +57,11 @@ impl ToTokens for CallBody { }), // Otherwise we just build the LazyNode wrapper None => out_tokens.append_all(quote! { - dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{ + Some(dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{ use dioxus_elements::{GlobalAttributes, SvgAttributes}; #inner - }) + })) }), }; } diff --git a/packages/core/Cargo.toml b/packages/core/Cargo.toml index 9c19720cf..7c3dadbdb 100644 --- a/packages/core/Cargo.toml +++ b/packages/core/Cargo.toml @@ -22,7 +22,9 @@ longest-increasing-subsequence = "0.1.0" # internall used log = { version = "0.4", features = ["release_max_level_off"] } -futures-util = { version = "0.3.15", no_default_features = true } +futures-util = { version = "0.3.15", default-features = false, features = [ + "std", +] } smallvec = "1.6.1" @@ -40,6 +42,8 @@ serde = { version = "1", features = ["derive"], optional = true } serde_repr = { version = "0.1.7", optional = true } +stack_dst = "0.6.1" + [dev-dependencies] anyhow = "1.0.42" dioxus-html = { path = "../html" } diff --git a/packages/core/benches/jsframework.rs b/packages/core/benches/jsframework.rs index 113df0b71..713d1fafa 100644 --- a/packages/core/benches/jsframework.rs +++ b/packages/core/benches/jsframework.rs @@ -34,13 +34,13 @@ fn create_rows(c: &mut Criterion) { } } }); - cx.render(rsx! { + rsx! { table { tbody { {rows} } } - }) + } }; c.bench_function("create rows", |b| { @@ -57,9 +57,9 @@ struct RowProps { row_id: usize, label: Label, } -fn Row((cx, props): Component) -> DomTree { +fn Row((cx, props): Component) -> Element { let [adj, col, noun] = props.label.0; - cx.render(rsx! { + rsx! { tr { td { class:"col-md-1", "{props.row_id}" } td { class:"col-md-1", onclick: move |_| { /* run onselect */ } @@ -72,7 +72,7 @@ fn Row((cx, props): Component) -> DomTree { } td { class: "col-md-6" } } - }) + } } #[derive(PartialEq)] diff --git a/packages/core/examples/alternative.rs b/packages/core/examples/alternative.rs index edf037f89..3344aa4b2 100644 --- a/packages/core/examples/alternative.rs +++ b/packages/core/examples/alternative.rs @@ -9,7 +9,7 @@ fn main() { pub static EXAMPLE: FC<()> = |(cx, _)| { let list = (0..10).map(|_f| LazyNodes::new(move |_f| todo!())); - cx.render(LazyNodes::new(move |cx| { + Some(LazyNodes::new(move |cx| { cx.raw_element( "div", None, diff --git a/packages/core/examples/borrowed.rs b/packages/core/examples/borrowed.rs index a11f55225..f29159c8a 100644 --- a/packages/core/examples/borrowed.rs +++ b/packages/core/examples/borrowed.rs @@ -20,10 +20,10 @@ struct ListItem { age: u32, } -fn app<'a>(cx: Context<'a>, props: &AppProps) -> DomTree<'a> { +fn app<'a>(cx: Context<'a>, props: &AppProps) -> Element<'a> { // let (val, set_val) = use_state_classic(cx, || 0); - cx.render(LazyNodes::new(move |_nodecx| { + Some(LazyNodes::new(move |_nodecx| { todo!() // builder::ElementBuilder::new(_nodecx, "div") // .iter_child({ @@ -56,8 +56,8 @@ struct ChildProps { item_handler: Rc, } -fn ChildItem<'a>(cx: Context<'a>, props: &'a ChildProps) -> DomTree<'a> { - cx.render(LazyNodes::new(move |__cx| todo!())) +fn ChildItem<'a>(cx: Context<'a>, props: &'a ChildProps) -> Element<'a> { + Some(LazyNodes::new(move |__cx| todo!())) } impl PartialEq for ChildProps { diff --git a/packages/core/examples/fragment_from_iter.rs b/packages/core/examples/fragment_from_iter.rs index ae7d761e8..9cfd6cabe 100644 --- a/packages/core/examples/fragment_from_iter.rs +++ b/packages/core/examples/fragment_from_iter.rs @@ -2,7 +2,7 @@ use dioxus_core::prelude::*; fn main() {} -fn app<'a>(cx: Context<'a>, props: &()) -> DomTree<'a> { +fn app<'a>(cx: Context<'a>, props: &()) -> Element<'a> { let vak = use_suspense( cx, || async {}, @@ -26,7 +26,7 @@ fn app<'a>(cx: Context<'a>, props: &()) -> DomTree<'a> { ) })); - cx.render(LazyNodes::new(move |f| { + Some(LazyNodes::new(move |f| { f.raw_element( "div", None, diff --git a/packages/core/examples/jsframework.rs b/packages/core/examples/jsframework.rs index 2b2939a15..af698ec26 100644 --- a/packages/core/examples/jsframework.rs +++ b/packages/core/examples/jsframework.rs @@ -15,7 +15,7 @@ fn main() { assert!(g.edits.len() > 1); } -fn App((cx, props): Component<()>) -> DomTree { +fn App((cx, props): Component<()>) -> Element { let mut rng = SmallRng::from_entropy(); let rows = (0..10_000_usize).map(|f| { let label = Label::new(&mut rng); @@ -26,13 +26,13 @@ fn App((cx, props): Component<()>) -> DomTree { } } }); - cx.render(rsx! { + rsx! { table { tbody { {rows} } } - }) + } } #[derive(PartialEq, Props)] @@ -41,11 +41,11 @@ struct RowProps { label: Label, } -fn Row((cx, props): Component) -> DomTree { +fn Row((cx, props): Component) -> Element { let handler = move |evt: MouseEvent| { let g = evt.button; }; - cx.render(rsx! { + rsx! { tr { td { class:"col-md-1", "{props.row_id}" } td { class:"col-md-1", onclick: move |_| { /* run onselect */ } @@ -58,7 +58,7 @@ fn Row((cx, props): Component) -> DomTree { } td { class: "col-md-6" } } - }) + } } #[derive(PartialEq)] diff --git a/packages/core/examples/syntax.rs b/packages/core/examples/syntax.rs index bf695aa18..b2a8aeaf8 100644 --- a/packages/core/examples/syntax.rs +++ b/packages/core/examples/syntax.rs @@ -32,3 +32,8 @@ fn html_usage() { } }; } + +static App: FC<()> = |(cx, props)| { + // + rsx!(div {}) +}; diff --git a/packages/core/examples/vdom_usage.rs b/packages/core/examples/vdom_usage.rs index caf58faaf..cd381bf5a 100644 --- a/packages/core/examples/vdom_usage.rs +++ b/packages/core/examples/vdom_usage.rs @@ -4,7 +4,7 @@ use dioxus_core::prelude::*; #[async_std::main] async fn main() { - static App: FC<()> = |(cx, props)| cx.render(LazyNodes::new(|f| f.text(format_args!("hello")))); + static App: FC<()> = |(cx, props)| Some(LazyNodes::new(|f| f.text(format_args!("hello")))); let mut dom = VirtualDom::new(App); diff --git a/packages/core/src/component.rs b/packages/core/src/component.rs index d15aa2e39..901f4e4d6 100644 --- a/packages/core/src/component.rs +++ b/packages/core/src/component.rs @@ -5,7 +5,10 @@ //! if the type supports PartialEq. The Properties trait is used by the rsx! and html! macros to generate the type-safe builder //! that ensures compile-time required and optional fields on cx. -use crate::innerlude::{Context, DomTree, LazyNodes, FC}; +use crate::{ + innerlude::{Context, Element, LazyNodes, FC}, + VNode, +}; /// A component is a wrapper around a Context and some Props that share a lifetime /// @@ -63,8 +66,8 @@ pub type Component<'a, T> = (Context<'a>, &'a T); /// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it. /// #[allow(non_upper_case_globals, non_snake_case)] -pub fn Fragment((cx, _): Component<()>) -> DomTree { - cx.render(LazyNodes::new(|f| f.fragment_from_iter(cx.children()))) +pub fn Fragment((cx, _): Component<()>) -> Element { + Some(LazyNodes::new(|f| f.fragment_from_iter(cx.children()))) } /// Every "Props" used for a component must implement the `Properties` trait. This trait gives some hints to Dioxus diff --git a/packages/core/src/context.rs b/packages/core/src/context.rs index 2fd319f14..86d4749cb 100644 --- a/packages/core/src/context.rs +++ b/packages/core/src/context.rs @@ -137,10 +137,7 @@ impl<'src> Context<'src> { /// cx.render(lazy_tree) /// } ///``` - pub fn render) -> VNode<'src>>( - self, - lazy_nodes: LazyNodes<'src, F>, - ) -> DomTree<'src> { + pub fn render(self, lazy_nodes: LazyNodes<'src>) -> Option> { let bump = &self.scope.frames.wip_frame().bump; Some(lazy_nodes.into_vnode(NodeFactory { bump })) } diff --git a/packages/core/src/hooks.rs b/packages/core/src/hooks.rs index 0e0d6de2a..0154dce3b 100644 --- a/packages/core/src/hooks.rs +++ b/packages/core/src/hooks.rs @@ -93,11 +93,11 @@ pub fn use_suspense<'src, Out, Fut, Cb>( cx: Context<'src>, task_initializer: impl FnOnce() -> Fut, user_callback: Cb, -) -> DomTree<'src> +) -> Element<'src> where Fut: Future + 'static, Out: 'static, - Cb: for<'a> Fn(SuspendedContext<'a>, &Out) -> DomTree<'a> + 'static, + Cb: for<'a> Fn(SuspendedContext<'a>, &Out) -> Element<'a> + 'static, { /* General strategy: @@ -135,12 +135,12 @@ where None => { let value = hook.value.clone(); - cx.render(LazyNodes::new(|f| { + Some(LazyNodes::new(|f| { let bump = f.bump(); use bumpalo::boxed::Box as BumpBox; - let f: &mut dyn FnMut(SuspendedContext<'src>) -> DomTree<'src> = + let f: &mut dyn FnMut(SuspendedContext<'src>) -> Element<'src> = bump.alloc(move |sus| { let val = value.borrow(); @@ -177,12 +177,14 @@ pub struct SuspendedContext<'a> { } impl<'src> SuspendedContext<'src> { - pub fn render) -> VNode<'src>>( + pub fn render( + // pub fn render) -> VNode<'src>>( self, - lazy_nodes: LazyNodes<'src, F>, - ) -> DomTree<'src> { + lazy_nodes: LazyNodes<'src>, + ) -> Element<'src> { let bump = &self.inner.scope.frames.wip_frame().bump; - Some(lazy_nodes.into_vnode(NodeFactory { bump })) + todo!("suspense") + // Some(lazy_nodes.into_vnode(NodeFactory { bump })) } } diff --git a/packages/core/src/lib.rs b/packages/core/src/lib.rs index c77aa50a0..02d6f8422 100644 --- a/packages/core/src/lib.rs +++ b/packages/core/src/lib.rs @@ -56,12 +56,13 @@ pub(crate) mod innerlude { pub use crate::util::*; pub use crate::virtual_dom::*; - pub type DomTree<'a> = Option>; - pub type FC

= for<'a> fn(Component<'a, P>) -> DomTree<'a>; + // pub type Element<'a> = Option>; + pub type Element<'a> = Option>; + pub type FC

= for<'a> fn(Component<'a, P>) -> Element<'a>; } pub use crate::innerlude::{ - Context, DioxusElement, DomEdit, DomTree, ElementId, EventPriority, LazyNodes, MountType, + Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, LazyNodes, MountType, Mutations, NodeFactory, Properties, SchedulerMsg, ScopeId, SuspendedContext, TaskHandle, TestDom, ThreadsafeVirtualDom, UserEvent, VNode, VirtualDom, FC, }; @@ -70,7 +71,7 @@ pub mod prelude { pub use crate::component::{fc_to_builder, Component, Fragment, Properties}; pub use crate::context::Context; pub use crate::hooks::*; - pub use crate::innerlude::{DioxusElement, DomTree, LazyNodes, Mutations, NodeFactory, FC}; + pub use crate::innerlude::{DioxusElement, Element, LazyNodes, Mutations, 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 7fd7bccf0..142eab4b7 100644 --- a/packages/core/src/nodes.rs +++ b/packages/core/src/nodes.rs @@ -4,7 +4,7 @@ //! cheap and *very* fast to construct - building a full tree should be quick. use crate::innerlude::{ - empty_cell, Context, DomTree, ElementId, Properties, Scope, ScopeId, SuspendedContext, FC, + empty_cell, Context, Element, ElementId, Properties, Scope, ScopeId, SuspendedContext, FC, }; use bumpalo::{boxed::Box as BumpBox, Bump}; use std::{ @@ -13,6 +13,10 @@ use std::{ marker::PhantomData, }; +use stack_dst::Value as StackDST; + +pub type LazyNodeFactory<'a> = StackDST) -> VNode<'a>>; + /// A composable "VirtualNode" to declare a User Interface in the Dioxus VirtualDOM. /// /// VNodes are designed to be lightweight and used with with a bump allocator. To create a VNode, you can use either of: @@ -287,7 +291,7 @@ pub struct VComponent<'src> { // Function pointer to the FC that was used to generate this component pub user_fc: *const (), - pub(crate) caller: &'src dyn for<'b> Fn(&'b Scope) -> DomTree<'b>, + pub(crate) caller: &'src dyn for<'b> Fn(&'b Scope) -> Element<'b>, pub(crate) children: &'src [VNode<'src>], @@ -306,7 +310,7 @@ pub struct VSuspended<'a> { pub dom_id: Cell>, #[allow(clippy::type_complexity)] - pub callback: RefCell) -> DomTree<'a>>>>, + pub callback: RefCell) -> Element<'a>>>>, } /// This struct provides an ergonomic API to quickly build VNodes. @@ -328,9 +332,10 @@ impl<'a> NodeFactory<'a> { self.bump } - pub fn render_directly(&self, lazy_nodes: LazyNodes<'a, F>) -> DomTree<'a> - where - F: FnOnce(NodeFactory<'a>) -> VNode<'a>, + pub fn render_directly(&self, lazy_nodes: LazyNodes<'a>) -> Option> +// pub fn render_directly(&self, lazy_nodes: LazyNodes<'a, F>) -> Element<'a> + // where + // F: FnOnce(NodeFactory<'a>) -> VNode<'a>, { Some(lazy_nodes.into_vnode(NodeFactory { bump: self.bump })) } @@ -526,11 +531,11 @@ impl<'a> NodeFactory<'a> { let key = key.map(|f| self.raw_text(f).0); - let caller: &'a mut dyn for<'b> Fn(&'b Scope) -> DomTree<'b> = - bump.alloc(move |scope: &Scope| -> DomTree { + let caller: &'a mut dyn for<'b> Fn(&'b Scope) -> Element<'b> = + bump.alloc(move |scope: &Scope| -> Element { log::debug!("calling component renderr {:?}", scope.our_arena_idx); let props: &'_ P = unsafe { &*(raw_props as *const P) }; - let res = component((Context { scope }, props)); + let res: Element = component((Context { scope }, props)); unsafe { std::mem::transmute(res) } }); @@ -691,40 +696,43 @@ impl<'a> IntoVNode<'a> for VNode<'a> { /// ```rust /// LazyNodes::new(|f| f.element("div", [], [], [] None)) /// ``` -pub struct LazyNodes<'a, G> -where - G: FnOnce(NodeFactory<'a>) -> VNode<'a>, -{ - inner: G, - _p: PhantomData<&'a ()>, +pub struct LazyNodes<'a> { + inner: LazyNodeFactory<'a>, } +// where +// G: FnOnce(NodeFactory<'a>) -> VNode<'a>, -impl<'a, G> LazyNodes<'a, G> -where - G: FnOnce(NodeFactory<'a>) -> VNode<'a>, +impl<'a> LazyNodes<'a> +// where +// G: FnOnce(NodeFactory<'a>) -> VNode<'a>, { - pub fn new(f: G) -> Self { - Self { - inner: f, - _p: PhantomData {}, - } + pub fn new(f: impl FnOnce(NodeFactory<'a>) -> VNode<'a>) -> Self { + todo!() + // pub fn new) -> VNode<'a>>(f: G) -> Self { + // let inner = LazyNodeFactory::new(f); + // Self { inner: f } } } // Our blanket impl -impl<'a, G> IntoVNode<'a> for LazyNodes<'a, G> -where - G: FnOnce(NodeFactory<'a>) -> VNode<'a>, +impl<'a> IntoVNode<'a> for LazyNodes<'a> +// where +// G: FnOnce(NodeFactory<'a>) -> VNode<'a>, { fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> { - (self.inner)(cx) + // let f = self.inner; + todo!("manually drop here") + // (self.inner)(cx) } } // Our blanket impl -impl<'a, G> IntoIterator for LazyNodes<'a, G> -where - G: FnOnce(NodeFactory<'a>) -> VNode<'a>, +impl<'a> IntoIterator for LazyNodes<'a> +// where +// G: FnOnce(NodeFactory<'a>) -> VNode<'a>, +// impl<'a, G> IntoIterator for LazyNodes<'a, G> +// where +// G: FnOnce(NodeFactory<'a>) -> VNode<'a>, { type Item = Self; type IntoIter = std::iter::Once; @@ -756,6 +764,15 @@ impl<'a> IntoVNode<'a> for Option> { } } +impl<'a> IntoVNode<'a> for Option> { + fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> { + match self { + Some(n) => n.into_vnode(cx), + None => cx.fragment_from_iter(None as Option), + } + } +} + impl IntoVNode<'_> for &'static str { fn into_vnode(self, cx: NodeFactory) -> VNode { cx.static_text(self) diff --git a/packages/core/src/scope.rs b/packages/core/src/scope.rs index 9e66fe3f4..348e1b74b 100644 --- a/packages/core/src/scope.rs +++ b/packages/core/src/scope.rs @@ -28,7 +28,7 @@ pub struct Scope { // Nodes pub(crate) frames: ActiveFrame, - pub(crate) caller: *const dyn for<'b> Fn(&'b Scope) -> DomTree<'b>, + pub(crate) caller: *const dyn for<'b> Fn(&'b Scope) -> Element<'b>, pub(crate) child_nodes: ScopeChildren<'static>, /* @@ -176,7 +176,7 @@ impl Scope { // Scopes cannot be made anywhere else except for this file // Therefore, their lifetimes are connected exclusively to the virtual dom pub(crate) fn new( - caller: &dyn for<'b> Fn(&'b Scope) -> DomTree<'b>, + caller: &dyn for<'b> Fn(&'b Scope) -> Element<'b>, our_arena_idx: ScopeId, parent_idx: Option, height: u32, @@ -217,7 +217,7 @@ impl Scope { pub(crate) fn update_scope_dependencies<'creator_node>( &mut self, - caller: &'creator_node dyn for<'b> Fn(&'b Scope) -> DomTree<'b>, + caller: &'creator_node dyn for<'b> Fn(&'b Scope) -> Element<'b>, child_nodes: ScopeChildren, ) { log::debug!("Updating scope dependencies {:?}", self.our_arena_idx); @@ -317,7 +317,7 @@ impl Scope { let mut cb = sus.callback.borrow_mut().take().unwrap(); - let new_node: DomTree<'a> = (cb)(cx); + let new_node: Element<'a> = (cb)(cx); } } @@ -350,20 +350,25 @@ impl Scope { log::debug!("Borrowed stuff is successfully cleared"); // Cast the caller ptr from static to one with our own reference - let render: &dyn for<'b> Fn(&'b Scope) -> DomTree<'b> = unsafe { &*self.caller }; + let render: &dyn for<'b> Fn(&'b Scope) -> Element<'b> = unsafe { &*self.caller }; // Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders. - if let Some(new_head) = render(self) { - log::debug!("Render is successful"); + // + todo!() + // if let Some(builder) = render(self) { + // let new_head = builder.into_vnode(NodeFactory { + // bump: &self.frames.wip_frame().bump, + // }); + // log::debug!("Render is successful"); - // the user's component succeeded. We can safely cycle to the next frame - self.frames.wip_frame_mut().head_node = unsafe { std::mem::transmute(new_head) }; - self.frames.cycle_frame(); + // // the user's component succeeded. We can safely cycle to the next frame + // self.frames.wip_frame_mut().head_node = unsafe { std::mem::transmute(new_head) }; + // self.frames.cycle_frame(); - true - } else { - false - } + // true + // } else { + // false + // } } } diff --git a/packages/core/src/test_dom.rs b/packages/core/src/test_dom.rs index 7b94496c2..2f7977269 100644 --- a/packages/core/src/test_dom.rs +++ b/packages/core/src/test_dom.rs @@ -21,16 +21,16 @@ impl TestDom { NodeFactory::new(&self.bump) } - pub fn render_direct<'a, F>(&'a self, lazy_nodes: LazyNodes<'a, F>) -> VNode<'a> - where - F: FnOnce(NodeFactory<'a>) -> VNode<'a>, + pub fn render_direct<'a>(&'a self, lazy_nodes: Element<'a>) -> VNode<'a> +// where + // F: FnOnce(NodeFactory<'a>) -> VNode<'a>, { lazy_nodes.into_vnode(NodeFactory::new(&self.bump)) } - pub fn render<'a, F>(&'a self, lazy_nodes: LazyNodes<'a, F>) -> &'a VNode<'a> - where - F: FnOnce(NodeFactory<'a>) -> VNode<'a>, + pub fn render<'a>(&'a self, lazy_nodes: Element<'a>) -> &'a VNode<'a> +// where + // F: FnOnce(NodeFactory<'a>) -> VNode<'a>, { self.bump .alloc(lazy_nodes.into_vnode(NodeFactory::new(&self.bump))) @@ -43,9 +43,10 @@ impl TestDom { machine.mutations } - pub fn create<'a, F1>(&'a self, left: LazyNodes<'a, F1>) -> Mutations<'a> - where - F1: FnOnce(NodeFactory<'a>) -> VNode<'a>, + pub fn create<'a>(&'a self, left: Element<'a>) -> Mutations<'a> +// pub fn create<'a, F1>(&'a self, left: LazyNodes<'a, F1>) -> Mutations<'a> + // where + // F1: FnOnce(NodeFactory<'a>) -> VNode<'a>, { let old = self.bump.alloc(self.render_direct(left)); @@ -58,14 +59,16 @@ impl TestDom { machine.mutations } - pub fn lazy_diff<'a, F1, F2>( + pub fn lazy_diff<'a>( &'a self, - left: LazyNodes<'a, F1>, - right: LazyNodes<'a, F2>, + left: Element<'a>, + right: Element<'a>, + // left: LazyNodes<'a, F1>, + // right: LazyNodes<'a, F2>, ) -> (Mutations<'a>, Mutations<'a>) - where - F1: FnOnce(NodeFactory<'a>) -> VNode<'a>, - F2: FnOnce(NodeFactory<'a>) -> VNode<'a>, +// where + // F1: FnOnce(NodeFactory<'a>) -> VNode<'a>, + // F2: FnOnce(NodeFactory<'a>) -> VNode<'a>, { let (old, new) = (self.render(left), self.render(right)); diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index acd8df52c..ff0600a08 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -143,7 +143,7 @@ impl VirtualDom { let _p = root_props.clone(); // Safety: this callback is only valid for the lifetime of the root props - let root_caller: Rc DomTree> = Rc::new(move |scope: &Scope| unsafe { + let root_caller: Rc Element> = Rc::new(move |scope: &Scope| unsafe { let props = _p.downcast_ref::

().unwrap(); std::mem::transmute(root((Context { scope }, props))) }); @@ -219,7 +219,7 @@ impl VirtualDom { let root = *self.root_fc.downcast_ref::>().unwrap(); - let root_caller: Box DomTree> = + let root_caller: Box Element> = Box::new(move |scope: &Scope| unsafe { let props: &'_ P = &*(props_ptr as *const P); std::mem::transmute(root((Context { scope }, props))) @@ -368,22 +368,24 @@ impl VirtualDom { use futures_util::StreamExt; // Wait for any new events if we have nothing to do - futures_util::select! { - _ = self.scheduler.async_tasks.next() => {} - msg = self.scheduler.receiver.next() => { - match msg.unwrap() { - SchedulerMsg::Task(t) => { - self.scheduler.handle_task(t); - }, - SchedulerMsg::Immediate(im) => { - self.scheduler.dirty_scopes.insert(im); - } - SchedulerMsg::UiEvent(evt) => { - self.scheduler.ui_events.push_back(evt); - } - } - }, - } + todo!("wait for work without select macro") + + // futures_util::select! { + // _ = self.scheduler.async_tasks.next() => {} + // msg = self.scheduler.receiver.next() => { + // match msg.unwrap() { + // SchedulerMsg::Task(t) => { + // self.scheduler.handle_task(t); + // }, + // SchedulerMsg::Immediate(im) => { + // self.scheduler.dirty_scopes.insert(im); + // } + // SchedulerMsg::UiEvent(evt) => { + // self.scheduler.ui_events.push_back(evt); + // } + // } + // }, + // } } } @@ -408,4 +410,4 @@ impl std::fmt::Display for VirtualDom { } // we never actually use the contents of this root caller -struct RootCaller(Rc Fn(&'b Scope) -> DomTree<'b> + 'static>); +struct RootCaller(Rc Fn(&'b Scope) -> Element<'b> + 'static>); diff --git a/packages/core/tests/borrowedstate.rs b/packages/core/tests/borrowedstate.rs index b7d2e3f31..09f319ac0 100644 --- a/packages/core/tests/borrowedstate.rs +++ b/packages/core/tests/borrowedstate.rs @@ -10,17 +10,17 @@ fn test_borrowed_state() { let _ = VirtualDom::new(Parent); } -fn Parent((cx, _): Component<()>) -> DomTree { +fn Parent((cx, _): Component<()>) -> Element { let value = cx.use_hook(|_| String::new(), |f| &*f, |_| {}); - cx.render(rsx! { + rsx! { div { Child { name: value } Child { name: value } Child { name: value } Child { name: value } } - }) + } } #[derive(Props)] @@ -28,13 +28,13 @@ struct ChildProps<'a> { name: &'a str, } -fn Child<'a>((cx, props): Component<'a, ChildProps>) -> DomTree<'a> { - cx.render(rsx! { +fn Child<'a>((cx, props): Component<'a, ChildProps>) -> Element<'a> { + rsx! { div { h1 { "it's nested" } Child2 { name: props.name } } - }) + } } #[derive(Props)] @@ -42,8 +42,8 @@ struct Grandchild<'a> { name: &'a str, } -fn Child2<'a>((cx, props): Component<'a, Grandchild>) -> DomTree<'a> { - cx.render(rsx! { +fn Child2<'a>((cx, props): Component<'a, Grandchild>) -> Element<'a> { + rsx! { div { "Hello {props.name}!" } - }) + } } diff --git a/packages/core/tests/create_dom.rs b/packages/core/tests/create_dom.rs index d8a79162d..8339ceb9f 100644 --- a/packages/core/tests/create_dom.rs +++ b/packages/core/tests/create_dom.rs @@ -22,13 +22,13 @@ fn new_dom(app: FC

, props: P) -> VirtualDom { #[test] fn test_original_diff() { static APP: FC<()> = |(cx, props)| { - cx.render(rsx! { + rsx! { div { div { "Hello, world!" } } - }) + } }; let mut dom = new_dom(APP, ()); @@ -58,7 +58,7 @@ fn test_original_diff() { #[test] fn create() { static APP: FC<()> = |(cx, props)| { - cx.render(rsx! { + rsx! { div { div { "Hello, world!" @@ -72,7 +72,7 @@ fn create() { } } } - }) + } }; let mut dom = new_dom(APP, ()); @@ -121,11 +121,11 @@ fn create() { #[test] fn create_list() { static APP: FC<()> = |(cx, props)| { - cx.render(rsx! { + rsx! { {(0..3).map(|f| rsx!{ div { "hello" }})} - }) + } }; let mut dom = new_dom(APP, ()); @@ -170,12 +170,12 @@ fn create_list() { #[test] fn create_simple() { static APP: FC<()> = |(cx, props)| { - cx.render(rsx! { + rsx! { div {} div {} div {} div {} - }) + } }; let mut dom = new_dom(APP, ()); @@ -208,19 +208,19 @@ fn create_simple() { #[test] fn create_components() { static App: FC<()> = |(cx, props)| { - cx.render(rsx! { + rsx! { Child { "abc1" } Child { "abc2" } Child { "abc3" } - }) + } }; static Child: FC<()> = |(cx, props)| { - cx.render(rsx! { + rsx! { h1 {} div { {cx.children()} } p {} - }) + } }; let mut dom = new_dom(App, ()); @@ -269,10 +269,10 @@ fn create_components() { #[test] fn anchors() { static App: FC<()> = |(cx, props)| { - cx.render(rsx! { + rsx! { {true.then(|| rsx!{ div { "hello" } })} {false.then(|| rsx!{ div { "goodbye" } })} - }) + } }; let mut dom = new_dom(App, ()); @@ -303,9 +303,9 @@ fn suspended() { || async { // }, - |cx, p| cx.render(rsx! { "hi "}), + |cx, p| rsx! { "hi "}, ); - cx.render(rsx! { {val} }) + rsx! { {val} } }; let mut dom = new_dom(App, ()); diff --git a/packages/core/tests/diffing.rs b/packages/core/tests/diffing.rs index bfb33b4d6..55a332e57 100644 --- a/packages/core/tests/diffing.rs +++ b/packages/core/tests/diffing.rs @@ -807,14 +807,14 @@ fn controlled_keyed_diffing_out_of_order_max_test() { fn suspense() { let dom = new_dom(); - let edits = dom.create(LazyNodes::new(|f| { + let edits = dom.create(Some(LazyNodes::new(|f| { use std::cell::{Cell, RefCell}; VNode::Suspended(f.bump().alloc(VSuspended { task_id: 0, callback: RefCell::new(None), dom_id: Cell::new(None), })) - })); + }))); assert_eq!( edits.edits, [CreatePlaceholder { root: 0 }, AppendChildren { many: 1 }] diff --git a/packages/core/tests/display_vdom.rs b/packages/core/tests/display_vdom.rs index ec81ac52c..734d0fd77 100644 --- a/packages/core/tests/display_vdom.rs +++ b/packages/core/tests/display_vdom.rs @@ -14,7 +14,7 @@ mod test_logging; #[test] fn please_work() { static App: FC<()> = |(cx, props)| { - cx.render(rsx! { + rsx! { div { hidden: "true" "hello" @@ -24,13 +24,13 @@ fn please_work() { Child {} } div { "hello" } - }) + } }; static Child: FC<()> = |(cx, props)| { - cx.render(rsx! { + rsx! { div { "child" } - }) + } }; let mut dom = VirtualDom::new(App); diff --git a/packages/core/tests/lifecycle.rs b/packages/core/tests/lifecycle.rs index 3b9c05cca..98837fbc3 100644 --- a/packages/core/tests/lifecycle.rs +++ b/packages/core/tests/lifecycle.rs @@ -22,7 +22,7 @@ fn manual_diffing() { static App: FC = |(cx, props)| { let val = props.value.lock().unwrap(); - cx.render(rsx! { div { "{val}" } }) + rsx! { div { "{val}" } } }; let value = Arc::new(Mutex::new("Hello")); diff --git a/packages/core/tests/sharedstate.rs b/packages/core/tests/sharedstate.rs index 1983ec8c7..f2a17b804 100644 --- a/packages/core/tests/sharedstate.rs +++ b/packages/core/tests/sharedstate.rs @@ -15,12 +15,12 @@ fn shared_state_test() { static App: FC<()> = |(cx, props)| { cx.provide_state(MySharedState("world!")); - rsx!(cx, Child {}) + rsx!(Child {}) }; static Child: FC<()> = |(cx, props)| { let shared = cx.consume_state::()?; - rsx!(cx, "Hello, {shared.0}") + rsx!("Hello, {shared.0}") }; let mut dom = VirtualDom::new(App); diff --git a/packages/core/tests/vdom_rebuild.rs b/packages/core/tests/vdom_rebuild.rs index 9ea872a17..2350774c5 100644 --- a/packages/core/tests/vdom_rebuild.rs +++ b/packages/core/tests/vdom_rebuild.rs @@ -19,7 +19,7 @@ use dioxus_html as dioxus_elements; fn app_runs() { static App: FC<()> = |(cx, props)| { // - cx.render(rsx!( div{"hello"} )) + rsx!( div{"hello"} ) }; let mut vdom = VirtualDom::new(App); let edits = vdom.rebuild(); @@ -29,10 +29,10 @@ fn app_runs() { #[test] fn fragments_work() { static App: FC<()> = |(cx, props)| { - cx.render(rsx!( + rsx!( div{"hello"} div{"goodbye"} - )) + ) }; let mut vdom = VirtualDom::new(App); let edits = vdom.rebuild(); @@ -43,10 +43,10 @@ fn fragments_work() { #[test] fn lists_work() { static App: FC<()> = |(cx, props)| { - cx.render(rsx!( + rsx!( h1 {"hello"} {(0..6).map(|f| rsx!(span{ "{f}" }))} - )) + ) }; let mut vdom = VirtualDom::new(App); let edits = vdom.rebuild(); @@ -56,11 +56,11 @@ fn lists_work() { #[test] fn conditional_rendering() { static App: FC<()> = |(cx, props)| { - cx.render(rsx!( + rsx!( h1 {"hello"} {true.then(|| rsx!(span{ "a" }))} {false.then(|| rsx!(span{ "b" }))} - )) + ) }; let mut vdom = VirtualDom::new(App); @@ -73,16 +73,16 @@ fn conditional_rendering() { #[test] fn child_components() { static App: FC<()> = |(cx, props)| { - cx.render(rsx!( + rsx!( {true.then(|| rsx!(Child { }))} {false.then(|| rsx!(Child { }))} - )) + ) }; static Child: FC<()> = |(cx, props)| { - cx.render(rsx!( + rsx!( h1 {"hello"} h1 {"goodbye"} - )) + ) }; let mut vdom = VirtualDom::new(App); let edits = vdom.rebuild(); @@ -92,8 +92,8 @@ fn child_components() { #[test] fn suspended_works() { static App: FC<()> = |(cx, props)| { - let title = use_suspense(cx, || async { "bob" }, |cx, f| cx.render(rsx! { "{f}"})); - cx.render(rsx!("hello" { title })) + let title = use_suspense(cx, || async { "bob" }, |cx, f| rsx! { "{f}"}); + rsx!("hello" { title }) }; let mut vdom = VirtualDom::new(App); diff --git a/packages/desktop/examples/todomvc.rs b/packages/desktop/examples/todomvc.rs index fa2eae08e..5d0ebd5cd 100644 --- a/packages/desktop/examples/todomvc.rs +++ b/packages/desktop/examples/todomvc.rs @@ -136,7 +136,7 @@ pub struct TodoEntryProps { id: u32, } -pub fn TodoEntry((cx, props): Component) -> DomTree { +pub fn TodoEntry((cx, props): Component) -> Element { let todos = use_shared_state::(cx)?; let _todos = todos.read(); diff --git a/packages/desktop/src/desktop_context.rs b/packages/desktop/src/desktop_context.rs index f5c352c38..b5c1ab78f 100644 --- a/packages/desktop/src/desktop_context.rs +++ b/packages/desktop/src/desktop_context.rs @@ -2,7 +2,7 @@ use std::cell::RefCell; use dioxus::prelude::Component; use dioxus_core as dioxus; -use dioxus_core::{Context, DomTree, LazyNodes, NodeFactory, Properties}; +use dioxus_core::{Context, Element, LazyNodes, NodeFactory, Properties}; use dioxus_core_macro::Props; /* @@ -54,7 +54,7 @@ pub struct WebviewWindowProps<'a> { /// /// /// -pub fn WebviewWindow<'a>((cx, props): Component<'a, WebviewWindowProps>) -> DomTree<'a> { +pub fn WebviewWindow<'a>((cx, props): Component<'a, WebviewWindowProps>) -> Element<'a> { let dtcx = cx.consume_state::>()?; cx.use_hook( diff --git a/packages/web/examples/basic.rs b/packages/web/examples/basic.rs index 21ede5078..699305df2 100644 --- a/packages/web/examples/basic.rs +++ b/packages/web/examples/basic.rs @@ -68,13 +68,13 @@ static APP: FC<()> = |(cx, _)| { }) }; -fn render_bullets(cx: Context) -> DomTree { +fn render_bullets(cx: Context) -> Element { rsx!(cx, div { "bite me" }) } -fn render_list(cx: Context, count: usize) -> DomTree { +fn render_list(cx: Context, count: usize) -> Element { let items = (0..count).map(|f| { rsx! { li { "a - {f}" }