wip: try to get lifetimes passed in properly

This commit is contained in:
Jonathan Kelley committed 2021-10-30 20:28:58 -04:00
1 parent 27d891934a
commit f70b5b4e4a
6 files changed
+312 -184

No files matched your search

+2 -2
View File
@@ -49,8 +49,8 @@ fern = { version = "0.6.0", features = ["colored"] }
rand = { version = "0.8.4", features = ["small_rng"] } rand = { version = "0.8.4", features = ["small_rng"] }
simple_logger = "1.13.0" simple_logger = "1.13.0"
dioxus-core-macro = { path = "../core-macro", version = "0.1.2" } dioxus-core-macro = { path = "../core-macro", version = "0.1.2" }
async-std = { version = "1.9.0", features = ["attributes"] } # async-std = { version = "1.9.0", features = ["attributes"] }
criterion = "0.3.5" # criterion = "0.3.5"
[features] [features]
default = [] default = []
+272 -166
View File
@@ -1,8 +1,10 @@
use std::borrow::BorrowMut;
use std::cell::{Cell, RefCell};
use std::marker::PhantomData; use std::marker::PhantomData;
use dioxus::component::Scope; use dioxus::component::Scope;
use dioxus::events::on::MouseEvent; use dioxus::events::on::MouseEvent;
use dioxus::nodes::{annotate_lazy, IntoVNode}; use dioxus::nodes::{annotate_lazy, IntoVNode, VComponent, VFragment, VText};
use dioxus_core as dioxus; use dioxus_core as dioxus;
use dioxus_core::prelude::*; use dioxus_core::prelude::*;
use dioxus_core_macro::*; use dioxus_core_macro::*;
@@ -29,191 +31,190 @@ fn t() {
}; };
} }
#[derive(PartialEq, Props)] // #[derive(PartialEq, Props)]
struct OurProps { // struct OurProps {
foo: String, // foo: String,
} // }
fn App<'a>((cx, props): Scope<'a, OurProps>) -> Element<'a> { // fn App<'a>((cx, props): Scope<'a, OurProps>) -> Element<'a> {
let a = rsx! { // let a = rsx! {
div { // div {
"asd" // "asd"
"{props.foo}" // "{props.foo}"
} // }
}; // };
let p = (0..10).map(|f| { // let p = (0..10).map(|f| {
rsx! { // rsx! {
div { // div {
} // }
} // }
}); // });
let g = match "text" { // let g = match "text" {
"a" => { // "a" => {
rsx!("asd") // rsx!("asd")
} // }
_ => { // _ => {
rsx!("asd") // rsx!("asd")
} // }
}; // };
let items = ["bob", "bill", "jack"]; // let items = ["bob", "bill", "jack"];
let f = items // let f = items
.iter() // .iter()
.filter(|f| f.starts_with('b')) // .filter(|f| f.starts_with('b'))
.map(|f| rsx!("hello {f}")); // .map(|f| rsx!("hello {f}"));
// use dioxus_hooks; // // use dioxus_hooks;
// let g = use_state(|| "hello".to_string()); // // let g = use_state(|| "hello".to_string());
let s: &'a mut String = cx.use_hook(|_| String::new(), |f| f, |_| {}); // let s: &'a mut String = cx.use_hook(|_| String::new(), |f| f, |_| {});
/* // /*
the final closure is allowed to borrow anything provided it // the final closure is allowed to borrow anything provided it
*/ // */
// // cx.render({
// // let p: Option<Box<dyn FnOnce(_) -> _>> = Some(Box::new(move |__cx: NodeFactory| {
// // use dioxus_elements::{GlobalAttributes, SvgAttributes};
// cx.render({ // // let props = Child2Props { foo: s };
// let p: Option<Box<dyn FnOnce(_) -> _>> = Some(Box::new(move |__cx: NodeFactory| { // // let ch: VNode = __cx.component(Child2, props, None, []);
// use dioxus_elements::{GlobalAttributes, SvgAttributes}; // // __cx.element(
// // dioxus_elements::div,
// // [],
// // [],
// // [ch],
// // // [__cx.component(Child2, fc_to_builder(Child2).foo(s).build(), None, [])],
// // None,
// // )
// // }));
// // p
// // // let ___p: Box<dyn FnOnce(NodeFactory) -> VNode> = Box::new(move |__cx| {
// // // use dioxus_elements::{GlobalAttributes, SvgAttributes};
// let props = Child2Props { foo: s }; // // // let props = Child2Props { foo: s };
// let ch: VNode = __cx.component(Child2, props, None, []); // // // let ch: VNode = __cx.component(Child2, props, None, []);
// __cx.element( // // // __cx.element(
// dioxus_elements::div, // // // dioxus_elements::div,
// [], // // // [],
// [], // // // [],
// [ch], // // // [ch],
// // [__cx.component(Child2, fc_to_builder(Child2).foo(s).build(), None, [])], // // // // [__cx.component(Child2, fc_to_builder(Child2).foo(s).build(), None, [])],
// None, // // // None,
// ) // // // )
// })); // // // });
// p // // // Some(___p)
// // let ___p: Box<dyn FnOnce(NodeFactory) -> VNode> = Box::new(move |__cx| { // // })
// // use dioxus_elements::{GlobalAttributes, SvgAttributes};
// // let props = Child2Props { foo: s }; // let a = annotate_lazy(move |f| {
// // let ch: VNode = __cx.component(Child2, props, None, []); // //
// // __cx.element( // todo!()
// // dioxus_elements::div, // });
// // [], // let b = annotate_lazy(move |f| {
// // [], // //
// // [ch], // f.text(format_args!("{}", props.foo))
// // // [__cx.component(Child2, fc_to_builder(Child2).foo(s).build(), None, [])], // });
// // None,
// // )
// // });
// // Some(___p)
// })
let a = annotate_lazy(move |f| { // let c = annotate_lazy(move |f| {
// // //
todo!() // f.component(
}); // Child,
let b = annotate_lazy(move |f| { // OurProps {
// // //
f.text(format_args!("{}", props.foo)) // foo: "hello".to_string(),
}); // },
// None,
// [],
// )
// });
let c = annotate_lazy(move |f| { // let st: &'a String = cx.use_hook(|_| "hello".to_string(), |f| f, |_| {});
//
f.component(
Child,
OurProps {
//
foo: "hello".to_string(),
},
None,
[],
)
});
let st: &'a String = cx.use_hook(|_| "hello".to_string(), |f| f, |_| {}); // let d = annotate_lazy(move |f| {
// //
// f.component(
// Child2,
// Child2Props {
// //
// foo: st,
// },
// None,
// [],
// )
// });
let d = annotate_lazy(move |f| { // let e = match "asd" {
// // b => {
f.component( // //
Child2,
Child2Props {
//
foo: st,
},
None,
[],
)
});
let e = match "asd" { // annotate_lazy(move |f| {
b => { // //
// // f.text(format_args!("{}", props.foo))
// })
// }
// a => {
// //
annotate_lazy(move |f| { // annotate_lazy(move |f| {
// // //
f.text(format_args!("{}", props.foo)) // f.text(format_args!("{}", props.foo))
}) // })
} // }
a => { // };
//
annotate_lazy(move |f| { // cx.render(annotate_lazy(move |f| {
// // //
f.text(format_args!("{}", props.foo))
})
}
};
cx.render(annotate_lazy(move |f| { // f.raw_element(
// // "div",
// None,
// [],
// [],
// [
// //
// f.fragment_from_iter(a),
// f.fragment_from_iter(b),
// f.fragment_from_iter(c),
// f.fragment_from_iter(e),
// ],
// None,
// )
// // todo!()
// }))
// // cx.render(rsx! {
// // div {
// // div {
// // {a}
// // // {p}
// // // {g}
// // // {f}
// // }
// // // div {
// // // "asd"
// // // div {
// // // "asd"
// // // }
// // // }
// // // Child {
// // // foo: "asd".to_string(),
// // // }
// // Child2 {
// // foo: s,
// // }
// // }
// // })
// }
f.raw_element( // fn Child((cx, props): Scope<OurProps>) -> Element {
"div", // cx.render(rsx! {
None, // div {
[], // div {}
[], // }
[ // })
// // }
f.fragment_from_iter(a),
f.fragment_from_iter(b),
f.fragment_from_iter(c),
f.fragment_from_iter(e),
],
None,
)
// todo!()
}))
// cx.render(rsx! {
// div {
// div {
// {a}
// // {p}
// // {g}
// // {f}
// }
// // div {
// // "asd"
// // div {
// // "asd"
// // }
// // }
// // Child {
// // foo: "asd".to_string(),
// // }
// Child2 {
// foo: s,
// }
// }
// })
}
fn Child((cx, props): Scope<OurProps>) -> Element {
cx.render(rsx! {
div {
div {}
}
})
}
#[derive(Props)] #[derive(Props)]
struct Child2Props<'a> { struct Child2Props<'a> {
@@ -221,9 +222,114 @@ struct Child2Props<'a> {
} }
fn Child2<'a>((cx, props): Scope<'a, Child2Props>) -> Element<'a> { fn Child2<'a>((cx, props): Scope<'a, Child2Props>) -> Element<'a> {
let node = cx
.render(rsx! {
div {
}
})
.unwrap();
let b = cx.bump();
let node: &'a VNode<'a> = b.alloc(node);
let children = ChildList { pthru: node };
// let c = VComponent {
// key: todo!(),
// associated_scope: todo!(),
// is_static: todo!(),
// user_fc: todo!(),
// caller: todo!(),
// children: todo!(),
// comparator: todo!(),
// drop_props: todo!(),
// can_memoize: todo!(),
// raw_props: todo!(),
// };
// Vcomp
// - borrowed
// - memoized
cx.render({
NodeFactory::annotate_lazy(move |__cx: NodeFactory| -> VNode {
use dioxus_elements::{GlobalAttributes, SvgAttributes};
__cx.element(
dioxus_elements::div,
[],
[],
[],
// [__cx.component(
// ChildrenComp,
// {
// let mut __manual_props = ChildrenTest { node: children };
// __manual_props
// },
// None,
// [],
// )],
None,
)
})
})
// cx.render(rsx! {
// div {
// // div {}
// ChildrenComp {
// // node: children
// ..ChildrenTest {
// node: children,
// }
// }
// }
// })
}
#[derive(Props)]
struct ChildrenTest<'a> {
node: ChildList<'a>,
}
struct ChildList<'a> {
pthru: &'a VNode<'a>,
}
impl<'a> Clone for ChildList<'a> {
fn clone(&self) -> Self {
Self { pthru: self.pthru }
}
}
impl<'a> Copy for ChildList<'a> {}
impl<'a> IntoVNode<'a> for ChildList<'a> {
fn into_vnode(self, _: NodeFactory<'a>) -> VNode<'a> {
match self.pthru {
VNode::Text(f) => VNode::Text(*f),
VNode::Element(e) => VNode::Element(*e),
VNode::Component(c) => VNode::Component(*c),
VNode::Suspended(s) => VNode::Suspended(*s),
VNode::Anchor(a) => VNode::Anchor(a),
VNode::Fragment(f) => VNode::Fragment(VFragment {
children: f.children,
is_static: f.is_static,
key: f.key,
}),
}
}
}
fn ChildrenComp<'a>((cx, props): Scope<'a, ChildrenTest<'a>>) -> Element<'a> {
cx.render(rsx! { cx.render(rsx! {
div { div {
// div {} div {
// if the node's id is already assigned, then it's being passed in as a child
// in these instances, we don't worry about re-checking the node?
{Some(props.node)}
}
} }
}) })
} }
+15 -4
View File
@@ -21,16 +21,27 @@ pub(crate) struct BumpFrame {
impl ActiveFrame { impl ActiveFrame {
pub fn new() -> Self { pub fn new() -> Self {
let b1 = Bump::new();
let b2 = Bump::new();
let frame_a = BumpFrame { let frame_a = BumpFrame {
bump: Bump::new(), head_node: VNode::Fragment(VFragment {
head_node: NodeFactory::unstable_place_holder(), key: None,
children: &[],
is_static: false,
}),
bump: b1,
#[cfg(test)] #[cfg(test)]
_name: "wip", _name: "wip",
}; };
let frame_b = BumpFrame { let frame_b = BumpFrame {
bump: Bump::new(), head_node: VNode::Fragment(VFragment {
head_node: NodeFactory::unstable_place_holder(), key: None,
children: &[],
is_static: false,
}),
bump: b2,
#[cfg(test)] #[cfg(test)]
_name: "fin", _name: "fin",
+7
View File
@@ -4,6 +4,8 @@
//! //!
//! We unsafely implement `send` for the VirtualDom, but those guarantees can only be //! We unsafely implement `send` for the VirtualDom, but those guarantees can only be
use bumpalo::Bump;
use crate::innerlude::*; use crate::innerlude::*;
use std::{any::TypeId, ops::Deref, rc::Rc}; use std::{any::TypeId, ops::Deref, rc::Rc};
@@ -122,6 +124,11 @@ impl<'src> Context<'src> {
self.scope.our_arena_idx self.scope.our_arena_idx
} }
pub fn bump(&self) -> &'src Bump {
let bump = &self.scope.frames.wip_frame().bump;
bump
}
/// Take a lazy VNode structure and actually build it with the context of the VDom's efficient VNode allocator. /// Take a lazy VNode structure and actually build it with the context of the VDom's efficient VNode allocator.
/// ///
/// This function consumes the context and absorb the lifetime, so these VNodes *must* be returned. /// This function consumes the context and absorb the lifetime, so these VNodes *must* be returned.
+5
View File
@@ -421,6 +421,10 @@ impl<'bump> DiffMachine<'bump> {
) => self ) => self
.stack .stack
.create_node(new_node, MountType::Replace { old: old_node }), .create_node(new_node, MountType::Replace { old: old_node }),
(Placeholder, _) | (_, Placeholder) => {
unreachable!("placeholder should never be diffed");
}
} }
} }
@@ -1125,6 +1129,7 @@ impl<'bump> DiffMachine<'bump> {
self.remove_nodes(e.children, false); self.remove_nodes(e.children, false);
} }
VNode::Fragment(f) => { VNode::Fragment(f) => {
self.remove_nodes(f.children, gen_muts); self.remove_nodes(f.children, gen_muts);
} }
+11 -12
View File
@@ -10,7 +10,6 @@ use bumpalo::{boxed::Box as BumpBox, Bump};
use std::{ use std::{
cell::{Cell, RefCell}, cell::{Cell, RefCell},
fmt::{Arguments, Debug, Formatter}, fmt::{Arguments, Debug, Formatter},
marker::PhantomData,
}; };
/// A composable "VirtualNode" to declare a User Interface in the Dioxus VirtualDOM. /// A composable "VirtualNode" to declare a User Interface in the Dioxus VirtualDOM.
@@ -33,7 +32,7 @@ pub enum VNode<'src> {
/// assert_eq!(vtext.is_static, true); /// assert_eq!(vtext.is_static, true);
/// } /// }
/// ``` /// ```
Text(VText<'src>), Text(&'src VText<'src>),
/// Element VNodes are VNodes that may contain attributes, listeners, a key, a tag, and children. /// Element VNodes are VNodes that may contain attributes, listeners, a key, a tag, and children.
/// ///
@@ -116,7 +115,7 @@ pub enum VNode<'src> {
/// assert_eq!(root, VNode::Anchor); /// assert_eq!(root, VNode::Anchor);
/// } /// }
/// ``` /// ```
Anchor(VAnchor), Anchor(&'src VAnchor),
} }
impl<'src> VNode<'src> { impl<'src> VNode<'src> {
@@ -328,21 +327,21 @@ impl<'a> NodeFactory<'a> {
self.bump self.bump
} }
pub fn unstable_place_holder() -> VNode<'static> { pub(crate) fn unstable_place_holder(&self) -> VNode {
VNode::Text(VText { VNode::Text(self.bump.alloc(VText {
text: "", text: "",
dom_id: empty_cell(), dom_id: empty_cell(),
is_static: true, is_static: true,
}) }))
} }
/// Directly pass in text blocks without the need to use the format_args macro. /// Directly pass in text blocks without the need to use the format_args macro.
pub fn static_text(&self, text: &'static str) -> VNode<'a> { pub fn static_text(&self, text: &'static str) -> VNode<'a> {
VNode::Text(VText { VNode::Text(self.bump.alloc(VText {
dom_id: empty_cell(), dom_id: empty_cell(),
text, text,
is_static: true, is_static: true,
}) }))
} }
/// Parses a lazy text Arguments and returns a string and a flag indicating if the text is 'static /// Parses a lazy text Arguments and returns a string and a flag indicating if the text is 'static
@@ -365,11 +364,11 @@ impl<'a> NodeFactory<'a> {
pub fn text(&self, args: Arguments) -> VNode<'a> { pub fn text(&self, args: Arguments) -> VNode<'a> {
let (text, is_static) = self.raw_text(args); let (text, is_static) = self.raw_text(args);
VNode::Text(VText { VNode::Text(self.bump.alloc(VText {
text, text,
is_static, is_static,
dom_id: empty_cell(), dom_id: empty_cell(),
}) }))
} }
pub fn element<L, A, V>( pub fn element<L, A, V>(
@@ -556,9 +555,9 @@ impl<'a> NodeFactory<'a> {
} }
if nodes.is_empty() { if nodes.is_empty() {
nodes.push(VNode::Anchor(VAnchor { nodes.push(VNode::Anchor(bump.alloc(VAnchor {
dom_id: empty_cell(), dom_id: empty_cell(),
})); })));
} }
let children = nodes.into_bump_slice(); let children = nodes.into_bump_slice();