wip: clean up using new children syntax
This commit is contained in:
1 parent
d4192d0de2
commit
9c1343610b
6 files changed
+96
-85
No files matched your search
@@ -5,11 +5,7 @@
|
||||
//! if the type supports PartialEq. The Properties trait is used by the rsx! and html! macros to generate the type-safe builder
|
||||
//! that ensures compile-time required and optional fields on cx.
|
||||
|
||||
use crate::{
|
||||
innerlude::{Context, Element, FC},
|
||||
NodeFactory, VNode,
|
||||
};
|
||||
|
||||
use crate::innerlude::{Context, Element, VNode};
|
||||
/// A component is a wrapper around a Context and some Props that share a lifetime
|
||||
///
|
||||
///
|
||||
@@ -44,6 +40,27 @@ use crate::{
|
||||
///
|
||||
pub type Scope<'a, T> = (Context<'a>, &'a T);
|
||||
|
||||
pub struct FragmentProps<'a> {
|
||||
childen: &'a VNode<'a>,
|
||||
}
|
||||
pub struct FragmentPropsBuilder<'a> {
|
||||
childen: Option<&'a VNode<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> Properties for FragmentProps<'a> {
|
||||
type Builder = FragmentPropsBuilder<'a>;
|
||||
|
||||
const IS_STATIC: bool = false;
|
||||
|
||||
fn builder() -> Self::Builder {
|
||||
todo!()
|
||||
}
|
||||
|
||||
unsafe fn memoize(&self, other: &Self) -> bool {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
/// Create inline fragments using Component syntax.
|
||||
///
|
||||
/// Fragments capture a series of children without rendering extra nodes.
|
||||
@@ -66,11 +83,8 @@ 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.
|
||||
///
|
||||
#[allow(non_upper_case_globals, non_snake_case)]
|
||||
pub fn Fragment<'a>((cx, _): Scope<'a, ()>) -> Element<'a> {
|
||||
todo!()
|
||||
// let p: Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_> =
|
||||
// Box::new(|f: NodeFactory| f.fragment_from_iter(cx.children()));
|
||||
// cx.render(p)
|
||||
pub fn Fragment<'a>((_, props): Scope<'a, FragmentProps<'a>>) -> Element<'a> {
|
||||
Some(props.childen.decouple())
|
||||
}
|
||||
|
||||
/// Every "Props" used for a component must implement the `Properties` trait. This trait gives some hints to Dioxus
|
||||
|
||||
@@ -420,10 +420,6 @@ impl<'bump> DiffMachine<'bump> {
|
||||
) => self
|
||||
.stack
|
||||
.create_node(new_node, MountType::Replace { old: old_node }),
|
||||
|
||||
(Placeholder, _) | (_, Placeholder) => {
|
||||
unreachable!("placeholder should never be diffed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,21 +1,18 @@
|
||||
use std::mem;
|
||||
//! Support for storing lazy-nodes on the stack
|
||||
//!
|
||||
//! This module provides support for a type called `LazyNodes` which is a micro-heap located on the stack to make calls
|
||||
//! to `rsx!` more efficient.
|
||||
//!
|
||||
//! To support returning rsx! from branches in match statements, we need to use dynamic dispatch on NodeFactory closures.
|
||||
//!
|
||||
//! This can be done either through boxing directly, or by using dynamic-sized-types and a custom allocator. In our case,
|
||||
//! we build a tiny alloactor in the stack and allocate the closure into that.
|
||||
//!
|
||||
//! The logic for this was borrowed from https://docs.rs/stack_dst/0.6.1/stack_dst/. Unfortunately, this crate does not
|
||||
//! support non-static closures, so we've implemented the core logic of `ValueA` in this module.
|
||||
|
||||
/*
|
||||
Remember: calls to rsx! are lazy - they are not evaluated immediately.
|
||||
|
||||
They also using dynamic dispatch, so we can return multiple rsx!'s from match statements and such.
|
||||
|
||||
If we allocated every rsx! call on the heap, it would be quite wasteful. Rsx! calls are FnOnce, so they can be stored in a stack.
|
||||
|
||||
Solutions like stackdst are useful, but they only support 'static closures.
|
||||
|
||||
All our closures are bound by the bump lifetime, so stack-dst will not work for us
|
||||
|
||||
Our solution is to try and manually allocate the closure onto the stack.
|
||||
If it fails, then we default to Box.
|
||||
|
||||
*/
|
||||
use crate::innerlude::{NodeFactory, VNode};
|
||||
use std::mem;
|
||||
|
||||
/// A concrete type provider for closures that build VNode structures.
|
||||
///
|
||||
@@ -73,13 +70,13 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
|
||||
let size = mem::size_of::<F>();
|
||||
|
||||
if info.len() * mem::size_of::<usize>() + size > mem::size_of::<StackHeapSize>() {
|
||||
log::error!("lazy nodes was too large to fit into stack. falling back to heap");
|
||||
log::debug!("lazy nodes was too large to fit into stack. falling back to heap");
|
||||
|
||||
Self {
|
||||
inner: StackNodeStorage::Heap(Box::new(val)),
|
||||
}
|
||||
} else {
|
||||
log::error!("lazy nodes fits on stack!");
|
||||
log::debug!("lazy nodes fits on stack!");
|
||||
let mut buf: StackHeapSize = [0; 12];
|
||||
|
||||
assert!(info.len() + round_to_words(size) <= buf.as_ref().len());
|
||||
@@ -173,3 +170,22 @@ unsafe fn make_fat_ptr<T: ?Sized>(data_ptr: usize, meta_vals: &[usize]) -> *mut
|
||||
fn round_to_words(len: usize) -> usize {
|
||||
(len + mem::size_of::<usize>() - 1) / mem::size_of::<usize>()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let bump = bumpalo::Bump::new();
|
||||
|
||||
simple_logger::init();
|
||||
|
||||
let factory = NodeFactory { bump: &bump };
|
||||
|
||||
let caller = NodeFactory::annotate_lazy(|f| {
|
||||
//
|
||||
f.text(format_args!("hello world!"))
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let g = caller.call(factory);
|
||||
|
||||
dbg!(g);
|
||||
}
|
||||
@@ -155,6 +155,22 @@ impl<'src> VNode<'src> {
|
||||
VNode::Component(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
// Create an "owned" version of the vnode.
|
||||
pub fn decouple(&self) -> VNode<'src> {
|
||||
match self {
|
||||
VNode::Text(t) => VNode::Text(*t),
|
||||
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,
|
||||
key: f.key,
|
||||
is_static: f.is_static,
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A placeholder node only generated when Fragments don't have any children.
|
||||
|
||||
+13
-13
@@ -341,21 +341,21 @@ impl ScopeInner {
|
||||
|
||||
// Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders.
|
||||
//
|
||||
todo!()
|
||||
// if let Some(builder) = render(self) {
|
||||
// let new_head = builder.into_vnode(NodeFactory {
|
||||
// bump: &self.frames.wip_frame().bump,
|
||||
// });
|
||||
// log::debug!("Render is successful");
|
||||
// todo!()
|
||||
if let Some(builder) = render(self) {
|
||||
let new_head = builder.into_vnode(NodeFactory {
|
||||
bump: &self.frames.wip_frame().bump,
|
||||
});
|
||||
log::debug!("Render is successful");
|
||||
|
||||
// // the user's component succeeded. We can safely cycle to the next frame
|
||||
// self.frames.wip_frame_mut().head_node = unsafe { std::mem::transmute(new_head) };
|
||||
// self.frames.cycle_frame();
|
||||
// the user's component succeeded. We can safely cycle to the next frame
|
||||
self.frames.wip_frame_mut().head_node = unsafe { std::mem::transmute(new_head) };
|
||||
self.frames.cycle_frame();
|
||||
|
||||
// true
|
||||
// } else {
|
||||
// false
|
||||
// }
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -21,27 +21,13 @@ impl TestDom {
|
||||
NodeFactory::new(&self.bump)
|
||||
}
|
||||
|
||||
pub fn render_direct<'a>(
|
||||
&'a self,
|
||||
lazy_nodes: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
|
||||
) -> VNode<'a>
|
||||
// where
|
||||
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
||||
{
|
||||
todo!()
|
||||
// lazy_nodes.into_vnode(NodeFactory::new(&self.bump))
|
||||
pub fn render_direct<'a>(&'a self, lazy_nodes: Option<LazyNodes<'a, '_>>) -> VNode<'a> {
|
||||
lazy_nodes.into_vnode(NodeFactory::new(&self.bump))
|
||||
}
|
||||
|
||||
pub fn render<'a>(
|
||||
&'a self,
|
||||
lazy_nodes: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
|
||||
) -> &'a VNode<'a>
|
||||
// where
|
||||
// F: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
||||
{
|
||||
todo!()
|
||||
// self.bump
|
||||
// .alloc(lazy_nodes.into_vnode(NodeFactory::new(&self.bump)))
|
||||
pub fn render<'a>(&'a self, lazy_nodes: Option<LazyNodes<'a, '_>>) -> &'a VNode<'a> {
|
||||
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> {
|
||||
@@ -51,14 +37,7 @@ impl TestDom {
|
||||
machine.mutations
|
||||
}
|
||||
|
||||
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>
|
||||
// where
|
||||
// F1: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
||||
{
|
||||
pub fn create<'a>(&'a self, left: Option<LazyNodes<'a, '_>>) -> Mutations<'a> {
|
||||
let old = self.bump.alloc(self.render_direct(left));
|
||||
|
||||
let mut machine = DiffMachine::new(Mutations::new(), &self.scheduler.pool);
|
||||
@@ -72,13 +51,9 @@ impl TestDom {
|
||||
|
||||
pub fn lazy_diff<'a>(
|
||||
&'a self,
|
||||
left: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
|
||||
right: Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>>,
|
||||
) -> (Mutations<'a>, Mutations<'a>)
|
||||
// where
|
||||
// F1: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
||||
// F2: FnOnce(NodeFactory<'a>) -> VNode<'a>,
|
||||
{
|
||||
left: Option<LazyNodes<'a, '_>>,
|
||||
right: Option<LazyNodes<'a, '_>>,
|
||||
) -> (Mutations<'a>, Mutations<'a>) {
|
||||
let (old, new) = (self.render(left), self.render(right));
|
||||
|
||||
let mut machine = DiffMachine::new(Mutations::new(), &self.scheduler.pool);
|
||||
@@ -105,9 +80,3 @@ impl Default for TestDom {
|
||||
Self::new()
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualDom {
|
||||
pub fn simulate(&mut self) {
|
||||
//
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user