wip: worked backwards a bit and got it slightly figured out

This commit is contained in:
Jonathan Kelley committed 2021-10-30 17:11:15 -04:00
1 parent ba9e1dbb8f
commit 9ee2bfb010
10 files changed
+322 -147

No files matched your search

+14 -4
View File
@@ -57,11 +57,21 @@ impl ToTokens for CallBody {
}), }),
// Otherwise we just build the LazyNode wrapper // Otherwise we just build the LazyNode wrapper
None => out_tokens.append_all(quote! { None => out_tokens.append_all(quote! {
dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{
use dioxus_elements::{GlobalAttributes, SvgAttributes};
#inner {
})
let ___p: Box<dyn FnOnce(NodeFactory) -> VNode + '_> = Box::new(move |__cx: NodeFactory|{
use dioxus_elements::{GlobalAttributes, SvgAttributes};
#inner
});
Some(___p)
}
// dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{
// use dioxus_elements::{GlobalAttributes, SvgAttributes};
// #inner
// })
}), }),
}; };
} }
+11 -11
View File
@@ -41,22 +41,22 @@ struct RowProps {
label: Label, label: Label,
} }
fn Row((cx, props): Scope<RowProps>) -> Element { fn Row<'a>((cx, props): Scope<'a, RowProps>) -> Element<'a> {
let handler = move |evt: MouseEvent| { let handler = move |evt: MouseEvent| {
let g = evt.button; let g = evt.button;
}; };
cx.render(rsx! { cx.render(rsx! {
tr { tr {
td { class:"col-md-1", "{props.row_id}" } // td { class:"col-md-1", "{props.row_id}" }
td { class:"col-md-1", onclick: move |_| { /* run onselect */ } // td { class:"col-md-1", onclick: move |_| { /* run onselect */ }
a { class: "lbl", "{props.label}" } // a { class: "lbl", "{props.label}" }
} // }
td { class: "col-md-1" // td { class: "col-md-1"
a { class: "remove", onclick: {handler} // a { class: "remove", onclick: {handler}
span { class: "glyphicon glyphicon-remove remove" aria_hidden: "true" } // span { class: "glyphicon glyphicon-remove remove" aria_hidden: "true" }
} // }
} // }
td { class: "col-md-6" } // td { class: "col-md-6" }
} }
}) })
} }
+43 -9
View File
@@ -57,10 +57,11 @@ fn App3((cx, props): Scope<()>) -> Element {
bame: 10, bame: 10,
} }
}; };
cx.render(rsx!(Child { todo!()
bame: 102, // cx.render(rsx!(Child {
..ChildProps { bame: 10 } // bame: 102,
})) // ..ChildProps { bame: 10 }
// }))
} }
#[derive(Props, PartialEq, Debug)] #[derive(Props, PartialEq, Debug)]
@@ -97,11 +98,11 @@ impl<'a> Children<'a> {
} }
} }
} }
impl<'a> IntoVNodeList<'a> for &Children<'a> { // impl<'a> IntoVNodeList<'a> for &Children<'a> {
fn into_vnode_list(self, cx: NodeFactory<'a>) -> &'a [VNode<'a>] { // fn into_vnode_list(self, cx: NodeFactory<'a>) -> &'a [VNode<'a>] {
todo!() // todo!()
} // }
} // }
static Bapp: FC<()> = |(cx, props)| { static Bapp: FC<()> = |(cx, props)| {
let name = cx.use_state(|| 0); let name = cx.use_state(|| 0);
@@ -117,3 +118,36 @@ static Bapp: FC<()> = |(cx, props)| {
} }
)) ))
}; };
static Match: FC<()> = |(cx, props)| {
//
let b: Box<dyn Fn(NodeFactory) -> VNode> = Box::new(|f| todo!());
let b = match "ag" {
"a" => {
let __b: Box<dyn FnOnce(NodeFactory) -> VNode> = Box::new(|f: NodeFactory| todo!());
__b
}
_ => {
let __b: Box<dyn FnOnce(NodeFactory) -> VNode> = Box::new(|f: NodeFactory| todo!());
__b
}
};
// let b: Box<dyn Fn(NodeFactory) -> VNode> = match "alph" {
// "beta" => Box::new(|f: NodeFactory| {
// //
// todo!()
// }),
// _ => Box::new(|f: NodeFactory| {
// //
// todo!()
// }),
// };
cx.render(rsx! {
div {
}
})
};
+71
View File
@@ -0,0 +1,71 @@
use std::marker::PhantomData;
use dioxus::component::Scope;
use dioxus::events::on::MouseEvent;
use dioxus::nodes::{IntoVNode, IntoVNodeList};
use dioxus_core as dioxus;
use dioxus_core::prelude::*;
use dioxus_core_macro::*;
use dioxus_html as dioxus_elements;
fn main() {}
fn t() {
let g = rsx! {
div {
div {
}
}
};
let g = {
let ___p: Box<dyn FnOnce(NodeFactory) -> VNode> = Box::new(|__cx: NodeFactory| {
use dioxus_elements::{GlobalAttributes, SvgAttributes};
__cx.element(dioxus_elements::div, [], [], [], None)
});
// let __z = ___p as ;
// __z
};
}
fn App((cx, props): Scope<()>) -> Element {
let a = rsx! {
div {
"asd"
}
};
let p = (0..10).map(|f| {
rsx! {
div {
}
}
});
let g = match "text" {
"a" => rsx!("asd"),
b => rsx!("asd"),
};
let items = ["bob", "bill", "jack"];
let f = items
.iter()
.filter(|f| f.starts_with('b'))
.map(|f| rsx!("hello {f}"));
cx.render(rsx! {
div {
div {
{a}
{p}
{g}
{f}
}
}
})
}
// std::boxed::Box<dyn for<'r> std::ops::FnOnce(dioxus_core::NodeFactory<'r>) -> dioxus_core::VNode<'_>>
+6 -3
View File
@@ -7,7 +7,7 @@
use crate::{ use crate::{
innerlude::{Context, Element, LazyNodes, FC}, innerlude::{Context, Element, LazyNodes, FC},
VNode, NodeFactory, VNode,
}; };
/// A component is a wrapper around a Context and some Props that share a lifetime /// A component is a wrapper around a Context and some Props that share a lifetime
@@ -66,8 +66,11 @@ pub type Scope<'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. /// 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)] #[allow(non_upper_case_globals, non_snake_case)]
pub fn Fragment((cx, _): Scope<()>) -> Element { pub fn Fragment<'a>((cx, _): Scope<'a, ()>) -> Element<'a> {
cx.render(LazyNodes::new(move |f| f.fragment_from_iter(cx.children()))) todo!()
// let p: Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_> =
// Box::new(|f: NodeFactory| f.fragment_from_iter(cx.children()));
// cx.render(p)
} }
/// Every "Props" used for a component must implement the `Properties` trait. This trait gives some hints to Dioxus /// Every "Props" used for a component must implement the `Properties` trait. This trait gives some hints to Dioxus
+21 -3
View File
@@ -137,12 +137,30 @@ impl<'src> Context<'src> {
/// cx.render(lazy_tree) /// cx.render(lazy_tree)
/// } /// }
///``` ///```
pub fn render<F: FnOnce(NodeFactory<'src>) -> VNode<'src>>( pub fn render(
self, self,
lazy_nodes: LazyNodes<'src, F>, lazy_nodes: Option<LazyNodes<'_>>,
// lazy_nodes: Box<dyn FnOnce(NodeFactory<'src>) -> VNode<'src> + '_>,
) -> Option<VNode<'src>> { ) -> Option<VNode<'src>> {
// pub fn render<F: FnOnce(NodeFactory<'src>) -> VNode<'src>>(
// self,
// lazy_nodes: LazyNodes<'src, F>,
// ) -> Option<VNode<'src>> {
let bump = &self.scope.frames.wip_frame().bump; let bump = &self.scope.frames.wip_frame().bump;
Some(lazy_nodes.into_vnode(NodeFactory { bump })) // Some(lazy_nodes.into_vnode(NodeFactory { bump }))
let factory = NodeFactory { bump };
// let vnode = lazy_nodes(factory);
match lazy_nodes {
Some(f) => Some(f(factory)),
None => None,
}
// match lazy_nodes {
// None => todo!(),
// }
// Some(lazy_nodes)
} }
/// `submit_task` will submit the future to be polled. /// `submit_task` will submit the future to be polled.
+4 -2
View File
@@ -181,9 +181,11 @@ pub struct SuspendedContext<'a> {
impl<'src> SuspendedContext<'src> { impl<'src> SuspendedContext<'src> {
// pub fn render( // pub fn render(
pub fn render<F: FnOnce(NodeFactory<'src>) -> VNode<'src>>( pub fn render(
// pub fn render<F: FnOnce(NodeFactory<'src>) -> VNode<'src>>(
self, self,
lazy_nodes: LazyNodes<'src, F>, lazy_nodes: LazyNodes<'_>,
// lazy_nodes: LazyNodes<'src, '_>,
) -> Element<'src> { ) -> Element<'src> {
let bump = &self.inner.scope.frames.wip_frame().bump; let bump = &self.inner.scope.frames.wip_frame().bump;
todo!("suspense") todo!("suspense")
+71 -66
View File
@@ -26,12 +26,13 @@ use crate::innerlude::{IntoVNode, NodeFactory, VNode};
/// ```rust /// ```rust
/// LazyNodes::new(|f| f.element("div", [], [], [] None)) /// LazyNodes::new(|f| f.element("div", [], [], [] None))
/// ``` /// ```
pub struct LazyNodes<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> { // pub struct LazyNodes<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> {
inner: Box<F>, // inner: Box<F>,
_p: PhantomData<&'a ()>, // _p: PhantomData<&'a ()>,
// inner: StackNodeStorage<'a>, // // inner: StackNodeStorage<'a>,
// inner: StackNodeStorage<'a>, // // inner: StackNodeStorage<'a>,
} // }
pub type LazyNodes<'b> = Box<dyn for<'a> FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>;
type StackHeapSize = [usize; 12]; type StackHeapSize = [usize; 12];
@@ -44,70 +45,74 @@ enum StackNodeStorage<'a> {
Heap(Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a>>), Heap(Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a>>),
} }
impl<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> LazyNodes<'a, F> { // impl<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> LazyNodes<'a, F> {
pub fn new(f: F) -> Self { // pub fn new(f: F) -> Self {
// let width = std::mem?::size_of::<F>(); // // let width = std::mem?::size_of::<F>();
// let b: Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a>> = Box::new(f); // // let b: Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a>> = Box::new(f);
todo!() // todo!()
// Self { inner: b } // // Self { inner: b }
// todo!() // // todo!()
// if width > std::mem::size_of::<StackHeapSize>() { // // if width > std::mem::size_of::<StackHeapSize>() {
// let g: Box<dyn for<'b> FnOnce(NodeFactory<'b>) -> VNode<'b> + 'g> = Box::new(f); // // let g: Box<dyn for<'b> FnOnce(NodeFactory<'b>) -> VNode<'b> + 'g> = Box::new(f);
// LazyNodes { // // LazyNodes {
// inner: StackNodeStorage::Heap(g), // // inner: StackNodeStorage::Heap(g),
// } // // }
// } else { // // } else {
// let mut buf = [0; 12]; // // let mut buf = [0; 12];
// let mut next_ofs = 0; // // let mut next_ofs = 0;
// next_ofs += 1; // // next_ofs += 1;
// LazyNodes { // // LazyNodes {
// inner: StackNodeStorage::Stack { // // inner: StackNodeStorage::Stack {
// next_ofs, // // next_ofs,
// buf, // // buf,
// width, // // width,
// }, // // },
// } // // }
// } // // }
} // }
} // }
// Our blanket impl // // Our blanket impl
impl<'a, F> IntoIterator for LazyNodes<'a, F> // impl<'a> IntoIterator for LazyNodes<'a>
where // // where
F: FnOnce(NodeFactory<'a>) -> VNode<'a>, // // F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
{ // // impl<'a, F> IntoIterator for LazyNodes<'a, F>
type Item = Self; // // where
type IntoIter = std::iter::Once<Self::Item>; // // F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
fn into_iter(self) -> Self::IntoIter { // {
std::iter::once(self) // type Item = Self;
} // type IntoIter = std::iter::Once<Self::Item>;
} // fn into_iter(self) -> Self::IntoIter {
// std::iter::once(self)
// }
// }
// Our blanket impl // // Our blanket impl
impl<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> IntoVNode<'a> for LazyNodes<'a, F> { // impl IntoVNode for LazyNodes<'_> {
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> { // // impl<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> IntoVNode<'a> for LazyNodes<'a, F> {
todo!() // fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
// match self.inner { // todo!()
// StackNodeStorage::Stack { // // match self.inner {
// buf, // // StackNodeStorage::Stack {
// next_ofs, // // buf,
// width, // // next_ofs,
// } => { // // width,
// // get the start of the allocation // // } => {
// let r = &buf[0]; // // // get the start of the allocation
// // let r = &buf[0];
// // recast the allocation as dyn FnOnce // // // recast the allocation as dyn FnOnce
// // pretend the FnOnce is box // // // pretend the FnOnce is box
// let g: Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a>> = todo!(); // // let g: Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a>> = todo!();
// // Box::from_raw(r as *const usize as *mut dyn FnOnce(NodeFactory<'a>)); // // // Box::from_raw(r as *const usize as *mut dyn FnOnce(NodeFactory<'a>));
// // use Box's ability to act as FnOnce // // // use Box's ability to act as FnOnce
// g(cx) // // g(cx)
// } // // }
// StackNodeStorage::Heap(b) => b(cx), // // StackNodeStorage::Heap(b) => b(cx),
// } // // }
} // }
} // }
+76 -46
View File
@@ -329,12 +329,19 @@ impl<'a> NodeFactory<'a> {
self.bump self.bump
} }
pub fn render_directly<F>(&self, lazy_nodes: LazyNodes<'a, F>) -> Element<'a> pub fn render_directly(&self, lazy_nodes: LazyNodes<'_>) -> Element<'a>
where // pub fn render_directly(&self, lazy_nodes: LazyNodes<'a, '_>) -> Element<'a>
F: FnOnce(NodeFactory<'a>) -> VNode<'a>, // where
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
{ {
// pub fn render_directly<F>(&self, lazy_nodes: LazyNodes<'a, F>) -> Element<'a>
// where
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
// {
// pub fn render_directly<F>(&self, lazy_nodes: LazyNodes<'a>) -> Option<VNode<'a>> { // pub fn render_directly<F>(&self, lazy_nodes: LazyNodes<'a>) -> Option<VNode<'a>> {
Some(lazy_nodes.into_vnode(NodeFactory { bump: self.bump })) // Some(lazy_nodes.into_vnode(NodeFactory { bump: self.bump }))
todo!()
} }
pub fn unstable_place_holder() -> VNode<'static> { pub fn unstable_place_holder() -> VNode<'static> {
@@ -552,7 +559,7 @@ impl<'a> NodeFactory<'a> {
})) }))
} }
pub fn fragment_from_iter(self, node_iter: impl IntoVNodeList<'a>) -> VNode<'a> { pub fn fragment_from_iter(self, node_iter: impl IntoVNodeList) -> VNode<'a> {
let children = node_iter.into_vnode_list(self); let children = node_iter.into_vnode_list(self);
// TODO // TODO
@@ -597,20 +604,20 @@ impl<'a> NodeFactory<'a> {
/// ///
/// As such, all node creation must go through the factory, which is only available in the component context. /// As such, all node creation must go through the factory, which is only available in the component context.
/// These strict requirements make it possible to manage lifetimes and state. /// These strict requirements make it possible to manage lifetimes and state.
pub trait IntoVNode<'a> { pub trait IntoVNode {
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a>; fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a>;
} }
pub trait IntoVNodeList<'a> { pub trait IntoVNodeList {
fn into_vnode_list(self, cx: NodeFactory<'a>) -> &'a [VNode<'a>]; fn into_vnode_list<'a>(self, cx: NodeFactory<'a>) -> &'a [VNode<'a>];
} }
impl<'a, T, V> IntoVNodeList<'a> for T impl<T, V> IntoVNodeList for T
where where
T: IntoIterator<Item = V>, T: IntoIterator<Item = V>,
V: IntoVNode<'a>, V: IntoVNode,
{ {
fn into_vnode_list(self, cx: NodeFactory<'a>) -> &'a [VNode<'a>] { fn into_vnode_list<'a>(self, cx: NodeFactory<'a>) -> &'a [VNode<'a>] {
let mut nodes = bumpalo::collections::Vec::new_in(cx.bump()); let mut nodes = bumpalo::collections::Vec::new_in(cx.bump());
for node in self.into_iter() { for node in self.into_iter() {
@@ -662,11 +669,11 @@ impl ScopeChildren<'_> {
} }
} }
impl<'a> IntoVNodeList<'a> for ScopeChildren<'a> { // impl IntoVNodeList for ScopeChildren<'_> {
fn into_vnode_list(self, _: NodeFactory<'a>) -> &'a [VNode<'a>] { // fn into_vnode_list<'a>(self, _: NodeFactory<'a>) -> &'a [VNode<'a>] {
self.0 // self.0
} // }
} // }
// For the case where a rendered VNode is passed into the rsx! macro through curly braces // For the case where a rendered VNode is passed into the rsx! macro through curly braces
impl<'a> IntoIterator for VNode<'a> { impl<'a> IntoIterator for VNode<'a> {
@@ -677,51 +684,74 @@ impl<'a> IntoIterator for VNode<'a> {
} }
} }
// For the case where a rendered VNode is passed into the rsx! macro through curly braces // // For the case where a rendered VNode is passed into the rsx! macro through curly braces
impl<'a> IntoVNode<'a> for VNode<'a> { // impl IntoVNode for VNode<'_> {
fn into_vnode(self, _: NodeFactory<'a>) -> VNode<'a> { // fn into_vnode<'a>(self, _: NodeFactory<'a>) -> VNode<'a> {
self // self
} // }
} // }
// Conveniently, we also support "null" (nothing) passed in // Conveniently, we also support "null" (nothing) passed in
impl IntoVNode<'_> for () { // impl IntoVNode for () {
fn into_vnode(self, cx: NodeFactory) -> VNode { // fn into_vnode(self, cx: NodeFactory) -> VNode {
cx.fragment_from_iter(None as Option<VNode>) // cx.fragment_from_iter(None as Option<VNode>)
} // }
} // }
// Conveniently, we also support "None" // // Conveniently, we also support "None"
impl IntoVNode<'_> for Option<()> { // impl IntoVNode for Option<()> {
fn into_vnode(self, cx: NodeFactory) -> VNode { // fn into_vnode(self, cx: NodeFactory) -> VNode {
cx.fragment_from_iter(None as Option<VNode>) // cx.fragment_from_iter(None as Option<VNode>)
} // }
} // }
impl<'a> IntoVNode<'a> for Option<VNode<'a>> { // impl IntoVNode for Option<VNode<'_>> {
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> { // fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
// match self {
// Some(n) => n,
// None => cx.fragment_from_iter(None as Option<VNode>),
// }
// }
// }
impl IntoVNode for Option<Box<dyn for<'r> FnOnce(NodeFactory<'r>) -> VNode<'_> + '_>> {
fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
match self { match self {
Some(n) => n, Some(n) => {
None => cx.fragment_from_iter(None as Option<VNode>), //
// n.into_vnode(cx)
n(cx)
}
None => VNode::Fragment(VFragment {
children: &[],
is_static: false,
key: None,
}),
} }
} }
} }
impl<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> IntoVNode<'a> for Option<LazyNodes<'a, F>> { impl IntoVNode for Box<dyn for<'r> FnOnce(NodeFactory<'r>) -> VNode<'_> + '_> {
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> { fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
match self { self(cx)
Some(n) => n.into_vnode(cx),
None => cx.fragment_from_iter(None as Option<VNode>),
}
} }
} }
impl IntoVNode<'_> for &'static str { // impl<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> IntoVNode<'a> for Option<LazyNodes<'a, F>> {
// 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<VNode>),
// }
// }
// }
impl IntoVNode for &'static str {
fn into_vnode(self, cx: NodeFactory) -> VNode { fn into_vnode(self, cx: NodeFactory) -> VNode {
cx.static_text(self) cx.static_text(self)
} }
} }
impl IntoVNode<'_> for Arguments<'_> { impl IntoVNode for Arguments<'_> {
fn into_vnode(self, cx: NodeFactory) -> VNode { fn into_vnode(self, cx: NodeFactory) -> VNode {
cx.text(self) cx.text(self)
} }
+5 -3
View File
@@ -25,15 +25,17 @@ impl TestDom {
// where // where
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>, // F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
{ {
lazy_nodes.into_vnode(NodeFactory::new(&self.bump)) todo!()
// lazy_nodes.into_vnode(NodeFactory::new(&self.bump))
} }
pub fn render<'a>(&'a self, lazy_nodes: Element<'a>) -> &'a VNode<'a> pub fn render<'a>(&'a self, lazy_nodes: Element<'a>) -> &'a VNode<'a>
// where // where
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>, // F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
{ {
self.bump todo!()
.alloc(lazy_nodes.into_vnode(NodeFactory::new(&self.bump))) // self.bump
// .alloc(lazy_nodes.into_vnode(NodeFactory::new(&self.bump)))
} }
pub fn diff<'a>(&'a self, old: &'a VNode<'a>, new: &'a VNode<'a>) -> Mutations<'a> { pub fn diff<'a>(&'a self, old: &'a VNode<'a>, new: &'a VNode<'a>) -> Mutations<'a> {