wip: clean up using new children syntax

This commit is contained in:
Jonathan Kelley committed 2021-11-01 03:29:50 -04:00
1 parent d4192d0de2
commit 9c1343610b
6 files changed
+96 -85

No files matched your search

+24 -10
View File
@@ -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
-4
View File
@@ -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");
}
}
}
+34 -18
View File
@@ -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);
}
+16
View File
@@ -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
View File
@@ -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
}
}
}
+9 -40
View File
@@ -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) {
//
}
}