Feat: building large apps, revamp macro
This commit is contained in:
1 parent
5791e49700
commit
9f7f43b661
20 files changed
+386
-293
No files matched your search
@@ -1,93 +1,17 @@
|
||||
// //! An alternative function syntax
|
||||
// //!
|
||||
|
||||
// use bumpalo::Bump;
|
||||
// use dioxus_core::prelude::VNode;
|
||||
|
||||
fn main() {}
|
||||
|
||||
// struct Context2<'a, P> {
|
||||
// _props: &'a P, // _p: PhantomData<&'a ()>,
|
||||
// rops: &'a P, // _p: PhantomData<&'a ()>,
|
||||
// }
|
||||
// impl<'a, P> Context2<'a, P> {
|
||||
// fn render(self, _f: impl FnOnce(&'a Bump) -> VNode<'a>) -> DTree {
|
||||
// DTree {}
|
||||
// }
|
||||
use dioxus_core::prelude::*;
|
||||
|
||||
// fn props(&self) -> &'a P {
|
||||
// todo!()
|
||||
// }
|
||||
|
||||
// pub fn use_hook<'scope, InternalHookState: 'static, Output: 'a>(
|
||||
// &'scope self,
|
||||
// _initializer: impl FnOnce() -> InternalHookState,
|
||||
// _runner: impl FnOnce(&'a mut InternalHookState) -> Output,
|
||||
// _cleanup: impl FnOnce(InternalHookState),
|
||||
// ) -> Output {
|
||||
// todo!()
|
||||
// }
|
||||
// }
|
||||
|
||||
// trait Properties {}
|
||||
|
||||
// struct DTree;
|
||||
// // type FC2<'a, T: 'a> = fn(Context2<T>) -> DTree;
|
||||
// fn virtual_child<'a, T: 'a>(_bump: &'a Bump, _props: T, _f: FC2<T>) -> VNode<'a> {
|
||||
// todo!()
|
||||
// }
|
||||
|
||||
// struct Props {
|
||||
// c: String,
|
||||
// }
|
||||
|
||||
// fn Example(ctx: Context2<Props>) -> DTree {
|
||||
// let val = use_state(&ctx, || String::from("asd"));
|
||||
// let props = ctx.props();
|
||||
|
||||
// ctx.render(move |b| {
|
||||
// dioxus_core::nodebuilder::div(b)
|
||||
// .child(dioxus_core::nodebuilder::text(props.c.as_str()))
|
||||
// .child(virtual_child(b, Props2 { a: val }, AltChild))
|
||||
// .finish()
|
||||
// })
|
||||
// }
|
||||
|
||||
// // #[fc]
|
||||
// fn Example2(ctx: Context2<()>, name: &str, _blah: &str) -> DTree {
|
||||
// let val = use_state(&ctx, || String::from("asd"));
|
||||
|
||||
// ctx.render(move |ctx| {
|
||||
// dioxus_core::builder::ElementBuilder::new(b, "div")
|
||||
// .child(dioxus_core::nodebuilder::text(name))
|
||||
// .child(virtual_child(b, Props2 { a: val }, AltChild))
|
||||
// .finish()
|
||||
// })
|
||||
// }
|
||||
|
||||
// type FC2<'a, T> = fn(Context2<T>) -> DTree;
|
||||
|
||||
// // still works if you don't take any references in your props (ie, something copy or cloneable)
|
||||
// static CHILD: FC2<Props2> = |_ctx: Context2<Props2>| {
|
||||
// //
|
||||
// todo!()
|
||||
// };
|
||||
|
||||
// struct Props2<'a> {
|
||||
// a: &'a String,
|
||||
// }
|
||||
// impl Properties for Props2<'_> {}
|
||||
|
||||
// fn AltChild(ctx: Context2<Props2>) -> DTree {
|
||||
// ctx.render(|_b| {
|
||||
// //
|
||||
// todo!()
|
||||
// })
|
||||
// }
|
||||
|
||||
// fn use_state<'a, 'c, P, T: 'static, F: FnOnce() -> T>(
|
||||
// _ctx: &'_ Context2<'a, P>,
|
||||
// _initial_state_fn: F,
|
||||
// ) -> &'a T {
|
||||
// todo!()
|
||||
// }
|
||||
static Example: FC<()> = |ctx, props| {
|
||||
ctx.render(dioxus_core::prelude::LazyNodes::new(move |ctx| {
|
||||
let bump = ctx.bump;
|
||||
dioxus::builder::ElementBuilder::new(ctx, "h1")
|
||||
.children([{
|
||||
use bumpalo::core_alloc::fmt::Write;
|
||||
let mut s = bumpalo::collections::String::new_in(bump);
|
||||
write!(s, "hello");
|
||||
dioxus::builder::text2(s)
|
||||
}])
|
||||
.finish()
|
||||
}))
|
||||
};
|
||||
@@ -22,7 +22,7 @@ struct ListItem {
|
||||
fn app(ctx: Context, props: &Props) -> DomTree {
|
||||
let (_f, setter) = use_state(&ctx, || 0);
|
||||
|
||||
ctx.render(move |c| {
|
||||
ctx.render(dioxus::prelude::LazyNodes::new(move |c| {
|
||||
let mut root = builder::ElementBuilder::new(c, "div");
|
||||
for child in &props.items {
|
||||
// notice that the child directly borrows from our vec
|
||||
@@ -39,7 +39,7 @@ fn app(ctx: Context, props: &Props) -> DomTree {
|
||||
));
|
||||
}
|
||||
root.finish()
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
type StateSetter<T> = dyn Fn(T);
|
||||
|
||||
@@ -13,7 +13,7 @@ struct Props {
|
||||
static Example: FC<Props> = |ctx, props| {
|
||||
let value = ctx.use_context(|c: &SomeContext| c.items.last().unwrap());
|
||||
|
||||
ctx.render(move |bump| {
|
||||
ctx.render(LazyNodes::new(move |bump| {
|
||||
builder::ElementBuilder::new(bump, "button")
|
||||
.on("click", move |_| {
|
||||
println!("Value is {}", props.name);
|
||||
@@ -24,7 +24,7 @@ static Example: FC<Props> = |ctx, props| {
|
||||
println!("Value is {}", props.name);
|
||||
})
|
||||
.finish()
|
||||
})
|
||||
}))
|
||||
// ctx.render(html! {
|
||||
// <div>
|
||||
// <button onclick={move |_| println!("Value is {}", value)} />
|
||||
|
||||
@@ -18,8 +18,54 @@ pub struct ExampleProps {
|
||||
}
|
||||
|
||||
static SomeComponent: FC<ExampleProps> = |ctx, _props| {
|
||||
let blah = rsx! {
|
||||
div {}
|
||||
};
|
||||
|
||||
let data = match 1 {
|
||||
1 => ctx.render(rsx! (
|
||||
div {
|
||||
h1 {}
|
||||
h3 {}
|
||||
}
|
||||
)),
|
||||
1 => ctx.render(rsx!( div { "abc" } )),
|
||||
2 => ctx.render(rsx!( div { "abc" } )),
|
||||
3 => ctx.render(rsx!( div { "abc" } )),
|
||||
_ => todo!(),
|
||||
};
|
||||
|
||||
let data = match 1 {
|
||||
1 => ctx.render(rsx! (
|
||||
div {
|
||||
h1 {}
|
||||
h3 {}
|
||||
}
|
||||
)),
|
||||
1 => ctx.render(rsx!(
|
||||
div { "abc" }
|
||||
)),
|
||||
2 => ctx.render(rsx!(
|
||||
div { "abc" }
|
||||
)),
|
||||
3 => ctx.render(rsx!(
|
||||
div { "abc" }
|
||||
)),
|
||||
_ => todo!(),
|
||||
};
|
||||
|
||||
let i = (0..10).map(|v| {
|
||||
rsx! {
|
||||
div {
|
||||
"{v}"
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
ctx.render(rsx! {
|
||||
div { }
|
||||
div {
|
||||
""
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ static Header: FC<()> = |ctx, props| {
|
||||
|
||||
let handler1 = move || println!("Value is {}", inner.current());
|
||||
|
||||
ctx.render(|c| {
|
||||
ctx.render(dioxus::prelude::LazyNodes::new(|c| {
|
||||
builder::ElementBuilder::new(c, "div")
|
||||
.child(VNode::Component(VComponent::new(
|
||||
Bottom,
|
||||
@@ -20,7 +20,7 @@ static Header: FC<()> = |ctx, props| {
|
||||
c.bump.alloc(()),
|
||||
)))
|
||||
.finish()
|
||||
})
|
||||
}))
|
||||
};
|
||||
|
||||
static Bottom: FC<()> = |ctx, props| {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
use dioxus_core::prelude::*;
|
||||
|
||||
fn main() {}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use crate::nodes::VNode;
|
||||
use crate::prelude::*;
|
||||
use crate::{nodebuilder::IntoDomTree, prelude::*};
|
||||
use crate::{nodebuilder::LazyNodes, nodes::VNode};
|
||||
use bumpalo::Bump;
|
||||
use hooks::Hook;
|
||||
use std::{cell::RefCell, future::Future, ops::Deref, rc::Rc, sync::atomic::AtomicUsize};
|
||||
@@ -95,7 +95,10 @@ impl<'a> Context<'a> {
|
||||
/// ctx.render(lazy_tree)
|
||||
/// }
|
||||
///```
|
||||
pub fn render(&self, lazy_nodes: impl FnOnce(&'_ NodeCtx<'a>) -> VNode<'a> + 'a) -> DomTree {
|
||||
pub fn render<F: for<'b> FnOnce(&'b NodeCtx<'a>) -> VNode<'a> + 'a>(
|
||||
&self,
|
||||
lazy_nodes: LazyNodes<'a, F>,
|
||||
) -> DomTree {
|
||||
let ctx = NodeCtx {
|
||||
bump: self.bump,
|
||||
scope: self.scope,
|
||||
@@ -103,7 +106,7 @@ impl<'a> Context<'a> {
|
||||
listeners: self.listeners,
|
||||
};
|
||||
|
||||
let safe_nodes = lazy_nodes(&ctx);
|
||||
let safe_nodes = lazy_nodes.into_vnode(&ctx);
|
||||
let root: VNode<'static> = unsafe { std::mem::transmute(safe_nodes) };
|
||||
DomTree { root }
|
||||
}
|
||||
|
||||
@@ -160,12 +160,7 @@ pub mod on {
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct MouseEvent(pub Box<RawMouseEvent>);
|
||||
impl Deref for MouseEvent {
|
||||
type Target = RawMouseEvent;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct RawMouseEvent {
|
||||
pub alt_key: bool,
|
||||
@@ -183,6 +178,12 @@ pub mod on {
|
||||
pub get_modifier_state: GetModifierKey,
|
||||
// relatedTarget: DOMEventTarget,
|
||||
}
|
||||
impl Deref for MouseEvent {
|
||||
type Target = RawMouseEvent;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.0.as_ref()
|
||||
}
|
||||
}
|
||||
event_builder! {
|
||||
MouseEvent;
|
||||
click contextmenu doubleclick drag dragend dragenter dragexit
|
||||
|
||||
@@ -138,6 +138,8 @@ pub mod prelude {
|
||||
use crate::nodes;
|
||||
pub use nodes::*;
|
||||
|
||||
pub use crate::nodebuilder::LazyNodes;
|
||||
|
||||
pub use crate::context::NodeCtx;
|
||||
// pub use nodes::iterables::IterableNodes;
|
||||
/// This type alias is an internal way of abstracting over the static functions that represent components.
|
||||
|
||||
+121
-155
@@ -16,14 +16,13 @@ use crate::{
|
||||
/// function for building `<div>` elements or the `button` function for building
|
||||
/// `<button>` elements.
|
||||
#[derive(Debug)]
|
||||
pub struct ElementBuilder<'a, Listeners, Attributes, Children>
|
||||
pub struct ElementBuilder<'a, 'b, Listeners, Attributes, Children>
|
||||
where
|
||||
Listeners: 'a + AsRef<[Listener<'a>]>,
|
||||
Attributes: 'a + AsRef<[Attribute<'a>]>,
|
||||
Children: 'a + AsRef<[VNode<'a>]>,
|
||||
{
|
||||
ctx: NodeCtx<'a>,
|
||||
// ctx: &'b NodeCtx<'a>,
|
||||
ctx: &'b NodeCtx<'a>,
|
||||
key: NodeKey,
|
||||
tag_name: &'a str,
|
||||
listeners: Listeners,
|
||||
@@ -32,9 +31,10 @@ where
|
||||
namespace: Option<&'a str>,
|
||||
}
|
||||
|
||||
impl<'a>
|
||||
impl<'a, 'b>
|
||||
ElementBuilder<
|
||||
'a,
|
||||
'b,
|
||||
bumpalo::collections::Vec<'a, Listener<'a>>,
|
||||
bumpalo::collections::Vec<'a, Attribute<'a>>,
|
||||
bumpalo::collections::Vec<'a, VNode<'a>>,
|
||||
@@ -63,24 +63,22 @@ impl<'a>
|
||||
/// let my_element_builder = ElementBuilder::new(&b, tag_name);
|
||||
/// # fn flip_coin() -> bool { true }
|
||||
/// ```
|
||||
pub fn new(ctx: &NodeCtx<'a>, tag_name: &'static str) -> Self {
|
||||
// pub fn new(ctx: &'b NodeCtx<'a>, tag_name: &'static str) -> Self {
|
||||
// pub fn new<B>(ctx: &'a mut NodeCtx<'a>, tag_name: &'a str) -> Self {
|
||||
pub fn new(ctx: &'b NodeCtx<'a>, tag_name: &'static str) -> Self {
|
||||
let bump = ctx.bump;
|
||||
todo!()
|
||||
// ElementBuilder {
|
||||
// ctx,
|
||||
// key: NodeKey::NONE,
|
||||
// tag_name,
|
||||
// listeners: bumpalo::collections::Vec::new_in(bump),
|
||||
// attributes: bumpalo::collections::Vec::new_in(bump),
|
||||
// children: bumpalo::collections::Vec::new_in(bump),
|
||||
// namespace: None,
|
||||
// }
|
||||
ElementBuilder {
|
||||
ctx,
|
||||
key: NodeKey::NONE,
|
||||
tag_name,
|
||||
listeners: bumpalo::collections::Vec::new_in(bump),
|
||||
attributes: bumpalo::collections::Vec::new_in(bump),
|
||||
children: bumpalo::collections::Vec::new_in(bump),
|
||||
namespace: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Listeners, Attributes, Children> ElementBuilder<'a, Listeners, Attributes, Children>
|
||||
impl<'a, 'b, Listeners, Attributes, Children>
|
||||
ElementBuilder<'a, 'b, Listeners, Attributes, Children>
|
||||
where
|
||||
Listeners: 'a + AsRef<[Listener<'a>]>,
|
||||
Attributes: 'a + AsRef<[Attribute<'a>]>,
|
||||
@@ -114,7 +112,7 @@ where
|
||||
/// .finish();
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn listeners<L>(self, listeners: L) -> ElementBuilder<'a, L, Attributes, Children>
|
||||
pub fn listeners<L>(self, listeners: L) -> ElementBuilder<'a, 'b, L, Attributes, Children>
|
||||
where
|
||||
L: 'a + AsRef<[Listener<'a>]>,
|
||||
{
|
||||
@@ -153,7 +151,7 @@ where
|
||||
/// .finish();
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn attributes<A>(self, attributes: A) -> ElementBuilder<'a, Listeners, A, Children>
|
||||
pub fn attributes<A>(self, attributes: A) -> ElementBuilder<'a, 'b, Listeners, A, Children>
|
||||
where
|
||||
A: 'a + AsRef<[Attribute<'a>]>,
|
||||
{
|
||||
@@ -192,7 +190,7 @@ where
|
||||
/// .finish();
|
||||
/// ```
|
||||
#[inline]
|
||||
pub fn children<C>(self, children: C) -> ElementBuilder<'a, Listeners, Attributes, C>
|
||||
pub fn children<C>(self, children: C) -> ElementBuilder<'a, 'b, Listeners, Attributes, C>
|
||||
where
|
||||
C: 'a + AsRef<[VNode<'a>]>,
|
||||
{
|
||||
@@ -311,8 +309,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Attributes, Children>
|
||||
ElementBuilder<'a, bumpalo::collections::Vec<'a, Listener<'a>>, Attributes, Children>
|
||||
impl<'a, 'b, Attributes, Children>
|
||||
ElementBuilder<'a, 'b, bumpalo::collections::Vec<'a, Listener<'a>>, Attributes, Children>
|
||||
where
|
||||
Attributes: 'a + AsRef<[Attribute<'a>]>,
|
||||
Children: 'a + AsRef<[VNode<'a>]>,
|
||||
@@ -365,8 +363,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Listeners, Children>
|
||||
ElementBuilder<'a, Listeners, bumpalo::collections::Vec<'a, Attribute<'a>>, Children>
|
||||
impl<'a, 'b, Listeners, Children>
|
||||
ElementBuilder<'a, 'b, Listeners, bumpalo::collections::Vec<'a, Attribute<'a>>, Children>
|
||||
where
|
||||
Listeners: 'a + AsRef<[Listener<'a>]>,
|
||||
Children: 'a + AsRef<[VNode<'a>]>,
|
||||
@@ -424,8 +422,8 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Listeners, Attributes>
|
||||
ElementBuilder<'a, Listeners, Attributes, bumpalo::collections::Vec<'a, VNode<'a>>>
|
||||
impl<'a, 'b, Listeners, Attributes>
|
||||
ElementBuilder<'a, 'b, Listeners, Attributes, bumpalo::collections::Vec<'a, VNode<'a>>>
|
||||
where
|
||||
Listeners: 'a + AsRef<[Listener<'a>]>,
|
||||
Attributes: 'a + AsRef<[Attribute<'a>]>,
|
||||
@@ -451,16 +449,26 @@ where
|
||||
self
|
||||
}
|
||||
|
||||
pub fn iter_child(mut self, nodes: impl IntoIterator<Item = DomTree>) -> Self {
|
||||
for item in nodes.into_iter() {
|
||||
self.children.push(item.root);
|
||||
/// Add multiple children to this element from an iterator.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```no_run
|
||||
/// use dioxus::{builder::*, bumpalo::Bump};
|
||||
///
|
||||
/// let b = Bump::new();
|
||||
///
|
||||
/// let my_div = p(&b)
|
||||
/// .iter_child((0..10).map(|f| span(&b).finish())
|
||||
/// .finish();
|
||||
/// ```
|
||||
pub fn iter_child(mut self, nodes: impl IntoIterator<Item = impl IntoDomTree<'a>>) -> Self {
|
||||
for item in nodes {
|
||||
let child = item.into_vnode(&self.ctx);
|
||||
self.children.push(child);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn into_tomdtree(mut self, nodes: impl IntoDomTree<'a>) -> Self {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for DomTree {
|
||||
@@ -472,166 +480,124 @@ impl IntoIterator for DomTree {
|
||||
}
|
||||
|
||||
pub trait IntoDomTree<'a> {
|
||||
type NodeIter: IntoIterator<Item = DomTree>;
|
||||
fn into_domtree(self, ctx: &NodeCtx<'a>) -> Self::NodeIter;
|
||||
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a>;
|
||||
}
|
||||
|
||||
impl IntoDomTree<'_> for DomTree {
|
||||
type NodeIter = std::iter::Once<DomTree>;
|
||||
fn into_domtree(self, ctx: &NodeCtx) -> Self::NodeIter {
|
||||
std::iter::once(self)
|
||||
// Cover the cases where nodes are pre-rendered.
|
||||
// Likely used by enums.
|
||||
// ----
|
||||
// let nodes = ctx.render(rsx!{ ... };
|
||||
// rsx! { {nodes } }
|
||||
impl<'a> IntoDomTree<'a> for DomTree {
|
||||
fn into_vnode(self, _ctx: &NodeCtx<'a>) -> VNode<'a> {
|
||||
self.root
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, G> IntoDomTree<'a> for NodeWrapper<'a, G>
|
||||
// Wrap the the node-builder closure in a concrete type.
|
||||
// ---
|
||||
// This is a bit of a hack to implement the IntoDomTree trait for closure types.
|
||||
pub struct LazyNodes<'a, G>
|
||||
where
|
||||
G: for<'b, 'c> FnOnce(&'b NodeCtx<'c>) -> VNode<'c> + 'a,
|
||||
{
|
||||
type NodeIter = std::iter::Once<DomTree>;
|
||||
|
||||
fn into_domtree(self, ctx: &NodeCtx) -> Self::NodeIter {
|
||||
let p: VNode<'_> = (self.inner)(ctx);
|
||||
let root: VNode<'static> = unsafe { std::mem::transmute(p) };
|
||||
std::iter::once(DomTree { root })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, G, I> IntoDomTree<'a> for I
|
||||
where
|
||||
G: for<'b, 'c> FnOnce(&'b NodeCtx<'c>) -> VNode<'c> + 'a,
|
||||
I: Iterator<Item = NodeWrapper<'a, G>>,
|
||||
// O: Iterator<Item = DomTree>,
|
||||
{
|
||||
type NodeIter = std::iter::Map<I, O>;
|
||||
|
||||
fn into_domtree(self, ctx: &NodeCtx) -> Self::NodeIter {
|
||||
self.map(|f| {
|
||||
//
|
||||
let caller = (f.inner);
|
||||
let r = caller(ctx);
|
||||
})
|
||||
// todo!()
|
||||
// let p: VNode<'_> = (self.inner)(ctx);
|
||||
// let root: VNode<'static> = unsafe { std::mem::transmute(p) };
|
||||
// std::iter::once(DomTree { root })
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
all possible impls
|
||||
|
||||
rsx!{ }
|
||||
ctx.render(rsx!)
|
||||
|
||||
map(rsx!)
|
||||
map(ctx.render(rsx!))
|
||||
*/
|
||||
|
||||
pub struct NodeWrapper<'a, G>
|
||||
where
|
||||
G: for<'b, 'c> FnOnce(&'b NodeCtx<'c>) -> VNode<'c> + 'a,
|
||||
G: for<'b> FnOnce(&'b NodeCtx<'a>) -> VNode<'a> + 'a,
|
||||
{
|
||||
inner: G,
|
||||
_p: std::marker::PhantomData<&'a ()>,
|
||||
}
|
||||
|
||||
fn new_wrapper<'a, G>(f: G) -> NodeWrapper<'a, G>
|
||||
impl<'a, G> LazyNodes<'a, G>
|
||||
where
|
||||
G: for<'b> FnOnce(&'b NodeCtx<'a>) -> VNode<'a> + 'a,
|
||||
{
|
||||
pub fn new(f: G) -> Self {
|
||||
Self {
|
||||
inner: f,
|
||||
_p: std::default::Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Cover the cases where nodes are used by macro.
|
||||
// Likely used directly.
|
||||
// ---
|
||||
// let nodes = rsx!{ ... };
|
||||
// rsx! { {nodes } }
|
||||
impl<'a, G> IntoDomTree<'a> for LazyNodes<'a, G>
|
||||
where
|
||||
G: for<'b> FnOnce(&'b NodeCtx<'a>) -> VNode<'a> + 'a,
|
||||
{
|
||||
fn into_vnode(self, ctx: &NodeCtx<'a>) -> VNode<'a> {
|
||||
(self.inner)(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
// Required because anything that enters brackets in the rsx! macro needs to implement IntoIterator
|
||||
impl<'a, G> IntoIterator for LazyNodes<'a, G>
|
||||
where
|
||||
G: for<'b, 'c> FnOnce(&'b NodeCtx<'c>) -> VNode<'c> + 'a,
|
||||
{
|
||||
NodeWrapper {
|
||||
inner: f,
|
||||
_p: std::default::Default::default(),
|
||||
type Item = Self;
|
||||
type IntoIter = std::iter::Once<Self::Item>;
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
std::iter::once(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_iterator_of_nodes<'b>() {
|
||||
let p = (0..10).map(|f| {
|
||||
//
|
||||
new_wrapper(rsx! {
|
||||
div {
|
||||
"aaa {f}"
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
let g = p.into_iter();
|
||||
for f in g {}
|
||||
use crate::prelude::*;
|
||||
|
||||
static Example: FC<()> = |ctx, props| {
|
||||
ctx.render(|c| {
|
||||
//
|
||||
ElementBuilder::new(c, "div")
|
||||
.into_tomdtree({
|
||||
// rsx!
|
||||
new_wrapper(move |n: &NodeCtx| -> VNode {
|
||||
//
|
||||
ElementBuilder::new(n, "div").finish()
|
||||
})
|
||||
// use the macro to be "blind" to the type
|
||||
// everything gets interpreted as
|
||||
/*
|
||||
let g: LazyNodes<_> = rsx! {
|
||||
div {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
for node in {expr} {
|
||||
ctx.push_alloc_node(node)
|
||||
}
|
||||
|
||||
|
||||
so.... just make sure whatever enters {} is iterable (domtree and nodewrapper need impls, )
|
||||
|
||||
|
||||
*/
|
||||
//
|
||||
})
|
||||
.into_tomdtree({
|
||||
// render to wrapper -> tree
|
||||
ctx.render(rsx! {
|
||||
div {}
|
||||
})
|
||||
})
|
||||
.into_tomdtree({
|
||||
// map rsx!
|
||||
(0..10).map(|f| {
|
||||
new_wrapper(move |n: &NodeCtx| -> VNode {
|
||||
//
|
||||
ElementBuilder::new(n, "div").finish()
|
||||
})
|
||||
})
|
||||
})
|
||||
.finish()
|
||||
ctx.render(rsx! {
|
||||
div {
|
||||
h1 {}
|
||||
{}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
use crate::prelude::*;
|
||||
// let p = (0..10).map(|f| {
|
||||
// //
|
||||
// LazyNodes::new(rsx! {
|
||||
// div {
|
||||
// "aaa {f}"
|
||||
// }
|
||||
// })
|
||||
// });
|
||||
|
||||
// let g = p.into_iter();
|
||||
// for f in g {}
|
||||
|
||||
// static Example: FC<()> = |ctx, props| {
|
||||
// //
|
||||
// let list = (0..10).map(|f| {
|
||||
// ctx.render(rsx! {
|
||||
// div {}
|
||||
// })
|
||||
// });
|
||||
|
||||
// ctx.render(|c| {
|
||||
// //
|
||||
// ElementBuilder::new(c, "div")
|
||||
// .iter_child({
|
||||
// //
|
||||
// // rsx!
|
||||
// LazyNodes::new(move |n: &NodeCtx| -> VNode {
|
||||
// //
|
||||
// ElementBuilder::new(n, "div").finish()
|
||||
// })
|
||||
// })
|
||||
// .iter_child({
|
||||
// // render to wrapper -> tree
|
||||
// ctx.render(rsx! {
|
||||
// div {}
|
||||
// })
|
||||
// })
|
||||
// .iter_child({
|
||||
// //
|
||||
// // map rsx!
|
||||
// (0..10).map(|f| {
|
||||
// ctx.render(rsx! {
|
||||
// div {}
|
||||
// LazyNodes::new(move |n: &NodeCtx| -> VNode {
|
||||
// //
|
||||
// ElementBuilder::new(n, "div").finish()
|
||||
// })
|
||||
// })
|
||||
// })
|
||||
// .iter_child(list)
|
||||
// .finish()
|
||||
// })
|
||||
// };
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
use crate::{
|
||||
events::VirtualEvent,
|
||||
innerlude::{Context, Properties, ScopeIdx, FC},
|
||||
innerlude::{Context, NodeCtx, Properties, ScopeIdx, FC},
|
||||
};
|
||||
|
||||
use bumpalo::Bump;
|
||||
|
||||
Reference in new issue
Block a user