ソースを参照

feat: wire up resource pool

Jonathan Kelley 3 年 前
コミット
31702db

+ 2 - 1
packages/core/src/childiter.rs

@@ -74,7 +74,8 @@ impl<'a> Iterator for RealChildIterator<'a> {
                     // For components, we load their root and push them onto the stack
                     VNode::Component(sc) => {
                         let scope =
-                            unsafe { self.scopes.get_scope(sc.ass_scope.get().unwrap()) }.unwrap();
+                            unsafe { self.scopes.get_scope(sc.associated_scope.get().unwrap()) }
+                                .unwrap();
                         // let scope = self.scopes.get(sc.ass_scope.get().unwrap()).unwrap();
 
                         // Simply swap the current node on the stack with the root of the component

+ 8 - 8
packages/core/src/diff.rs

@@ -341,7 +341,7 @@ impl<'bump> DiffMachine<'bump> {
         });
 
         // Actually initialize the caller's slot with the right address
-        vcomponent.ass_scope.set(Some(new_idx));
+        vcomponent.associated_scope.set(Some(new_idx));
 
         if !vcomponent.can_memoize {
             let cur_scope = self.vdom.get_scope_mut(parent_idx).unwrap();
@@ -357,7 +357,7 @@ impl<'bump> DiffMachine<'bump> {
         let new_component = self.vdom.get_scope_mut(new_idx).unwrap();
 
         // Run the scope for one iteration to initialize it
-        if new_component.run_scope() {
+        if new_component.run_scope(self.vdom) {
             // Take the node that was just generated from running the component
             let nextnode = new_component.frames.fin_head();
             self.stack.create_component(new_idx, nextnode);
@@ -505,7 +505,7 @@ impl<'bump> DiffMachine<'bump> {
         old: &'bump VComponent<'bump>,
         new: &'bump VComponent<'bump>,
     ) {
-        let scope_addr = old.ass_scope.get().unwrap();
+        let scope_addr = old.associated_scope.get().unwrap();
 
         // Make sure we're dealing with the same component (by function pointer)
         if old.user_fc == new.user_fc {
@@ -513,7 +513,7 @@ impl<'bump> DiffMachine<'bump> {
             self.stack.scope_stack.push(scope_addr);
 
             // Make sure the new component vnode is referencing the right scope id
-            new.ass_scope.set(Some(scope_addr));
+            new.associated_scope.set(Some(scope_addr));
 
             // make sure the component's caller function is up to date
             let scope = self.vdom.get_scope_mut(scope_addr).unwrap();
@@ -529,7 +529,7 @@ impl<'bump> DiffMachine<'bump> {
                 }
                 false => {
                     // the props are different...
-                    if scope.run_scope() {
+                    if scope.run_scope(self.vdom) {
                         self.diff_node(scope.frames.wip_head(), scope.frames.fin_head());
                     }
                 }
@@ -967,7 +967,7 @@ impl<'bump> DiffMachine<'bump> {
                     search_node = frag.children.last();
                 }
                 VNode::Component(el) => {
-                    let scope_id = el.ass_scope.get().unwrap();
+                    let scope_id = el.associated_scope.get().unwrap();
                     let scope = self.vdom.get_scope(scope_id).unwrap();
                     search_node = Some(scope.root());
                 }
@@ -985,7 +985,7 @@ impl<'bump> DiffMachine<'bump> {
                     search_node = Some(&frag.children[0]);
                 }
                 VNode::Component(el) => {
-                    let scope_id = el.ass_scope.get().unwrap();
+                    let scope_id = el.associated_scope.get().unwrap();
                     let scope = self.vdom.get_scope(scope_id).unwrap();
                     search_node = Some(scope.root());
                 }
@@ -1043,7 +1043,7 @@ impl<'bump> DiffMachine<'bump> {
                 }
 
                 VNode::Component(c) => {
-                    let scope_id = c.ass_scope.get().unwrap();
+                    let scope_id = c.associated_scope.get().unwrap();
                     let scope = self.vdom.get_scope(scope_id).unwrap();
                     let root = scope.root();
                     self.remove_nodes(Some(root));

+ 32 - 41
packages/core/src/nodes.rs

@@ -13,7 +13,6 @@ use std::{
     cell::{Cell, RefCell},
     fmt::{Arguments, Debug, Formatter},
     marker::PhantomData,
-    mem::ManuallyDrop,
     rc::Rc,
 };
 
@@ -43,8 +42,8 @@ impl<'src> VNode<'src> {
             VNode::Component(c) => c.key,
             VNode::Fragment(f) => f.key,
             VNode::Text(_t) => None,
-            VNode::Suspended(s) => None,
-            VNode::Anchor(f) => None,
+            VNode::Suspended(_s) => None,
+            VNode::Anchor(_f) => None,
         }
     }
     pub fn direct_id(&self) -> ElementId {
@@ -68,16 +67,36 @@ pub struct VAnchor {
 
 pub struct VText<'src> {
     pub text: &'src str,
+
     pub dom_id: Cell<Option<ElementId>>,
+
     pub is_static: bool,
 }
 
 pub struct VFragment<'src> {
-    pub children: &'src [VNode<'src>],
     pub key: Option<&'src str>,
+
+    pub children: &'src [VNode<'src>],
+
     pub is_static: bool,
 }
 
+pub struct VElement<'a> {
+    pub tag_name: &'static str,
+
+    pub namespace: Option<&'static str>,
+
+    pub key: Option<&'a str>,
+
+    pub dom_id: Cell<Option<ElementId>>,
+
+    pub listeners: &'a [Listener<'a>],
+
+    pub attributes: &'a [Attribute<'a>],
+
+    pub children: &'a [VNode<'a>],
+}
+
 pub trait DioxusElement {
     const TAG_NAME: &'static str;
     const NAME_SPACE: Option<&'static str>;
@@ -91,19 +110,6 @@ pub trait DioxusElement {
     }
 }
 
-pub struct VElement<'a> {
-    pub key: Option<&'a str>,
-
-    // tag is always static
-    pub tag_name: &'static str,
-    pub namespace: Option<&'static str>,
-    pub dom_id: Cell<Option<ElementId>>,
-
-    pub listeners: &'a [Listener<'a>],
-    pub attributes: &'a [Attribute<'a>],
-    pub children: &'a [VNode<'a>],
-}
-
 /// An attribute on a DOM node, such as `id="my-thing"` or
 /// `href="https://example.com"`.
 #[derive(Clone, Debug)]
