wip: remove cx.children. start to move towards a "children" field
This commit is contained in:
1 parent
6b2645fd80
commit
7b97e009ec
14 files changed
+114
-276
No files matched your search
@@ -233,65 +233,12 @@ fn Child2<'a>((cx, props): Scope<'a, Child2Props>) -> Element<'a> {
|
|||||||
let b = cx.bump();
|
let b = cx.bump();
|
||||||
let node: &'a VNode<'a> = b.alloc(node);
|
let node: &'a VNode<'a> = b.alloc(node);
|
||||||
|
|
||||||
let children = ChildList { pthru: node };
|
let children = Children { 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(ChildrenMemo, (), None, []),
|
|
||||||
// __cx.component(
|
|
||||||
// ChildrenComp,
|
|
||||||
// //
|
|
||||||
// ChildrenTest { node: children },
|
|
||||||
// None,
|
|
||||||
// [],
|
|
||||||
// ),
|
|
||||||
// // {
|
|
||||||
// // let _props: &_ = __cx.bump().alloc(ChildrenTest { node: children });
|
|
||||||
// // __cx.component_v2_borrowed(
|
|
||||||
// // //
|
|
||||||
// // move |c| ChildrenComp((c, _props)),
|
|
||||||
// // ChildrenComp,
|
|
||||||
// // _props,
|
|
||||||
// // )
|
|
||||||
// // },
|
|
||||||
// // {
|
|
||||||
// // let _props: &_ = __cx.bump().alloc(());
|
|
||||||
// // __cx.component_v2_borrowed(move |c| ChildrenMemo((c, _props)))
|
|
||||||
// // },
|
|
||||||
// ],
|
|
||||||
// None,
|
|
||||||
// )
|
|
||||||
// })
|
|
||||||
// })
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
ChildrenComp {
|
ChildrenComp {
|
||||||
..ChildrenTest {
|
children: children
|
||||||
node: children,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -299,21 +246,21 @@ fn Child2<'a>((cx, props): Scope<'a, Child2Props>) -> Element<'a> {
|
|||||||
|
|
||||||
#[derive(Props)]
|
#[derive(Props)]
|
||||||
struct ChildrenTest<'a> {
|
struct ChildrenTest<'a> {
|
||||||
node: ChildList<'a>,
|
children: Children<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ChildList<'a> {
|
struct Children<'a> {
|
||||||
pthru: &'a VNode<'a>,
|
pthru: &'a VNode<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Clone for ChildList<'a> {
|
impl<'a> Clone for Children<'a> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self { pthru: self.pthru }
|
Self { pthru: self.pthru }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> Copy for ChildList<'a> {}
|
impl<'a> Copy for Children<'a> {}
|
||||||
|
|
||||||
impl<'a> IntoVNode<'a> for ChildList<'a> {
|
impl<'a> IntoVNode<'a> for Children<'a> {
|
||||||
fn into_vnode(self, _: NodeFactory<'a>) -> VNode<'a> {
|
fn into_vnode(self, _: NodeFactory<'a>) -> VNode<'a> {
|
||||||
match self.pthru {
|
match self.pthru {
|
||||||
VNode::Text(f) => VNode::Text(*f),
|
VNode::Text(f) => VNode::Text(*f),
|
||||||
@@ -338,7 +285,7 @@ fn ChildrenComp<'a>((cx, props): Scope<'a, ChildrenTest<'a>>) -> Element<'a> {
|
|||||||
// if the node's id is already assigned, then it's being passed in as a child
|
// 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?
|
// in these instances, we don't worry about re-checking the node?
|
||||||
|
|
||||||
{Some(props.node)}
|
{Some(props.children)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ use std::time::Duration;
|
|||||||
|
|
||||||
use dioxus_core::prelude::*;
|
use dioxus_core::prelude::*;
|
||||||
|
|
||||||
#[async_std::main]
|
// #[async_std::main]
|
||||||
async fn main() {
|
fn main() {
|
||||||
static App: FC<()> =
|
static App: FC<()> =
|
||||||
|(cx, props)| cx.render(Some(Box::new(move |f| f.text(format_args!("hello")))));
|
|(cx, props)| cx.render(Some(Box::new(move |f| f.text(format_args!("hello")))));
|
||||||
|
|
||||||
@@ -11,7 +11,7 @@ async fn main() {
|
|||||||
|
|
||||||
dom.rebuild();
|
dom.rebuild();
|
||||||
|
|
||||||
let deadline = async_std::task::sleep(Duration::from_millis(50));
|
// let deadline = async_std::task::sleep(Duration::from_millis(50));
|
||||||
|
|
||||||
// let _fut = dom.run_with_deadline(|| deadline.);
|
// let _fut = dom.run_with_deadline(|| deadline.);
|
||||||
}
|
}
|
||||||
@@ -138,6 +138,6 @@ impl EmptyBuilder {
|
|||||||
|
|
||||||
/// This utility function launches the builder method so rsx! and html! macros can use the typed-builder pattern
|
/// This utility function launches the builder method so rsx! and html! macros can use the typed-builder pattern
|
||||||
/// to initialize a component's props.
|
/// to initialize a component's props.
|
||||||
pub fn fc_to_builder<T: Properties>(_: FC<T>) -> T::Builder {
|
pub fn fc_to_builder<'a, T: Properties + 'a>(_: fn(Scope<'a, T>) -> Element<'a>) -> T::Builder {
|
||||||
T::builder()
|
T::builder()
|
||||||
}
|
}
|
||||||
@@ -54,49 +54,6 @@ impl<'a> Deref for Context<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'src> Context<'src> {
|
impl<'src> Context<'src> {
|
||||||
/// Access the children elements passed into the component
|
|
||||||
///
|
|
||||||
/// This enables patterns where a component is passed children from its parent.
|
|
||||||
///
|
|
||||||
/// ## Details
|
|
||||||
///
|
|
||||||
/// Unlike React, Dioxus allows *only* lists of children to be passed from parent to child - not arbitrary functions
|
|
||||||
/// or classes. If you want to generate nodes instead of accepting them as a list, consider declaring a closure
|
|
||||||
/// on the props that takes Context.
|
|
||||||
///
|
|
||||||
/// If a parent passes children into a component, the child will always re-render when the parent re-renders. In other
|
|
||||||
/// words, a component cannot be automatically memoized if it borrows nodes from its parent, even if the component's
|
|
||||||
/// props are valid for the static lifetime.
|
|
||||||
///
|
|
||||||
/// ## Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// const App: FC<()> = |(cx, props)|{
|
|
||||||
/// cx.render(rsx!{
|
|
||||||
/// CustomCard {
|
|
||||||
/// h1 {}
|
|
||||||
/// p {}
|
|
||||||
/// }
|
|
||||||
/// })
|
|
||||||
/// }
|
|
||||||
///
|
|
||||||
/// const CustomCard: FC<()> = |(cx, props)|{
|
|
||||||
/// cx.render(rsx!{
|
|
||||||
/// div {
|
|
||||||
/// h1 {"Title card"}
|
|
||||||
/// {cx.children()}
|
|
||||||
/// }
|
|
||||||
/// })
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// ## Notes:
|
|
||||||
///
|
|
||||||
/// This method returns a "ScopeChildren" object. This object is copy-able and preserve the correct lifetime.
|
|
||||||
pub fn children(&self) -> ScopeChildren<'src> {
|
|
||||||
self.scope.child_nodes()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a subscription that schedules a future render for the reference component
|
/// Create a subscription that schedules a future render for the reference component
|
||||||
///
|
///
|
||||||
/// ## Notice: you should prefer using prepare_update and get_scope_id
|
/// ## Notice: you should prefer using prepare_update and get_scope_id
|
||||||
@@ -147,28 +104,10 @@ impl<'src> Context<'src> {
|
|||||||
pub fn render(
|
pub fn render(
|
||||||
self,
|
self,
|
||||||
lazy_nodes: Option<Box<dyn FnOnce(NodeFactory<'src>) -> VNode<'src> + '_>>,
|
lazy_nodes: Option<Box<dyn FnOnce(NodeFactory<'src>) -> VNode<'src> + '_>>,
|
||||||
// lazy_nodes: Option<Box<dyn FnOnce(NodeFactory) -> VNode + '_>>,
|
|
||||||
// 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 }))
|
|
||||||
|
|
||||||
let factory = NodeFactory { bump };
|
let factory = NodeFactory { bump };
|
||||||
// let vnode = lazy_nodes(factory);
|
lazy_nodes.map(|f| f(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.
|
||||||
|
|||||||
@@ -348,7 +348,6 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
Some(parent_idx),
|
Some(parent_idx),
|
||||||
parent_scope.height + 1,
|
parent_scope.height + 1,
|
||||||
parent_scope.subtree(),
|
parent_scope.subtree(),
|
||||||
ScopeChildren(vcomponent.children),
|
|
||||||
shared,
|
shared,
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
@@ -555,7 +554,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
|
|
||||||
// make sure the component's caller function is up to date
|
// make sure the component's caller function is up to date
|
||||||
let scope = self.vdom.get_scope_mut(scope_addr).unwrap();
|
let scope = self.vdom.get_scope_mut(scope_addr).unwrap();
|
||||||
scope.update_scope_dependencies(new.caller, ScopeChildren(new.children));
|
scope.update_scope_dependencies(new.caller);
|
||||||
|
|
||||||
// React doesn't automatically memoize, but we do.
|
// React doesn't automatically memoize, but we do.
|
||||||
let props_are_the_same = old.comparator.unwrap();
|
let props_are_the_same = old.comparator.unwrap();
|
||||||
|
|||||||
+23
-79
@@ -638,47 +638,6 @@ pub trait IntoVNode<'a> {
|
|||||||
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a>;
|
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Child nodes of the parent component.
|
|
||||||
///
|
|
||||||
/// # Example
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// let children = cx.children();
|
|
||||||
/// let first_node = &children[0];
|
|
||||||
/// rsx!{
|
|
||||||
/// h1 { {first_node} }
|
|
||||||
/// p { {&children[1..]} }
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
pub struct ScopeChildren<'a>(pub &'a [VNode<'a>]);
|
|
||||||
|
|
||||||
impl Copy for ScopeChildren<'_> {}
|
|
||||||
|
|
||||||
impl<'a> Clone for ScopeChildren<'a> {
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
ScopeChildren(self.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ScopeChildren<'_> {
|
|
||||||
// dangerous method - used to fix the associated lifetime
|
|
||||||
pub(crate) unsafe fn extend_lifetime(self) -> ScopeChildren<'static> {
|
|
||||||
std::mem::transmute(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
// dangerous method - used to fix the associated lifetime
|
|
||||||
pub(crate) unsafe fn shorten_lifetime<'a>(self) -> ScopeChildren<'a> {
|
|
||||||
std::mem::transmute(self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// impl IntoVNodeList for ScopeChildren<'_> {
|
|
||||||
// fn into_vnode_list<'a>(self, _: NodeFactory<'a>) -> &'a [VNode<'a>] {
|
|
||||||
// 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> {
|
||||||
type Item = VNode<'a>;
|
type Item = VNode<'a>;
|
||||||
@@ -690,34 +649,31 @@ impl<'a> IntoIterator for VNode<'a> {
|
|||||||
|
|
||||||
// TODO: do we even need this? It almost seems better not to
|
// TODO: do we even need this? It almost seems better not to
|
||||||
// // 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 IntoVNode for VNode<'_> {
|
impl<'a> IntoVNode<'a> for VNode<'a> {
|
||||||
// fn into_vnode<'a>(self, _: NodeFactory<'a>) -> VNode<'a> {
|
fn into_vnode(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 IntoVNode for Option<VNode<'_>> {
|
impl<'a> IntoVNode<'a> for Option<VNode<'a>> {
|
||||||
// fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
||||||
// match self {
|
self.unwrap_or_else(|| cx.fragment_from_iter(None as Option<VNode>))
|
||||||
// Some(n) => n,
|
}
|
||||||
// None => cx.fragment_from_iter(None as Option<VNode>),
|
}
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn annotate_lazy<'a, 'b, F>(f: F) -> Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>>
|
pub fn annotate_lazy<'a, 'b, F>(f: F) -> Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>>
|
||||||
where
|
where
|
||||||
@@ -729,11 +685,7 @@ where
|
|||||||
impl<'a> IntoVNode<'a> for Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>> {
|
impl<'a> IntoVNode<'a> for Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>> {
|
||||||
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
fn into_vnode(self, cx: NodeFactory<'a>) -> VNode<'a> {
|
||||||
match self {
|
match self {
|
||||||
Some(n) => {
|
Some(lazy) => lazy(cx),
|
||||||
//
|
|
||||||
// n.into_vnode(cx)
|
|
||||||
n(cx)
|
|
||||||
}
|
|
||||||
None => VNode::Fragment(VFragment {
|
None => VNode::Fragment(VFragment {
|
||||||
children: &[],
|
children: &[],
|
||||||
is_static: false,
|
is_static: false,
|
||||||
@@ -749,20 +701,12 @@ impl<'a> IntoVNode<'a> for Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 {
|
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)
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ pub struct ScopeInner {
|
|||||||
// Nodes
|
// Nodes
|
||||||
pub(crate) frames: ActiveFrame,
|
pub(crate) frames: ActiveFrame,
|
||||||
pub(crate) caller: *const dyn for<'b> Fn(&'b ScopeInner) -> Element<'b>,
|
pub(crate) caller: *const dyn for<'b> Fn(&'b ScopeInner) -> Element<'b>,
|
||||||
pub(crate) child_nodes: ScopeChildren<'static>,
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
we care about:
|
we care about:
|
||||||
@@ -181,11 +180,8 @@ impl ScopeInner {
|
|||||||
parent_idx: Option<ScopeId>,
|
parent_idx: Option<ScopeId>,
|
||||||
height: u32,
|
height: u32,
|
||||||
subtree: u32,
|
subtree: u32,
|
||||||
child_nodes: ScopeChildren,
|
|
||||||
shared: EventChannel,
|
shared: EventChannel,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let child_nodes = unsafe { child_nodes.extend_lifetime() };
|
|
||||||
|
|
||||||
let schedule_any_update = shared.schedule_any_immediate.clone();
|
let schedule_any_update = shared.schedule_any_immediate.clone();
|
||||||
|
|
||||||
let memoized_updater = Rc::new(move || schedule_any_update(our_arena_idx));
|
let memoized_updater = Rc::new(move || schedule_any_update(our_arena_idx));
|
||||||
@@ -198,7 +194,6 @@ impl ScopeInner {
|
|||||||
Self {
|
Self {
|
||||||
memoized_updater,
|
memoized_updater,
|
||||||
shared,
|
shared,
|
||||||
child_nodes,
|
|
||||||
caller,
|
caller,
|
||||||
parent_idx,
|
parent_idx,
|
||||||
our_arena_idx,
|
our_arena_idx,
|
||||||
@@ -218,18 +213,10 @@ impl ScopeInner {
|
|||||||
pub(crate) fn update_scope_dependencies<'creator_node>(
|
pub(crate) fn update_scope_dependencies<'creator_node>(
|
||||||
&mut self,
|
&mut self,
|
||||||
caller: &'creator_node dyn for<'b> Fn(&'b ScopeInner) -> Element<'b>,
|
caller: &'creator_node dyn for<'b> Fn(&'b ScopeInner) -> Element<'b>,
|
||||||
child_nodes: ScopeChildren,
|
|
||||||
) {
|
) {
|
||||||
log::debug!("Updating scope dependencies {:?}", self.our_arena_idx);
|
log::debug!("Updating scope dependencies {:?}", self.our_arena_idx);
|
||||||
let caller = caller as *const _;
|
let caller = caller as *const _;
|
||||||
self.caller = unsafe { std::mem::transmute(caller) };
|
self.caller = unsafe { std::mem::transmute(caller) };
|
||||||
|
|
||||||
let child_nodes = unsafe { child_nodes.extend_lifetime() };
|
|
||||||
self.child_nodes = child_nodes;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(crate) fn child_nodes(&self) -> ScopeChildren {
|
|
||||||
unsafe { self.child_nodes.shorten_lifetime() }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This method cleans up any references to data held within our hook list. This prevents mutable aliasing from
|
/// This method cleans up any references to data held within our hook list. This prevents mutable aliasing from
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ impl TestDom {
|
|||||||
NodeFactory::new(&self.bump)
|
NodeFactory::new(&self.bump)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_direct<'a>(&'a self, lazy_nodes: Element<'a>) -> VNode<'a>
|
pub fn render_direct<'a>(
|
||||||
|
&'a self,
|
||||||
|
lazy_nodes: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
|
||||||
|
) -> VNode<'a>
|
||||||
// where
|
// where
|
||||||
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
||||||
{
|
{
|
||||||
@@ -29,7 +32,10 @@ impl TestDom {
|
|||||||
// lazy_nodes.into_vnode(NodeFactory::new(&self.bump))
|
// 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: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
|
||||||
|
) -> &'a VNode<'a>
|
||||||
// where
|
// where
|
||||||
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
||||||
{
|
{
|
||||||
@@ -45,7 +51,10 @@ impl TestDom {
|
|||||||
machine.mutations
|
machine.mutations
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create<'a>(&'a self, left: Element<'a>) -> Mutations<'a>
|
pub fn create<'a>(
|
||||||
|
&'a self,
|
||||||
|
left: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
|
||||||
|
) -> Mutations<'a>
|
||||||
// pub fn create<'a, F1>(&'a self, left: LazyNodes<'a, F1>) -> Mutations<'a>
|
// pub fn create<'a, F1>(&'a self, left: LazyNodes<'a, F1>) -> Mutations<'a>
|
||||||
// where
|
// where
|
||||||
// F1: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
// F1: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
||||||
@@ -63,10 +72,8 @@ impl TestDom {
|
|||||||
|
|
||||||
pub fn lazy_diff<'a>(
|
pub fn lazy_diff<'a>(
|
||||||
&'a self,
|
&'a self,
|
||||||
left: Element<'a>,
|
left: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
|
||||||
right: Element<'a>,
|
right: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
|
||||||
// left: LazyNodes<'a, F1>,
|
|
||||||
// right: LazyNodes<'a, F2>,
|
|
||||||
) -> (Mutations<'a>, Mutations<'a>)
|
) -> (Mutations<'a>, Mutations<'a>)
|
||||||
// where
|
// where
|
||||||
// F1: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
// F1: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
||||||
|
|||||||
@@ -158,7 +158,6 @@ impl VirtualDom {
|
|||||||
None,
|
None,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
ScopeChildren(&[]),
|
|
||||||
scheduler.pool.channel.clone(),
|
scheduler.pool.channel.clone(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
@@ -226,7 +225,7 @@ impl VirtualDom {
|
|||||||
std::mem::transmute(root((Context { scope }, props)))
|
std::mem::transmute(root((Context { scope }, props)))
|
||||||
});
|
});
|
||||||
|
|
||||||
root_scope.update_scope_dependencies(&root_caller, ScopeChildren(&[]));
|
root_scope.update_scope_dependencies(&root_caller);
|
||||||
|
|
||||||
drop(root_props);
|
drop(root_props);
|
||||||
|
|
||||||
|
|||||||
@@ -22,13 +22,13 @@ fn new_dom<P: 'static + Send>(app: FC<P>, props: P) -> VirtualDom {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_original_diff() {
|
fn test_original_diff() {
|
||||||
static APP: FC<()> = |(cx, props)| {
|
static APP: FC<()> = |(cx, props)| {
|
||||||
rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
div {
|
div {
|
||||||
"Hello, world!"
|
"Hello, world!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut dom = new_dom(APP, ());
|
let mut dom = new_dom(APP, ());
|
||||||
@@ -58,7 +58,7 @@ fn test_original_diff() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn create() {
|
fn create() {
|
||||||
static APP: FC<()> = |(cx, props)| {
|
static APP: FC<()> = |(cx, props)| {
|
||||||
rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
div {
|
div {
|
||||||
"Hello, world!"
|
"Hello, world!"
|
||||||
@@ -72,7 +72,7 @@ fn create() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut dom = new_dom(APP, ());
|
let mut dom = new_dom(APP, ());
|
||||||
@@ -121,11 +121,11 @@ fn create() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn create_list() {
|
fn create_list() {
|
||||||
static APP: FC<()> = |(cx, props)| {
|
static APP: FC<()> = |(cx, props)| {
|
||||||
rsx! {
|
cx.render(rsx! {
|
||||||
{(0..3).map(|f| rsx!{ div {
|
{(0..3).map(|f| rsx!{ div {
|
||||||
"hello"
|
"hello"
|
||||||
}})}
|
}})}
|
||||||
}
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut dom = new_dom(APP, ());
|
let mut dom = new_dom(APP, ());
|
||||||
@@ -170,12 +170,12 @@ fn create_list() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn create_simple() {
|
fn create_simple() {
|
||||||
static APP: FC<()> = |(cx, props)| {
|
static APP: FC<()> = |(cx, props)| {
|
||||||
rsx! {
|
cx.render(rsx! {
|
||||||
div {}
|
div {}
|
||||||
div {}
|
div {}
|
||||||
div {}
|
div {}
|
||||||
div {}
|
div {}
|
||||||
}
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut dom = new_dom(APP, ());
|
let mut dom = new_dom(APP, ());
|
||||||
@@ -208,19 +208,19 @@ fn create_simple() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn create_components() {
|
fn create_components() {
|
||||||
static App: FC<()> = |(cx, props)| {
|
static App: FC<()> = |(cx, props)| {
|
||||||
rsx! {
|
cx.render(rsx! {
|
||||||
Child { "abc1" }
|
Child { "abc1" }
|
||||||
Child { "abc2" }
|
Child { "abc2" }
|
||||||
Child { "abc3" }
|
Child { "abc3" }
|
||||||
}
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
static Child: FC<()> = |(cx, props)| {
|
static Child: FC<()> = |(cx, props)| {
|
||||||
rsx! {
|
cx.render(rsx! {
|
||||||
h1 {}
|
h1 {}
|
||||||
div { {cx.children()} }
|
div { {cx.children()} }
|
||||||
p {}
|
p {}
|
||||||
}
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut dom = new_dom(App, ());
|
let mut dom = new_dom(App, ());
|
||||||
@@ -269,10 +269,10 @@ fn create_components() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn anchors() {
|
fn anchors() {
|
||||||
static App: FC<()> = |(cx, props)| {
|
static App: FC<()> = |(cx, props)| {
|
||||||
rsx! {
|
cx.render(rsx! {
|
||||||
{true.then(|| rsx!{ div { "hello" } })}
|
{true.then(|| rsx!{ div { "hello" } })}
|
||||||
{false.then(|| rsx!{ div { "goodbye" } })}
|
{false.then(|| rsx!{ div { "goodbye" } })}
|
||||||
}
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut dom = new_dom(App, ());
|
let mut dom = new_dom(App, ());
|
||||||
@@ -303,9 +303,23 @@ fn suspended() {
|
|||||||
|| async {
|
|| async {
|
||||||
//
|
//
|
||||||
},
|
},
|
||||||
|cx, p| rsx! { "hi "},
|
|cx, p| todo!(),
|
||||||
|
// |cx, p| rsx! { "hi "},
|
||||||
);
|
);
|
||||||
rsx! { {val} }
|
|
||||||
|
// let prom = use_task(fetch());
|
||||||
|
|
||||||
|
// Value {
|
||||||
|
// a: value.await,
|
||||||
|
// b: value.await,
|
||||||
|
// f: a.await
|
||||||
|
// div {
|
||||||
|
// div {
|
||||||
|
// hidden: should_hide.await,
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
cx.render(rsx! { {val} })
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut dom = new_dom(App, ());
|
let mut dom = new_dom(App, ());
|
||||||
|
|||||||
@@ -433,11 +433,11 @@ fn keyed_diffing_order() {
|
|||||||
let dom = new_dom();
|
let dom = new_dom();
|
||||||
|
|
||||||
let left = rsx!(
|
let left = rsx!(
|
||||||
{(0..5).map(|f| {rsx! { div { key: "{f}" }}})}
|
// {(0..5).map(|f| {rsx! { div { key: "{f}" }}})}
|
||||||
p {"e"}
|
p {"e"}
|
||||||
);
|
);
|
||||||
let right = rsx!(
|
let right = rsx!(
|
||||||
{(0..2).map(|f| {rsx! { div { key: "{f}" }}})}
|
{(0..2).map(|f| rsx! { div { key: "{f}" }})}
|
||||||
p {"e"}
|
p {"e"}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -807,16 +807,17 @@ fn controlled_keyed_diffing_out_of_order_max_test() {
|
|||||||
fn suspense() {
|
fn suspense() {
|
||||||
let dom = new_dom();
|
let dom = new_dom();
|
||||||
|
|
||||||
let edits = dom.create(Some(LazyNodes::new(|f| {
|
todo!()
|
||||||
use std::cell::{Cell, RefCell};
|
// let edits = dom.create(Some(LazyNodes::new(|f| {
|
||||||
VNode::Suspended(f.bump().alloc(VSuspended {
|
// use std::cell::{Cell, RefCell};
|
||||||
task_id: 0,
|
// VNode::Suspended(f.bump().alloc(VSuspended {
|
||||||
callback: RefCell::new(None),
|
// task_id: 0,
|
||||||
dom_id: Cell::new(None),
|
// callback: RefCell::new(None),
|
||||||
}))
|
// dom_id: Cell::new(None),
|
||||||
})));
|
// }))
|
||||||
assert_eq!(
|
// })));
|
||||||
edits.edits,
|
// assert_eq!(
|
||||||
[CreatePlaceholder { root: 0 }, AppendChildren { many: 1 }]
|
// edits.edits,
|
||||||
);
|
// [CreatePlaceholder { root: 0 }, AppendChildren { many: 1 }]
|
||||||
|
// );
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ fn manual_diffing() {
|
|||||||
|
|
||||||
static App: FC<AppProps> = |(cx, props)| {
|
static App: FC<AppProps> = |(cx, props)| {
|
||||||
let val = props.value.lock().unwrap();
|
let val = props.value.lock().unwrap();
|
||||||
rsx! { div { "{val}" } }
|
cx.render(rsx! { div { "{val}" } })
|
||||||
};
|
};
|
||||||
|
|
||||||
let value = Arc::new(Mutex::new("Hello"));
|
let value = Arc::new(Mutex::new("Hello"));
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ fn shared_state_test() {
|
|||||||
|
|
||||||
static App: FC<()> = |(cx, props)| {
|
static App: FC<()> = |(cx, props)| {
|
||||||
cx.provide_state(MySharedState("world!"));
|
cx.provide_state(MySharedState("world!"));
|
||||||
rsx!(Child {})
|
cx.render(rsx!(Child {}))
|
||||||
};
|
};
|
||||||
|
|
||||||
static Child: FC<()> = |(cx, props)| {
|
static Child: FC<()> = |(cx, props)| {
|
||||||
let shared = cx.consume_state::<MySharedState>()?;
|
let shared = cx.consume_state::<MySharedState>()?;
|
||||||
rsx!("Hello, {shared.0}")
|
cx.render(rsx!("Hello, {shared.0}"))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut dom = VirtualDom::new(App);
|
let mut dom = VirtualDom::new(App);
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ use dioxus_html as dioxus_elements;
|
|||||||
fn app_runs() {
|
fn app_runs() {
|
||||||
static App: FC<()> = |(cx, props)| {
|
static App: FC<()> = |(cx, props)| {
|
||||||
//
|
//
|
||||||
rsx!( div{"hello"} )
|
cx.render(rsx!( div{"hello"} ))
|
||||||
};
|
};
|
||||||
let mut vdom = VirtualDom::new(App);
|
let mut vdom = VirtualDom::new(App);
|
||||||
let edits = vdom.rebuild();
|
let edits = vdom.rebuild();
|
||||||
@@ -29,10 +29,10 @@ fn app_runs() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn fragments_work() {
|
fn fragments_work() {
|
||||||
static App: FC<()> = |(cx, props)| {
|
static App: FC<()> = |(cx, props)| {
|
||||||
rsx!(
|
cx.render(rsx!(
|
||||||
div{"hello"}
|
div{"hello"}
|
||||||
div{"goodbye"}
|
div{"goodbye"}
|
||||||
)
|
))
|
||||||
};
|
};
|
||||||
let mut vdom = VirtualDom::new(App);
|
let mut vdom = VirtualDom::new(App);
|
||||||
let edits = vdom.rebuild();
|
let edits = vdom.rebuild();
|
||||||
@@ -43,10 +43,10 @@ fn fragments_work() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn lists_work() {
|
fn lists_work() {
|
||||||
static App: FC<()> = |(cx, props)| {
|
static App: FC<()> = |(cx, props)| {
|
||||||
rsx!(
|
cx.render(rsx!(
|
||||||
h1 {"hello"}
|
h1 {"hello"}
|
||||||
{(0..6).map(|f| rsx!(span{ "{f}" }))}
|
{(0..6).map(|f| rsx!(span{ "{f}" }))}
|
||||||
)
|
))
|
||||||
};
|
};
|
||||||
let mut vdom = VirtualDom::new(App);
|
let mut vdom = VirtualDom::new(App);
|
||||||
let edits = vdom.rebuild();
|
let edits = vdom.rebuild();
|
||||||
@@ -56,11 +56,11 @@ fn lists_work() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn conditional_rendering() {
|
fn conditional_rendering() {
|
||||||
static App: FC<()> = |(cx, props)| {
|
static App: FC<()> = |(cx, props)| {
|
||||||
rsx!(
|
cx.render(rsx!(
|
||||||
h1 {"hello"}
|
h1 {"hello"}
|
||||||
{true.then(|| rsx!(span{ "a" }))}
|
{true.then(|| rsx!(span{ "a" }))}
|
||||||
{false.then(|| rsx!(span{ "b" }))}
|
{false.then(|| rsx!(span{ "b" }))}
|
||||||
)
|
))
|
||||||
};
|
};
|
||||||
let mut vdom = VirtualDom::new(App);
|
let mut vdom = VirtualDom::new(App);
|
||||||
|
|
||||||
@@ -73,16 +73,16 @@ fn conditional_rendering() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn child_components() {
|
fn child_components() {
|
||||||
static App: FC<()> = |(cx, props)| {
|
static App: FC<()> = |(cx, props)| {
|
||||||
rsx!(
|
cx.render(rsx!(
|
||||||
{true.then(|| rsx!(Child { }))}
|
{true.then(|| rsx!(Child { }))}
|
||||||
{false.then(|| rsx!(Child { }))}
|
{false.then(|| rsx!(Child { }))}
|
||||||
)
|
))
|
||||||
};
|
};
|
||||||
static Child: FC<()> = |(cx, props)| {
|
static Child: FC<()> = |(cx, props)| {
|
||||||
rsx!(
|
cx.render(rsx!(
|
||||||
h1 {"hello"}
|
h1 {"hello"}
|
||||||
h1 {"goodbye"}
|
h1 {"goodbye"}
|
||||||
)
|
))
|
||||||
};
|
};
|
||||||
let mut vdom = VirtualDom::new(App);
|
let mut vdom = VirtualDom::new(App);
|
||||||
let edits = vdom.rebuild();
|
let edits = vdom.rebuild();
|
||||||
@@ -92,8 +92,9 @@ fn child_components() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn suspended_works() {
|
fn suspended_works() {
|
||||||
static App: FC<()> = |(cx, props)| {
|
static App: FC<()> = |(cx, props)| {
|
||||||
let title = use_suspense(cx, || async { "bob" }, move |cx, f| rsx! { "{f}"});
|
let title = use_suspense(cx, || async { "bob" }, move |cx, f| todo!());
|
||||||
rsx!("hello" { title })
|
// let title = use_suspense(cx, || async { "bob" }, move |cx, f| rsx! { "{f}"});
|
||||||
|
cx.render(rsx!("hello" { title }))
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut vdom = VirtualDom::new(App);
|
let mut vdom = VirtualDom::new(App);
|
||||||
|
|||||||
Reference in new issue
Block a user