Procházet zdrojové kódy

wip: no more lifetimes

Jonathan Kelley před 3 roky
rodič
revize
d96276a

+ 2 - 2
packages/core/src/component.rs

@@ -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.
 ///
 #[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| {
         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
 /// 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()
 }

+ 2 - 2
packages/core/src/hooks.rs

@@ -95,11 +95,11 @@ pub fn use_suspense<'src, Out, Fut, Cb>(
     cx: Context<'src>,
     task_initializer: impl FnOnce() -> Fut,
     user_callback: Cb,
-) -> Element<'src>
+) -> Element
 where
     Fut: Future<Output = Out>,
     Out: 'static,
-    Cb: FnMut(&Out) -> Element<'src> + 'src,
+    Cb: FnMut(&Out) -> Element + 'src,
 {
     /*
     General strategy:

+ 2 - 2
packages/core/src/lib.rs

@@ -48,8 +48,8 @@ pub(crate) mod innerlude {
     pub use crate::util::*;
     pub use crate::virtual_dom::*;
 
-    pub type Element<'a> = Option<VNode<'a>>;
-    pub type FC<P> = for<'a> fn(Scope<'a, P>) -> Element<'a>;
+    pub type Element = Option<CachedNode>;
+    pub type FC<P> = for<'a> fn(Scope<'a, P>) -> CachedNode;
 }
 
 pub use crate::innerlude::{

+ 16 - 4
packages/core/src/nodes.rs

@@ -14,6 +14,18 @@ use std::{
     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.
 ///
 /// 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> {
-    Borrowed(BumpBox<'src, dyn for<'b> Fn(&'b ScopeInner) -> Element<'b> + 'src>),
-    Owned(Box<dyn for<'b> Fn(&'b ScopeInner) -> Element<'b>>),
+    Borrowed(BumpBox<'src, dyn for<'b> Fn(&'b ScopeInner) -> Element + 'src>),
+    Owned(Box<dyn for<'b> Fn(&'b ScopeInner) -> Element>),
 }
 
 pub struct VSuspended<'a> {
@@ -344,7 +356,7 @@ pub struct VSuspended<'a> {
     pub dom_id: Cell<Option<ElementId>>,
 
     #[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.
@@ -481,7 +493,7 @@ impl<'a> NodeFactory<'a> {
 
     pub fn component<P, P1>(
         &self,
-        component: fn(Scope<'a, P>) -> Element<'a>,
+        component: fn(Scope<'a, P>) -> Element,
         props: P,
         key: Option<Arguments>,
     ) -> VNode<'a>

+ 7 - 8
packages/core/src/scope.rs

@@ -173,7 +173,7 @@ impl ScopeInner {
             let sus: &'a VSuspended<'static> = unsafe { &*suspended };
             let sus: &'a VSuspended<'a> = unsafe { std::mem::transmute(sus) };
             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)
     /// }
     ///```
-    pub fn render<'src>(
-        &'src self,
-        lazy_nodes: Option<LazyNodes<'src, '_>>,
-    ) -> Option<VNode<'src>> {
-        let bump = &self.frames.wip_frame().bump;
-        let factory = NodeFactory { bump };
-        lazy_nodes.map(|f| f.call(factory))
+    pub fn render<'src>(&'src self, lazy_nodes: Option<LazyNodes<'src, '_>>) -> Option<CachedNode> {
+        todo!()
+        // ) -> Option<VNode<'src>> {
+        // let bump = &self.frames.wip_frame().bump;
+        // let factory = NodeFactory { bump };
+        // lazy_nodes.map(|f| f.call(factory))
     }
 
     /// Push an effect to be ran after the component has been successfully mounted to the dom

+ 9 - 7
packages/core/src/virtual_dom.rs

@@ -267,7 +267,8 @@ impl VirtualDom {
             let root_caller: Box<dyn Fn(&ScopeInner) -> Element> =
                 Box::new(move |scope: &ScopeInner| unsafe {
                     let props: &'_ P = &*(props_ptr as *const P);
-                    std::mem::transmute(root((scope, props)))
+                    Some(root((scope, props)))
+                    // std::mem::transmute()
                 });
 
             drop(root_props);
@@ -896,18 +897,19 @@ impl VirtualDom {
         // temporarily cast the vcomponent to the right lifetime
         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.
         if let Some(builder) = render(scope) {
-            let new_head = builder.into_vnode(NodeFactory {
-                bump: &scope.frames.wip_frame().bump,
-            });
+            todo!("attach the niode");
+            // let new_head = builder.into_vnode(NodeFactory {
+            //     bump: &scope.frames.wip_frame().bump,
+            // });
             log::debug!("Render is successful");
 
             // 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.cycle_frame();
+            // scope.frames.wip_frame_mut().head_node = unsafe { std::mem::transmute(new_head) };
+            // scope.frames.cycle_frame();
 
             true
         } else {