@@ -131,22 +137,12 @@ pub struct Listener<'bump> {
     pub(crate) callback: RefCell<Option<BumpBox<'bump, dyn FnMut(SyntheticEvent) + 'bump>>>,
 }
 
-impl Listener<'_> {
-    // serialize the listener event stuff to a string
-    pub fn serialize(&self) {
-        //
-    }
-    pub fn deserialize() {
-        //
-    }
-}
-
 /// Virtual Components for custom user-defined components
 /// Only supports the functional syntax
 pub struct VComponent<'src> {
     pub key: Option<&'src str>,
 
-    pub ass_scope: Cell<Option<ScopeId>>,
+    pub associated_scope: Cell<Option<ScopeId>>,
 
     pub(crate) caller: Rc<dyn Fn(&Scope) -> DomTree>,
 
@@ -158,21 +154,19 @@ pub struct VComponent<'src> {
 
     pub is_static: bool,
 
-    pub can_memoize: bool,
+    pub(crate) can_memoize: bool,
 
-    pub name: &'static str,
-
-    // a pointer into the bump arena (given by the 'src lifetime)
+    // Raw pointer into the bump arena for the props of the component
     pub(crate) raw_props: *const (),
 
-    // a pointer to the raw fn typ
+    // Function pointer to the FC that was used to generate this component
     pub(crate) user_fc: *const (),
 }
 
 pub struct VSuspended<'a> {
-    pub dom_id: Cell<Option<ElementId>>,
     pub task_id: u64,
-    pub callback: RefCell<Option<&'a dyn FnOnce(SuspendedContext<'a>) -> DomTree<'a>>>,
+    pub dom_id: Cell<Option<ElementId>>,
+    pub(crate) callback: RefCell<Option<&'a dyn FnOnce(SuspendedContext<'a>) -> DomTree<'a>>>,
 }
 
 /// This struct provides an ergonomic API to quickly build VNodes.
@@ -350,10 +344,8 @@ impl<'a> NodeFactory<'a> {
     {
         let bump = self.bump();
 
-        let name = crate::util::type_name_of(component);
-
         // We don't want the fat part of the fat pointer
-        // This function does static dispatch so we don't need any VTable stuff
+        // THe "Fat" part is provided on next-render
         let children: &'a V = bump.alloc(children);
         let children = children.as_ref();
 
@@ -415,9 +407,8 @@ impl<'a> NodeFactory<'a> {
             is_static,
             drop_props: RefCell::new(Some(drop_props)),
             can_memoize: P::IS_STATIC,
-            ass_scope: Cell::new(None),
+            associated_scope: Cell::new(None),
             key,
-            name,
         }))
     }
 
@@ -663,7 +654,7 @@ impl Debug for VNode<'_> {
             VNode::Component(comp) => write!(
                 s,
                 "VComponent {{ fc: {:?}, children: {:?} }}",
-                comp.name, comp.children
+                comp.user_fc, comp.children
             ),
         }
     }

