wip: implement lazy nodes properly
This commit is contained in:
1 parent
7b97e009ec
commit
3e07214272
7 files changed
+47
-67
No files matched your search
@@ -17,7 +17,7 @@ pub static EXAMPLE: FC<()> = |(cx, _)| {
|
|||||||
});
|
});
|
||||||
// let list = (0..10).map(|_f| Some(Box::new(move |_f| todo!())));
|
// let list = (0..10).map(|_f| Some(Box::new(move |_f| todo!())));
|
||||||
|
|
||||||
cx.render(Some(Box::new(move |cx| {
|
cx.render(Some(LazyNodes::new(move |cx| {
|
||||||
cx.raw_element(
|
cx.raw_element(
|
||||||
"div",
|
"div",
|
||||||
None,
|
None,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use std::marker::PhantomData;
|
|||||||
|
|
||||||
use dioxus::component::Scope;
|
use dioxus::component::Scope;
|
||||||
use dioxus::events::on::MouseEvent;
|
use dioxus::events::on::MouseEvent;
|
||||||
use dioxus::nodes::{annotate_lazy, IntoVNode, VComponent, VFragment, VText};
|
use dioxus::nodes::{IntoVNode, VComponent, VFragment, VText};
|
||||||
use dioxus_core as dioxus;
|
use dioxus_core as dioxus;
|
||||||
use dioxus_core::prelude::*;
|
use dioxus_core::prelude::*;
|
||||||
use dioxus_core_macro::*;
|
use dioxus_core_macro::*;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use dioxus_core::prelude::*;
|
use dioxus_core::{lazynodes::LazyNodes, prelude::*};
|
||||||
|
|
||||||
// #[async_std::main]
|
// #[async_std::main]
|
||||||
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(LazyNodes::new(move |f| f.text(format_args!("hello")))));
|
||||||
|
|
||||||
let mut dom = VirtualDom::new(App);
|
let mut dom = VirtualDom::new(App);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
use bumpalo::Bump;
|
use bumpalo::Bump;
|
||||||
|
|
||||||
use crate::innerlude::*;
|
use crate::{innerlude::*, lazynodes::LazyNodes};
|
||||||
use std::{any::TypeId, ops::Deref, rc::Rc};
|
use std::{any::TypeId, ops::Deref, rc::Rc};
|
||||||
|
|
||||||
/// Components in Dioxus use the "Context" object to interact with their lifecycle.
|
/// Components in Dioxus use the "Context" object to interact with their lifecycle.
|
||||||
@@ -103,11 +103,12 @@ 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<LazyNodes<'src, '_>>,
|
||||||
|
// lazy_nodes: Option<Box<dyn FnOnce(NodeFactory<'src>) -> VNode<'src> + '_>>,
|
||||||
) -> Option<VNode<'src>> {
|
) -> Option<VNode<'src>> {
|
||||||
let bump = &self.scope.frames.wip_frame().bump;
|
let bump = &self.scope.frames.wip_frame().bump;
|
||||||
let factory = NodeFactory { bump };
|
let factory = NodeFactory { bump };
|
||||||
lazy_nodes.map(|f| f(factory))
|
lazy_nodes.map(|f| f.call(factory))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `submit_task` will submit the future to be polled.
|
/// `submit_task` will submit the future to be polled.
|
||||||
|
|||||||
@@ -26,29 +26,37 @@ 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, 'b> {
|
||||||
// inner: Box<F>,
|
inner: StackNodeStorage<'a, 'b>,
|
||||||
// _p: PhantomData<&'a ()>,
|
}
|
||||||
// // inner: StackNodeStorage<'a>,
|
|
||||||
// // inner: StackNodeStorage<'a>,
|
|
||||||
// }
|
|
||||||
// pub type LazyNodes<'b> = Box<dyn for<'a> FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>;
|
|
||||||
|
|
||||||
// pub fn to_lazy_nodes<'b>(
|
impl<'a, 'b> LazyNodes<'a, 'b> {
|
||||||
// f: impl for<'a> FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b,
|
pub fn new<F>(f: F) -> Self
|
||||||
// ) -> Option<LazyNodes<'b>> {
|
where
|
||||||
// Some(Box::new(f))
|
F: FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b,
|
||||||
// }
|
{
|
||||||
|
Self {
|
||||||
|
inner: StackNodeStorage::Heap(Box::new(f)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn call(self, f: NodeFactory<'a>) -> VNode<'a> {
|
||||||
|
match self.inner {
|
||||||
|
StackNodeStorage::Heap(lazy) => lazy(f),
|
||||||
|
_ => todo!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type StackHeapSize = [usize; 12];
|
type StackHeapSize = [usize; 12];
|
||||||
|
|
||||||
enum StackNodeStorage<'a> {
|
enum StackNodeStorage<'a, 'b> {
|
||||||
Stack {
|
Stack {
|
||||||
next_ofs: usize,
|
next_ofs: usize,
|
||||||
buf: StackHeapSize,
|
buf: StackHeapSize,
|
||||||
width: usize,
|
width: usize,
|
||||||
},
|
},
|
||||||
Heap(Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a>>),
|
Heap(Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// impl<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> LazyNodes<'a, F> {
|
// impl<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>> LazyNodes<'a, F> {
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ pub mod context;
|
|||||||
pub mod diff;
|
pub mod diff;
|
||||||
pub mod diff_stack;
|
pub mod diff_stack;
|
||||||
pub mod events;
|
pub mod events;
|
||||||
// pub mod events2;
|
|
||||||
pub mod heuristics;
|
pub mod heuristics;
|
||||||
pub mod hooklist;
|
pub mod hooklist;
|
||||||
pub mod hooks;
|
pub mod hooks;
|
||||||
@@ -46,6 +45,7 @@ pub(crate) mod innerlude {
|
|||||||
pub use crate::heuristics::*;
|
pub use crate::heuristics::*;
|
||||||
pub(crate) use crate::hooklist::*;
|
pub(crate) use crate::hooklist::*;
|
||||||
pub use crate::hooks::*;
|
pub use crate::hooks::*;
|
||||||
|
pub use crate::lazynodes::*;
|
||||||
pub use crate::mutations::*;
|
pub use crate::mutations::*;
|
||||||
pub use crate::nodes::*;
|
pub use crate::nodes::*;
|
||||||
pub(crate) use crate::resources::*;
|
pub(crate) use crate::resources::*;
|
||||||
@@ -56,7 +56,7 @@ pub(crate) mod innerlude {
|
|||||||
pub use crate::threadsafe::*;
|
pub use crate::threadsafe::*;
|
||||||
pub use crate::util::*;
|
pub use crate::util::*;
|
||||||
pub use crate::virtual_dom::*;
|
pub use crate::virtual_dom::*;
|
||||||
// pub type Element<'a> = Option<VNode<'a>>;
|
|
||||||
pub type Element<'a> = Option<VNode<'a>>;
|
pub type Element<'a> = Option<VNode<'a>>;
|
||||||
pub type FC<P> = for<'a> fn(Scope<'a, P>) -> Element<'a>;
|
pub type FC<P> = for<'a> fn(Scope<'a, P>) -> Element<'a>;
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ pub mod prelude {
|
|||||||
pub use crate::component::{fc_to_builder, Fragment, Properties, Scope};
|
pub use crate::component::{fc_to_builder, Fragment, Properties, Scope};
|
||||||
pub use crate::context::Context;
|
pub use crate::context::Context;
|
||||||
pub use crate::hooks::*;
|
pub use crate::hooks::*;
|
||||||
pub use crate::innerlude::{DioxusElement, Element, Mutations, NodeFactory, FC};
|
pub use crate::innerlude::{DioxusElement, Element, LazyNodes, NodeFactory, FC};
|
||||||
pub use crate::nodes::VNode;
|
pub use crate::nodes::VNode;
|
||||||
pub use crate::VirtualDom;
|
pub use crate::VirtualDom;
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-43
@@ -3,9 +3,12 @@
|
|||||||
//! VNodes represent lazily-constructed VDom trees that support diffing and event handlers. These VNodes should be *very*
|
//! VNodes represent lazily-constructed VDom trees that support diffing and event handlers. These VNodes should be *very*
|
||||||
//! cheap and *very* fast to construct - building a full tree should be quick.
|
//! cheap and *very* fast to construct - building a full tree should be quick.
|
||||||
|
|
||||||
use crate::innerlude::{
|
use crate::{
|
||||||
empty_cell, Context, Element, ElementId, Properties, Scope, ScopeId, ScopeInner,
|
innerlude::{
|
||||||
SuspendedContext, FC,
|
empty_cell, Context, Element, ElementId, Properties, Scope, ScopeId, ScopeInner,
|
||||||
|
SuspendedContext,
|
||||||
|
},
|
||||||
|
lazynodes::LazyNodes,
|
||||||
};
|
};
|
||||||
use bumpalo::{boxed::Box as BumpBox, Bump};
|
use bumpalo::{boxed::Box as BumpBox, Bump};
|
||||||
use std::{
|
use std::{
|
||||||
@@ -328,14 +331,6 @@ impl<'a> NodeFactory<'a> {
|
|||||||
self.bump
|
self.bump
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn unstable_place_holder(&self) -> VNode {
|
|
||||||
VNode::Text(self.bump.alloc(VText {
|
|
||||||
text: "",
|
|
||||||
dom_id: empty_cell(),
|
|
||||||
is_static: true,
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Directly pass in text blocks without the need to use the format_args macro.
|
/// Directly pass in text blocks without the need to use the format_args macro.
|
||||||
pub fn static_text(&self, text: &'static str) -> VNode<'a> {
|
pub fn static_text(&self, text: &'static str) -> VNode<'a> {
|
||||||
VNode::Text(self.bump.alloc(VText {
|
VNode::Text(self.bump.alloc(VText {
|
||||||
@@ -449,23 +444,6 @@ impl<'a> NodeFactory<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn component_v2_borrowed<P: 'a>(
|
|
||||||
self,
|
|
||||||
f: impl Fn(Context<'a>) -> Option<VNode<'a>> + 'a,
|
|
||||||
fc: fn(Scope<'a, P>) -> Element<'a>,
|
|
||||||
p: &'a P,
|
|
||||||
) -> VNode<'a> {
|
|
||||||
//
|
|
||||||
todo!()
|
|
||||||
}
|
|
||||||
// pub fn component_v2_memoized(
|
|
||||||
// self,
|
|
||||||
// f: impl for<'b> Fn(Context<'b>) -> Option<VNode<'b>> + 'static,
|
|
||||||
// ) -> VNode<'a> {
|
|
||||||
// //
|
|
||||||
// todo!()
|
|
||||||
// }
|
|
||||||
|
|
||||||
pub fn component<P, V>(
|
pub fn component<P, V>(
|
||||||
&self,
|
&self,
|
||||||
component: fn(Scope<'a, P>) -> Element<'a>,
|
component: fn(Scope<'a, P>) -> Element<'a>,
|
||||||
@@ -609,13 +587,11 @@ impl<'a> NodeFactory<'a> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn annotate_lazy<'z, 'b, F>(
|
pub fn annotate_lazy<'z, 'b, F>(f: F) -> Option<LazyNodes<'z, 'b>>
|
||||||
f: F,
|
|
||||||
) -> Option<Box<dyn FnOnce(NodeFactory<'z>) -> VNode<'z> + 'b>>
|
|
||||||
where
|
where
|
||||||
F: FnOnce(NodeFactory<'z>) -> VNode<'z> + 'b,
|
F: FnOnce(NodeFactory<'z>) -> VNode<'z> + 'b,
|
||||||
{
|
{
|
||||||
Some(Box::new(f))
|
Some(LazyNodes::new(f))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -675,17 +651,11 @@ impl<'a> IntoVNode<'a> for Option<VNode<'a>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn annotate_lazy<'a, 'b, F>(f: F) -> Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b>>
|
impl<'a> IntoVNode<'a> for Option<LazyNodes<'a, '_>> {
|
||||||
where
|
// impl<'a> IntoVNode<'a> for Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_>> {
|
||||||
F: FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b,
|
|
||||||
{
|
|
||||||
Some(Box::new(f))
|
|
||||||
}
|
|
||||||
|
|
||||||
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(lazy) => lazy(cx),
|
Some(lazy) => lazy.call(cx),
|
||||||
None => VNode::Fragment(VFragment {
|
None => VNode::Fragment(VFragment {
|
||||||
children: &[],
|
children: &[],
|
||||||
is_static: false,
|
is_static: false,
|
||||||
@@ -695,9 +665,10 @@ impl<'a> IntoVNode<'a> for Option<Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> +
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> IntoVNode<'a> for Box<dyn FnOnce(NodeFactory<'a>) -> VNode<'a> + '_> {
|
impl<'a> IntoVNode<'a> for LazyNodes<'a, '_> {
|
||||||
|
// impl<'a> IntoVNode<'a> for 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> {
|
||||||
self(cx)
|
self.call(cx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user