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"] }
simple_logger = "1.13.0"
dioxus-core-macro = { path = "../core-macro", version = "0.1.2" }
async-std = { version = "1.9.0", features = ["attributes"] }
criterion = "0.3.5"
# async-std = { version = "1.9.0", features = ["attributes"] }
# criterion = "0.3.5"
[features]
default = []
+272 -166
View File
@@ -1,8 +1,10 @@
use std::borrow::BorrowMut;
use std::cell::{Cell, RefCell};
use std::marker::PhantomData;
use dioxus::component::Scope;
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::prelude::*;
use dioxus_core_macro::*;
@@ -29,191 +31,190 @@ fn t() {
};
}
#[derive(PartialEq, Props)]
struct OurProps {
foo: String,
}
// #[derive(PartialEq, Props)]
// struct OurProps {
// foo: String,
// }
fn App<'a>((cx, props): Scope<'a, OurProps>) -> Element<'a> {
let a = rsx! {
div {
"asd"
"{props.foo}"
}
};
// fn App<'a>((cx, props): Scope<'a, OurProps>) -> Element<'a> {
// let a = rsx! {
// div {
// "asd"
// "{props.foo}"
// }
// };
let p = (0..10).map(|f| {
rsx! {
div {
// let p = (0..10).map(|f| {
// rsx! {
// div {
}
}
});
// }
// }
// });
let g = match "text" {
"a" => {
rsx!("asd")
}
_ => {
rsx!("asd")
}
};
// let g = match "text" {
// "a" => {
// rsx!("asd")
// }
// _ => {
// rsx!("asd")
// }
// };
let items = ["bob", "bill", "jack"];
// let items = ["bob", "bill", "jack"];
let f = items
.iter()
.filter(|f| f.starts_with('b'))
.map(|f| rsx!("hello {f}"));
// let f = items
// .iter()
// .filter(|f| f.starts_with('b'))
// .map(|f| rsx!("hello {f}"));
// use dioxus_hooks;
// let g = use_state(|| "hello".to_string());
// // use dioxus_hooks;
// // 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 p: Option<Box<dyn FnOnce(_) -> _>> = Some(Box::new(move |__cx: NodeFactory| {
// use dioxus_elements::{GlobalAttributes, SvgAttributes};
// // let props = Child2Props { foo: s };
// // let ch: VNode = __cx.component(Child2, props, None, []);
// // __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 ch: VNode = __cx.component(Child2, props, None, []);
// __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 ch: VNode = __cx.component(Child2, props, None, []);
// // // __cx.element(
// // // dioxus_elements::div,
// // // [],
// // // [],
// // // [ch],
// // // // [__cx.component(Child2, fc_to_builder(Child2).foo(s).build(), None, [])],
// // // None,
// // // )
// // // });
// // // Some(___p)
// // })
// // let props = Child2Props { foo: s };
// // let ch: VNode = __cx.component(Child2, props, None, []);
// // __cx.element(
// // dioxus_elements::div,
// // [],
// // [],
// // [ch],
// // // [__cx.component(Child2, fc_to_builder(Child2).foo(s).build(), None, [])],
// // None,
// // )
// // });
// // Some(___p)
// })
// let a = annotate_lazy(move |f| {
// //
// todo!()
// });
// let b = annotate_lazy(move |f| {
// //
// f.text(format_args!("{}", props.foo))
// });
let a = annotate_lazy(move |f| {
//
todo!()
});
let b = annotate_lazy(move |f| {
//
f.text(format_args!("{}", props.foo))
});
// let c = annotate_lazy(move |f| {
// //
// f.component(
// Child,
// OurProps {
// //
// foo: "hello".to_string(),
// },
// None,
// [],
// )
// });
let c = annotate_lazy(move |f| {
//
f.component(
Child,
OurProps {
//
foo: "hello".to_string(),
},
None,
[],
)
});
// let st: &'a String = cx.use_hook(|_| "hello".to_string(), |f| f, |_| {});
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| {
//
f.component(
Child2,
Child2Props {
//
foo: st,
},
None,
[],
)
});
// let e = match "asd" {
// b => {
// //
let e = match "asd" {
b => {
//
// annotate_lazy(move |f| {
// //
// f.text(format_args!("{}", props.foo))
// })
// }
// a => {
// //
annotate_lazy(move |f| {
//
f.text(format_args!("{}", props.foo))
})
}
a => {
//
// annotate_lazy(move |f| {
// //
// f.text(format_args!("{}", props.foo))
// })
// }
// };
annotate_lazy(move |f| {
//
f.text(format_args!("{}", props.foo))
})
}
};
// cx.render(annotate_lazy(move |f| {
// //
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(
"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,
// }
// }
// })
}
fn Child((cx, props): Scope<OurProps>) -> Element {
cx.render(rsx! {
div {
div {}
}
})
}
// fn Child((cx, props): Scope<OurProps>) -> Element {
// cx.render(rsx! {
// div {
// div {}
// }
// })
// }
#[derive(Props)]
struct Child2Props<'a> {
@@ -221,9 +222,114 @@ struct Child2Props<'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! {
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 {
pub fn new() -> Self {
let b1 = Bump::new();
let b2 = Bump::new();
let frame_a = BumpFrame {
bump: Bump::new(),
head_node: NodeFactory::unstable_place_holder(),
head_node: VNode::Fragment(VFragment {
key: None,
children: &[],
is_static: false,
}),
bump: b1,
#[cfg(test)]
_name: "wip",
};
let frame_b = BumpFrame {
bump: Bump::new(),
head_node: NodeFactory::unstable_place_holder(),
head_node: VNode::Fragment(VFragment {
key: None,
children: &[],
is_static: false,
}),
bump: b2,
#[cfg(test)]
_name: "fin",
+7
View File
@@ -4,6 +4,8 @@
//!
//! We unsafely implement `send` for the VirtualDom, but those guarantees can only be
use bumpalo::Bump;
use crate::innerlude::*;
use std::{any::TypeId, ops::Deref, rc::Rc};
@@ -122,6 +124,11 @@ impl<'src> Context<'src> {
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.
///
/// 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
.stack
.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);
}
VNode::Fragment(f) => {
self.remove_nodes(f.children, gen_muts);
}
+11 -12
View File
@@ -10,7 +10,6 @@ use bumpalo::{boxed::Box as BumpBox, Bump};
use std::{
cell::{Cell, RefCell},
fmt::{Arguments, Debug, Formatter},
marker::PhantomData,
};
/// 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);
/// }
/// ```
Text(VText<'src>),
Text(&'src VText<'src>),
/// 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);
/// }
/// ```
Anchor(VAnchor),
Anchor(&'src VAnchor),
}
impl<'src> VNode<'src> {
@@ -328,21 +327,21 @@ impl<'a> NodeFactory<'a> {
self.bump
}
pub fn unstable_place_holder() -> VNode<'static> {
VNode::Text(VText {
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(VText {
VNode::Text(self.bump.alloc(VText {
dom_id: empty_cell(),
text,
is_static: true,
})
}))
}
/// 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> {
let (text, is_static) = self.raw_text(args);
VNode::Text(VText {
VNode::Text(self.bump.alloc(VText {
text,
is_static,
dom_id: empty_cell(),
})
}))
}
pub fn element<L, A, V>(
@@ -556,9 +555,9 @@ impl<'a> NodeFactory<'a> {
}
if nodes.is_empty() {
nodes.push(VNode::Anchor(VAnchor {
nodes.push(VNode::Anchor(bump.alloc(VAnchor {
dom_id: empty_cell(),
}));
})));
}
let children = nodes.into_bump_slice();