1
0
Jonathan Kelley 2 жил өмнө
parent
commit
03aea885cf

+ 6 - 2
packages/core/src/any_props.rs

@@ -8,7 +8,11 @@ use crate::{
 };
 
 /// A trait that essentially allows VComponentProps to be used generically
-pub unsafe trait AnyProps<'a> {
+///
+/// # Safety
+///
+/// This should not be implemented outside this module
+pub(crate) unsafe trait AnyProps<'a> {
     fn props_ptr(&self) -> *const ();
     fn render(&'a self, bump: &'a ScopeState) -> RenderReturn<'a>;
     unsafe fn memoize(&self, other: &dyn AnyProps) -> bool;
@@ -64,6 +68,6 @@ where
         });
 
         // Call the render function directly
-        (self.render_fn)(scope).as_return(cx)
+        (self.render_fn)(scope).into_return(cx)
     }
 }

+ 5 - 17
packages/core/src/arena.rs

@@ -31,7 +31,7 @@ impl ElementRef {
     }
 }
 
-impl<'b> VirtualDom {
+impl VirtualDom {
     pub(crate) fn next_element(&mut self, template: &VNode, path: &'static [u8]) -> ElementId {
         let entry = self.elements.vacant_entry();
         let id = entry.key();
@@ -68,9 +68,8 @@ impl<'b> VirtualDom {
 
         if let Some(root) = scope.as_ref().try_root_node() {
             let root = unsafe { root.extend_lifetime_ref() };
-            match root {
-                RenderReturn::Sync(Ok(node)) => self.drop_scope_inner(node),
-                _ => {}
+            if let RenderReturn::Sync(Ok(node)) = root {
+                self.drop_scope_inner(node)
             }
         }
 
@@ -78,9 +77,8 @@ impl<'b> VirtualDom {
 
         if let Some(root) = unsafe { scope.as_ref().previous_frame().try_load_node() } {
             let root = unsafe { root.extend_lifetime_ref() };
-            match root {
-                RenderReturn::Sync(Ok(node)) => self.drop_scope_inner(node),
-                _ => {}
+            if let RenderReturn::Sync(Ok(node)) = root {
+                self.drop_scope_inner(node)
             }
         }
 
@@ -123,16 +121,6 @@ impl ElementPath {
     }
 }
 
-#[test]
-fn path_ascendant() {
-    // assert!(&ElementPath::Deep(&[]).is_ascendant(&&[0_u8]));
-    // assert!(&ElementPath::Deep(&[1, 2]), &[1, 2, 3]);
-    // assert!(!is_path_ascendant(
-    //     &ElementPath::Deep(&[1, 2, 3, 4]),
-    //     &[1, 2, 3]
-    // ));
-}
-
 impl PartialEq<&[u8]> for ElementPath {
     fn eq(&self, other: &&[u8]) -> bool {
         match *self {

+ 5 - 9
packages/core/src/create.rs

@@ -224,7 +224,7 @@ impl<'b> VirtualDom {
         }
 
         for node in template.template.roots {
-            self.create_static_node(template, node);
+            self.create_static_node(node);
         }
 
         self.mutations.template_mutations.push(SaveTemplate {
@@ -233,11 +233,7 @@ impl<'b> VirtualDom {
         });
     }
 
-    pub(crate) fn create_static_node(
-        &mut self,
-        template: &'b VNode<'b>,
-        node: &'b TemplateNode<'static>,
-    ) {
+    pub(crate) fn create_static_node(&mut self, node: &'b TemplateNode<'static>) {
         match *node {
             // Todo: create the children's template
             TemplateNode::Dynamic(_) => self
@@ -275,7 +271,7 @@ impl<'b> VirtualDom {
 
                 self.mutations
                     .template_mutations
-                    .extend(attrs.into_iter().filter_map(|attr| match attr {
+                    .extend(attrs.iter().filter_map(|attr| match attr {
                         TemplateAttribute::Static {
                             name,
                             value,
@@ -294,8 +290,8 @@ impl<'b> VirtualDom {
                 }
 
                 children
-                    .into_iter()
-                    .for_each(|child| self.create_static_node(template, child));
+                    .iter()
+                    .for_each(|child| self.create_static_node(child));
 
                 self.mutations
                     .template_mutations

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

@@ -320,14 +320,14 @@ impl<'b> VirtualDom {
                 Text(t) => self.reclaim(t.id.get()),
                 Fragment(VFragment::Empty(t)) => self.reclaim(t.get()),
                 Fragment(VFragment::NonEmpty(nodes)) => {
-                    nodes.into_iter().for_each(|node| self.clean_up_node(node))
+                    nodes.iter().for_each(|node| self.clean_up_node(node))
                 }
             };
         }
 
         // we clean up nodes with dynamic attributes, provided the node is unique and not a root node
         let mut id = None;
-        for (idx, attr) in node.dynamic_attrs.into_iter().enumerate() {
+        for (idx, attr) in node.dynamic_attrs.iter().enumerate() {
             // We'll clean up the root nodes either way, so don't worry
             if node.template.attr_paths[idx].len() == 1 {
                 continue;
@@ -620,7 +620,7 @@ impl<'b> VirtualDom {
         // If none of the old keys are reused by the new children, then we remove all the remaining old children and
         // create the new children afresh.
         if shared_keys.is_empty() {
-            if let Some(_) = old.get(0) {
+            if old.get(0).is_some() {
                 self.remove_nodes(&old[1..]);
                 self.replace_many(&old[0], new);
             } else {
@@ -744,7 +744,7 @@ impl<'b> VirtualDom {
     /// Remove these nodes from the dom
     /// Wont generate mutations for the inner nodes
     fn remove_nodes(&mut self, nodes: &'b [VNode<'b>]) {
-        nodes.into_iter().for_each(|node| self.remove_node(node));
+        nodes.iter().for_each(|node| self.remove_node(node));
     }
 
     fn remove_node(&mut self, node: &'b VNode<'b>) {

+ 18 - 22
packages/core/src/factory.rs

@@ -106,10 +106,10 @@ impl ScopeState {
 }
 
 pub trait ComponentReturn<'a, A = ()> {
-    fn as_return(self, cx: &'a ScopeState) -> RenderReturn<'a>;
+    fn into_return(self, cx: &'a ScopeState) -> RenderReturn<'a>;
 }
 impl<'a> ComponentReturn<'a> for Element<'a> {
-    fn as_return(self, _cx: &ScopeState) -> RenderReturn<'a> {
+    fn into_return(self, _cx: &ScopeState) -> RenderReturn<'a> {
         RenderReturn::Sync(self)
     }
 }
@@ -119,11 +119,9 @@ impl<'a, F> ComponentReturn<'a, AsyncMarker> for F
 where
     F: Future<Output = Element<'a>> + 'a,
 {
-    fn as_return(self, cx: &'a ScopeState) -> RenderReturn<'a> {
+    fn into_return(self, cx: &'a ScopeState) -> RenderReturn<'a> {
         let f: &mut dyn Future<Output = Element<'a>> = cx.bump().alloc(self);
-        let boxed = unsafe { BumpBox::from_raw(f) };
-        let pined: BumpBox<_> = boxed.into();
-        RenderReturn::Async(pined)
+        RenderReturn::Async(unsafe { BumpBox::from_raw(f) })
     }
 }
 
@@ -148,18 +146,18 @@ pub trait IntoDynNode<'a, A = ()> {
     fn into_vnode(self, cx: &'a ScopeState) -> DynamicNode<'a>;
 }
 
-impl<'a, 'b> IntoDynNode<'a> for () {
+impl<'a> IntoDynNode<'a> for () {
     fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
         DynamicNode::Fragment(VFragment::Empty(Cell::new(ElementId(0))))
     }
 }
-impl<'a, 'b> IntoDynNode<'a> for VNode<'a> {
+impl<'a> IntoDynNode<'a> for VNode<'a> {
     fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
         DynamicNode::Fragment(VFragment::NonEmpty(_cx.bump().alloc([self])))
     }
 }
 
-impl<'a, 'b, T: IntoDynNode<'a>> IntoDynNode<'a> for Option<T> {
+impl<'a, T: IntoDynNode<'a>> IntoDynNode<'a> for Option<T> {
     fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
         match self {
             Some(val) => val.into_vnode(_cx),
@@ -183,7 +181,7 @@ impl<'a, 'b> IntoDynNode<'a> for LazyNodes<'a, 'b> {
     }
 }
 
-impl<'b> IntoDynNode<'_> for &'b str {
+impl<'a> IntoDynNode<'_> for &'a str {
     fn into_vnode(self, cx: &ScopeState) -> DynamicNode {
         cx.text(format_args!("{}", self))
     }
@@ -201,25 +199,23 @@ impl<'b> IntoDynNode<'b> for Arguments<'_> {
     }
 }
 
-impl<'a, 'b> IntoDynNode<'a> for &VNode<'a> {
+impl<'a> IntoDynNode<'a> for &'a VNode<'a> {
     fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
-        todo!()
-        // VNode {
-        //     node_id: self.node_id.clone(),
-        //     parent: self.parent,
-        //     template: self.template,
-        //     root_ids: self.root_ids,
-        //     key: self.key,
-        //     dynamic_nodes: self.dynamic_nodes,
-        //     dynamic_attrs: self.dynamic_attrs,
-        // }
+        DynamicNode::Fragment(VFragment::NonEmpty(_cx.bump().alloc([VNode {
+            parent: self.parent,
+            template: self.template,
+            root_ids: self.root_ids,
+            key: self.key,
+            dynamic_nodes: self.dynamic_nodes,
+            dynamic_attrs: self.dynamic_attrs,
+        }])))
     }
 }
 
 pub trait IntoTemplate<'a> {
     fn into_template(self, _cx: &'a ScopeState) -> VNode<'a>;
 }
-impl<'a, 'b> IntoTemplate<'a> for VNode<'a> {
+impl<'a> IntoTemplate<'a> for VNode<'a> {
     fn into_template(self, _cx: &'a ScopeState) -> VNode<'a> {
         self
     }

+ 1 - 9
packages/core/src/mutations.rs

@@ -1,6 +1,6 @@
 use crate::{arena::ElementId, ScopeId};
 
-#[derive(Debug)]
+#[derive(Debug, Default)]
 #[must_use = "not handling edits can lead to visual inconsistencies in UI"]
 pub struct Mutations<'a> {
     pub subtree: usize,
@@ -9,14 +9,6 @@ pub struct Mutations<'a> {
 }
 
 impl<'a> Mutations<'a> {
-    pub fn new() -> Self {
-        Self {
-            subtree: 0,
-            edits: Vec::new(),
-            template_mutations: Vec::new(),
-        }
-    }
-
     /// A useful tool for testing mutations
     ///
     /// Rewrites IDs to just be "template", so you can compare the mutations

+ 13 - 11
packages/core/src/nodes.rs

@@ -102,8 +102,8 @@ pub struct VComponent<'a> {
     pub name: &'static str,
     pub static_props: bool,
     pub scope: Cell<Option<ScopeId>>,
-    pub props: Cell<Option<Box<dyn AnyProps<'a> + 'a>>>,
     pub render_fn: *const (),
+    pub(crate) props: Cell<Option<Box<dyn AnyProps<'a> + 'a>>>,
 }
 
 impl<'a> std::fmt::Debug for VComponent<'a> {
@@ -153,11 +153,13 @@ pub enum AttributeValue<'a> {
     Float(f32),
     Int(i32),
     Bool(bool),
-    Listener(RefCell<Option<BumpBox<'a, dyn FnMut(UiEvent<dyn Any>) + 'a>>>),
+    Listener(RefCell<Option<ListenerCb<'a>>>),
     Any(BumpBox<'a, dyn AnyValue>),
     None,
 }
 
+type ListenerCb<'a> = BumpBox<'a, dyn FnMut(UiEvent<dyn Any>) + 'a>;
+
 impl<'a> AttributeValue<'a> {
     pub fn new_listener<T: 'static>(
         cx: &'a ScopeState,
@@ -208,15 +210,15 @@ impl<'a> PartialEq for AttributeValue<'a> {
 
 impl<'a> AttributeValue<'a> {
     pub fn matches_type(&self, other: &'a AttributeValue<'a>) -> bool {
-        match (self, other) {
-            (Self::Text(_), Self::Text(_)) => true,
-            (Self::Float(_), Self::Float(_)) => true,
-            (Self::Int(_), Self::Int(_)) => true,
-            (Self::Bool(_), Self::Bool(_)) => true,
-            (Self::Listener(_), Self::Listener(_)) => true,
-            (Self::Any(_), Self::Any(_)) => true,
-            _ => return false,
-        }
+        matches!(
+            (self, other),
+            (Self::Text(_), Self::Text(_))
+                | (Self::Float(_), Self::Float(_))
+                | (Self::Int(_), Self::Int(_))
+                | (Self::Bool(_), Self::Bool(_))
+                | (Self::Listener(_), Self::Listener(_))
+                | (Self::Any(_), Self::Any(_))
+        )
     }
 }
 

+ 1 - 1
packages/core/src/scheduler/suspense.rs

@@ -41,7 +41,7 @@ impl SuspenseBoundary {
         Self {
             id,
             waiting_on: Default::default(),
-            mutations: RefCell::new(Mutations::new()),
+            mutations: RefCell::new(Mutations::default()),
             placeholder: Cell::new(None),
             created_on_stack: Cell::new(0),
             onresolve: None,

+ 2 - 16
packages/core/src/scheduler/task.rs

@@ -2,8 +2,7 @@ use super::{waker::RcWake, Scheduler, SchedulerMsg};
 use crate::ScopeId;
 use std::cell::RefCell;
 use std::future::Future;
-use std::task::Context;
-use std::{pin::Pin, rc::Rc, task::Poll};
+use std::{pin::Pin, rc::Rc};
 
 #[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -12,22 +11,9 @@ pub struct TaskId(pub usize);
 /// the task itself is the waker
 pub(crate) struct LocalTask {
     pub scope: ScopeId,
+    pub(super) task: RefCell<Pin<Box<dyn Future<Output = ()> + 'static>>>,
     id: TaskId,
     tx: futures_channel::mpsc::UnboundedSender<SchedulerMsg>,
-    task: RefCell<Pin<Box<dyn Future<Output = ()> + 'static>>>,
-}
-
-impl LocalTask {
-    /// Poll this task and return whether or not it is complete
-    pub(super) fn progress(self: &Rc<Self>) -> bool {
-        let waker = self.waker();
-        let mut cx = Context::from_waker(&waker);
-
-        match self.task.borrow_mut().as_mut().poll(&mut cx) {
-            Poll::Ready(_) => true,
-            _ => false,
-        }
-    }
 }
 
 impl Scheduler {

+ 4 - 1
packages/core/src/scheduler/wait.rs

@@ -18,8 +18,11 @@ impl VirtualDom {
         let mut tasks = self.scheduler.tasks.borrow_mut();
         let task = &tasks[id.0];
 
+        let waker = task.waker();
+        let mut cx = Context::from_waker(&waker);
+
         // If the task completes...
-        if task.progress() {
+        if task.task.borrow_mut().as_mut().poll(&mut cx).is_ready() {
             // Remove it from the scope so we dont try to double drop it when the scope dropes
             self.scopes[task.scope.0].spawned_tasks.remove(&id);
 

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

@@ -134,7 +134,7 @@ impl ScopeState {
     /// This is useful for traversing the tree outside of the VirtualDom, such as in a custom renderer or in SSR.
     ///
     /// Panics if the tree has not been built yet.
-    pub fn root_node<'a>(&'a self) -> &'a RenderReturn<'a> {
+    pub fn root_node(&self) -> &RenderReturn {
         self.try_root_node()
             .expect("The tree has not been built yet. Make sure to call rebuild on the tree before accessing its nodes.")
     }
@@ -144,7 +144,7 @@ impl ScopeState {
     /// This is useful for traversing the tree outside of the VirtualDom, such as in a custom renderer or in SSR.
     ///
     /// Returns [`None`] if the tree has not been built yet.
-    pub fn try_root_node<'a>(&'a self) -> Option<&'a RenderReturn<'a>> {
+    pub fn try_root_node(&self) -> Option<&RenderReturn> {
         let ptr = self.current_frame().node.get();
 
         if ptr.is_null() {

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

@@ -6,7 +6,7 @@ use crate::{
     any_props::VProps,
     arena::{ElementId, ElementRef},
     factory::RenderReturn,
-    innerlude::{DirtyScope, Mutations, Scheduler, SchedulerMsg, ErrorBoundary},
+    innerlude::{DirtyScope, ErrorBoundary, Mutations, Scheduler, SchedulerMsg},
     mutations::Mutation,
     nodes::{Template, TemplateId},
     scheduler::{SuspenseBoundary, SuspenseId},
@@ -236,7 +236,7 @@ impl VirtualDom {
             dirty_scopes: BTreeSet::new(),
             collected_leaves: Vec::new(),
             finished_fibers: Vec::new(),
-            mutations: Mutations::new(),
+            mutations: Mutations::default(),
         };
 
         let root = dom.new_scope(Box::new(VProps::new(
@@ -454,9 +454,9 @@ impl VirtualDom {
     }
 
     /// Swap the current mutations with a new
-    fn finalize<'a>(&'a mut self) -> Mutations<'a> {
+    fn finalize(&mut self) -> Mutations {
         // todo: make this a routine
-        let mut out = Mutations::new();
+        let mut out = Mutations::default();
         std::mem::swap(&mut self.mutations, &mut out);
         out
     }
@@ -481,7 +481,7 @@ impl VirtualDom {
     ///
     /// apply_edits(edits);
     /// ```
-    pub fn rebuild<'a>(&'a mut self) -> Mutations<'a> {
+    pub fn rebuild(&mut self) -> Mutations {
         match unsafe { self.run_scope(ScopeId(0)).extend_lifetime_ref() } {
             // Rebuilding implies we append the created elements to the root
             RenderReturn::Sync(Ok(node)) => {
@@ -519,10 +519,7 @@ impl VirtualDom {
     /// It's generally a good idea to put some sort of limit on the suspense process in case a future is having issues.
     ///
     /// If no suspense trees are present
-    pub async fn render_with_deadline<'a>(
-        &'a mut self,
-        deadline: impl Future<Output = ()>,
-    ) -> Mutations<'a> {
+    pub async fn render_with_deadline(&mut self, deadline: impl Future<Output = ()>) -> Mutations {
         pin_mut!(deadline);
 
         loop {