+ 30 - 30
packages/core/src/scope.rs

@@ -115,12 +115,12 @@ impl Scope {
 
     /// Returns true if the scope completed successfully
     ///
-    pub(crate) fn run_scope<'sel>(&'sel mut self) -> bool {
+    pub(crate) fn run_scope<'sel>(&'sel mut self, pool: &ResourcePool) -> bool {
         // Cycle to the next frame and then reset it
         // This breaks any latent references, invalidating every pointer referencing into it.
         // Remove all the outdated listeners
 
-        self.ensure_drop_safety();
+        self.ensure_drop_safety(pool);
 
         // Safety:
         // - We dropped the listeners, so no more &mut T can be used while these are held
@@ -154,7 +154,7 @@ impl Scope {
     ///
     /// Refrences to hook data can only be stored in listeners and component props. During diffing, we make sure to log
     /// all listeners and borrowed props so we can clear them here.
-    fn ensure_drop_safety(&mut self) {
+    fn ensure_drop_safety(&mut self, pool: &ResourcePool) {
         // make sure all garabge is collected before trying to proceed with anything else
         debug_assert!(
             self.pending_garbage.borrow().is_empty(),
@@ -163,33 +163,33 @@ impl Scope {
 
         // todo!("arch changes");
 
-        // // make sure we drop all borrowed props manually to guarantee that their drop implementation is called before we
-        // // run the hooks (which hold an &mut Referrence)
-        // // right now, we don't drop
-        // // let vdom = &self.vdom;
-        // self.borrowed_props
-        //     .get_mut()
-        //     .drain(..)
-        //     .map(|li| unsafe { &*li })
-        //     .for_each(|comp| {
-        //         // First drop the component's undropped references
-        //         let scope_id = comp.ass_scope.get().unwrap();
-        //         let scope = unsafe { vdom.get_scope_mut(scope_id) }.unwrap();
-        //         scope.ensure_drop_safety();
-
-        //         // Now, drop our own reference
-        //         let mut dropper = comp.drop_props.borrow_mut().take().unwrap();
-        //         dropper();
-        //     });
-
-        // // Now that all the references are gone, we can safely drop our own references in our listeners.
-        // self.listeners
-        //     .get_mut()
-        //     .drain(..)
-        //     .map(|li| unsafe { &*li })
-        //     .for_each(|listener| {
-        //         listener.callback.borrow_mut().take();
-        //     });
+        // make sure we drop all borrowed props manually to guarantee that their drop implementation is called before we
+        // run the hooks (which hold an &mut Referrence)
+        // right now, we don't drop
+        // let vdom = &self.vdom;
+        self.borrowed_props
+            .get_mut()
+            .drain(..)
+            .map(|li| unsafe { &*li })
+            .for_each(|comp| {
+                // First drop the component's undropped references
+                let scope_id = comp.associated_scope.get().unwrap();
+                let scope = pool.get_scope_mut(scope_id).unwrap();
+                scope.ensure_drop_safety(pool);
+
+                // Now, drop our own reference
+                let mut dropper = comp.drop_props.borrow_mut().take().unwrap();
+                dropper();
+            });
+
+        // Now that all the references are gone, we can safely drop our own references in our listeners.
+        self.listeners
+            .get_mut()
+            .drain(..)
+            .map(|li| unsafe { &*li })
+            .for_each(|listener| {
+                listener.callback.borrow_mut().take();
+            });
     }
 
     // A safe wrapper around calling listeners

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

@@ -168,7 +168,7 @@ impl VirtualDom {
             .expect("The base scope should never be moved");
 
         // // We run the component. If it succeeds, then we can diff it and add the changes to the dom.
-        if cur_component.run_scope() {
+        if cur_component.run_scope(&self.scheduler.pool) {
             diff_machine
                 .stack
                 .create_node(cur_component.frames.fin_head(), MountType::Append);
@@ -204,7 +204,7 @@ impl VirtualDom {
             .get_scope_mut(self.base_scope)
             .expect("The base scope should never be moved");
 
-        if cur_component.run_scope() {
+        if cur_component.run_scope(&self.scheduler.pool) {
             diff_machine.diff_scope(self.base_scope).await;
         }
 

+ 1 - 1
packages/ssr/src/lib.rs

@@ -169,7 +169,7 @@ impl<'a> TextRenderer<'a> {
                 }
             }
             VNode::Component(vcomp) => {
-                let idx = vcomp.ass_scope.get().unwrap();
+                let idx = vcomp.associated_scope.get().unwrap();
                 match (self.vdom, self.cfg.skip_components) {
                     (Some(vdom), false) => {
                         let new_node = vdom.get_scope(idx).unwrap().root();