wip: no more lifetimes

This commit is contained in:
Jonathan Kelley committed 2021-11-06 21:07:01 -04:00
1 parent 857c92f7f0
commit d96276a715
6 files changed
+38 -25

No files matched your search

+2 -2
View File
@@ -99,7 +99,7 @@ impl<'a> Properties for FragmentProps<'a> {
/// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it. /// 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)] #[allow(non_upper_case_globals, non_snake_case)]
pub fn Fragment<'a>((cx, props): Scope<'a, FragmentProps<'a>>) -> Element<'a> { pub fn Fragment<'a>((cx, props): Scope<'a, FragmentProps<'a>>) -> Element {
cx.render(Some(LazyNodes::new(|f| { cx.render(Some(LazyNodes::new(|f| {
f.fragment_from_iter(&props.children) f.fragment_from_iter(&props.children)
}))) })))
@@ -170,6 +170,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<'a, T: Properties + 'a>(_: fn(Scope<'a, T>) -> Element<'a>) -> T::Builder { pub fn fc_to_builder<'a, T: Properties + 'a>(_: fn(Scope<'a, T>) -> Element) -> T::Builder {
T::builder() T::builder()
} }
+2 -2
View File
@@ -95,11 +95,11 @@ pub fn use_suspense<'src, Out, Fut, Cb>(
cx: Context<'src>, cx: Context<'src>,
task_initializer: impl FnOnce() -> Fut, task_initializer: impl FnOnce() -> Fut,
user_callback: Cb, user_callback: Cb,
) -> Element<'src> ) -> Element
where where
Fut: Future<Output = Out>, Fut: Future<Output = Out>,
Out: 'static, Out: 'static,
Cb: FnMut(&Out) -> Element<'src> + 'src, Cb: FnMut(&Out) -> Element + 'src,
{ {
/* /*
General strategy: General strategy:
+2 -2
View File
@@ -48,8 +48,8 @@ pub(crate) mod innerlude {
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 = Option<CachedNode>;
pub type FC<P> = for<'a> fn(Scope<'a, P>) -> Element<'a>; pub type FC<P> = for<'a> fn(Scope<'a, P>) -> CachedNode;
} }
pub use crate::innerlude::{ pub use crate::innerlude::{
+16 -4
View File
@@ -14,6 +14,18 @@ use std::{
fmt::{Arguments, Debug, Formatter}, fmt::{Arguments, Debug, Formatter},
}; };
/// A cached node is a "pointer" to a "rendered" node in a particular scope
///
/// It does not provide direct access to the node, so it doesn't carry any lifetime information with it
///
/// It is used during the diffing/rendering process as a runtime key into an existing set of nodes. The "render" key
/// is essentially a unique key to guarantee safe usage of the Node.
pub struct CachedNode {
frame_id: u32,
gen_id: u32,
scope_id: ScopeId,
}
/// A composable "VirtualNode" to declare a User Interface in the Dioxus VirtualDOM. /// A composable "VirtualNode" to declare a User Interface in the Dioxus VirtualDOM.
/// ///
/// VNodes are designed to be lightweight and used with with a bump allocator. To create a VNode, you can use either of: /// VNodes are designed to be lightweight and used with with a bump allocator. To create a VNode, you can use either of:
@@ -335,8 +347,8 @@ pub struct VComponent<'src> {
} }
pub enum VCompCaller<'src> { pub enum VCompCaller<'src> {
Borrowed(BumpBox<'src, dyn for<'b> Fn(&'b ScopeInner) -> Element<'b> + 'src>), Borrowed(BumpBox<'src, dyn for<'b> Fn(&'b ScopeInner) -> Element + 'src>),
Owned(Box<dyn for<'b> Fn(&'b ScopeInner) -> Element<'b>>), Owned(Box<dyn for<'b> Fn(&'b ScopeInner) -> Element>),
} }
pub struct VSuspended<'a> { pub struct VSuspended<'a> {
@@ -344,7 +356,7 @@ pub struct VSuspended<'a> {
pub dom_id: Cell<Option<ElementId>>, pub dom_id: Cell<Option<ElementId>>,
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
pub callback: RefCell<Option<BumpBox<'a, dyn FnMut() -> Element<'a> + 'a>>>, pub callback: RefCell<Option<BumpBox<'a, dyn FnMut() -> Element + 'a>>>,
} }
/// This struct provides an ergonomic API to quickly build VNodes. /// This struct provides an ergonomic API to quickly build VNodes.
@@ -481,7 +493,7 @@ impl<'a> NodeFactory<'a> {
pub fn component<P, P1>( pub fn component<P, P1>(
&self, &self,
component: fn(Scope<'a, P>) -> Element<'a>, component: fn(Scope<'a, P>) -> Element,
props: P, props: P,
key: Option<Arguments>, key: Option<Arguments>,
) -> VNode<'a> ) -> VNode<'a>
+7 -8
View File
@@ -173,7 +173,7 @@ impl ScopeInner {
let sus: &'a VSuspended<'static> = unsafe { &*suspended }; let sus: &'a VSuspended<'static> = unsafe { &*suspended };
let sus: &'a VSuspended<'a> = unsafe { std::mem::transmute(sus) }; let sus: &'a VSuspended<'a> = unsafe { std::mem::transmute(sus) };
let mut boxed = sus.callback.borrow_mut().take().unwrap(); let mut boxed = sus.callback.borrow_mut().take().unwrap();
let new_node: Element<'a> = boxed(); let new_node: Element = boxed();
} }
} }
@@ -366,13 +366,12 @@ impl ScopeInner {
/// cx.render(lazy_tree) /// cx.render(lazy_tree)
/// } /// }
///``` ///```
pub fn render<'src>( pub fn render<'src>(&'src self, lazy_nodes: Option<LazyNodes<'src, '_>>) -> Option<CachedNode> {
&'src self, todo!()
lazy_nodes: Option<LazyNodes<'src, '_>>, // ) -> Option<VNode<'src>> {
) -> Option<VNode<'src>> { // let bump = &self.frames.wip_frame().bump;
let bump = &self.frames.wip_frame().bump; // let factory = NodeFactory { bump };
let factory = NodeFactory { bump }; // lazy_nodes.map(|f| f.call(factory))
lazy_nodes.map(|f| f.call(factory))
} }
/// Push an effect to be ran after the component has been successfully mounted to the dom /// Push an effect to be ran after the component has been successfully mounted to the dom
+9 -7
View File
@@ -267,7 +267,8 @@ impl VirtualDom {
let root_caller: Box<dyn Fn(&ScopeInner) -> Element> = let root_caller: Box<dyn Fn(&ScopeInner) -> Element> =
Box::new(move |scope: &ScopeInner| unsafe { Box::new(move |scope: &ScopeInner| unsafe {
let props: &'_ P = &*(props_ptr as *const P); let props: &'_ P = &*(props_ptr as *const P);
std::mem::transmute(root((scope, props))) Some(root((scope, props)))
// std::mem::transmute()
}); });
drop(root_props); drop(root_props);
@@ -896,18 +897,19 @@ impl VirtualDom {
// temporarily cast the vcomponent to the right lifetime // temporarily cast the vcomponent to the right lifetime
let vcomp = scope.load_vcomp(); let vcomp = scope.load_vcomp();
let render: &dyn for<'b> Fn(&'b ScopeInner) -> Element<'b> = todo!(); let render: &dyn Fn(&ScopeInner) -> Element = todo!();
// Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders. // Todo: see if we can add stronger guarantees around internal bookkeeping and failed component renders.
if let Some(builder) = render(scope) { if let Some(builder) = render(scope) {
let new_head = builder.into_vnode(NodeFactory { todo!("attach the niode");
bump: &scope.frames.wip_frame().bump, // let new_head = builder.into_vnode(NodeFactory {
}); // bump: &scope.frames.wip_frame().bump,
// });
log::debug!("Render is successful"); log::debug!("Render is successful");
// the user's component succeeded. We can safely cycle to the next frame // the user's component succeeded. We can safely cycle to the next frame
scope.frames.wip_frame_mut().head_node = unsafe { std::mem::transmute(new_head) }; // scope.frames.wip_frame_mut().head_node = unsafe { std::mem::transmute(new_head) };
scope.frames.cycle_frame(); // scope.frames.cycle_frame();
true true
} else { } else {