Browse Source

wip: a few things left, slme cleanup

Jonathan Kelley 3 years ago
parent
commit
289d2f2518

+ 10 - 23
packages/core/src/diff.rs

@@ -124,7 +124,7 @@ impl<'bump> DiffState<'bump> {
 
 impl<'bump> ScopeArena {
     pub fn diff_scope(&'bump self, state: &mut DiffState<'bump>, id: &ScopeId) {
-        if let Some(component) = self.get_scope(&id) {
+        if let Some(component) = self.get_scope(id) {
             let (old, new) = (component.wip_head(), component.fin_head());
             state.stack.push(DiffInstruction::Diff { new, old });
             self.work(state, || false);
@@ -221,7 +221,7 @@ impl<'bump> ScopeArena {
                     state.mutations.replace_with(old_id, nodes_created as u32);
                     self.remove_nodes(state, Some(old), true);
                 } else {
-                    if let Some(id) = self.find_first_element_id(state, old) {
+                    if let Some(id) = self.find_first_element_id(old) {
                         state.mutations.replace_with(id, nodes_created as u32);
                     }
                     self.remove_nodes(state, Some(old), true);
@@ -235,12 +235,12 @@ impl<'bump> ScopeArena {
             }
 
             MountType::InsertAfter { other_node } => {
-                let root = self.find_last_element(state, other_node).unwrap();
+                let root = self.find_last_element(other_node).unwrap();
                 state.mutations.insert_after(root, nodes_created as u32);
             }
 
             MountType::InsertBefore { other_node } => {
-                let root = self.find_first_element_id(state, other_node).unwrap();
+                let root = self.find_first_element_id(other_node).unwrap();
                 state.mutations.insert_before(root, nodes_created as u32);
             }
         }
@@ -331,7 +331,7 @@ impl<'bump> ScopeArena {
             let scope = self.get_scope(&cur_scope_id).unwrap();
 
             for listener in *listeners {
-                self.attach_listener_to_scope(state, listener, scope);
+                self.attach_listener_to_scope(listener, scope);
                 listener.mounted_node.set(Some(real_id));
                 state.mutations.new_event_listener(listener, cur_scope_id);
             }
@@ -561,7 +561,7 @@ impl<'bump> ScopeArena {
                         state.mutations.new_event_listener(new_l, cur_scope_id);
                     }
                     new_l.mounted_node.set(old_l.mounted_node.get());
-                    self.attach_listener_to_scope(state, new_l, scope);
+                    self.attach_listener_to_scope(new_l, scope);
                 }
             } else {
                 for listener in old.listeners {
@@ -572,7 +572,7 @@ impl<'bump> ScopeArena {
                 for listener in new.listeners {
                     listener.mounted_node.set(Some(root));
                     state.mutations.new_event_listener(listener, cur_scope_id);
-                    self.attach_listener_to_scope(state, listener, scope);
+                    self.attach_listener_to_scope(listener, scope);
                 }
             }
         }
@@ -1128,11 +1128,7 @@ impl<'bump> ScopeArena {
     //  Utilities
     // =====================
 
-    fn find_last_element(
-        &'bump self,
-        state: &mut DiffState<'bump>,
-        vnode: &'bump VNode<'bump>,
-    ) -> Option<ElementId> {
+    fn find_last_element(&'bump self, vnode: &'bump VNode<'bump>) -> Option<ElementId> {
         let mut search_node = Some(vnode);
 
         loop {
@@ -1156,11 +1152,7 @@ impl<'bump> ScopeArena {
         }
     }
 
-    fn find_first_element_id(
-        &'bump self,
-        state: &mut DiffState<'bump>,
-        vnode: &'bump VNode<'bump>,
-    ) -> Option<ElementId> {
+    fn find_first_element_id(&'bump self, vnode: &'bump VNode<'bump>) -> Option<ElementId> {
         let mut search_node = Some(vnode);
 
         loop {
@@ -1288,12 +1280,7 @@ impl<'bump> ScopeArena {
     }
 
     /// Adds a listener closure to a scope during diff.
-    fn attach_listener_to_scope(
-        &'bump self,
-        state: &mut DiffState<'bump>,
-        listener: &'bump Listener<'bump>,
-        scope: &ScopeState,
-    ) {
+    fn attach_listener_to_scope(&'bump self, listener: &'bump Listener<'bump>, scope: &ScopeState) {
         let long_listener = unsafe { std::mem::transmute(listener) };
         scope.items.borrow_mut().listeners.push(long_listener)
     }

+ 6 - 25
packages/core/src/lazynodes.rs

@@ -39,14 +39,12 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
     where
         F: FnOnce(NodeFactory<'a>) -> VNode<'a> + 'b,
     {
+        // there's no way to call FnOnce without a box, so we need to store it in a slot and use static dispatch
         let mut slot = Some(_val);
 
-        let val = move |f| {
-            let inn = slot.take().unwrap();
-            match f {
-                Some(f) => Some(inn(f)),
-                None => None,
-            }
+        let val = move |fac: Option<NodeFactory<'a>>| {
+            let inner = slot.take().unwrap();
+            fac.map(inner)
         };
 
         unsafe { LazyNodes::new_inner(val) }
@@ -125,7 +123,6 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
                 *dataptr.add(i) = *src_ptr.add(i);
             }
 
-            log::debug!("I am forgetting the contents of the stuff");
             std::mem::forget(val);
 
             Self {
@@ -143,7 +140,6 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
             StackNodeStorage::Heap(mut lazy) => lazy(Some(f)).unwrap(),
             StackNodeStorage::Stack(mut stack) => stack.call(f),
         }
-        // todo drop?
     }
 }
 
@@ -154,25 +150,12 @@ struct LazyStack {
 }
 
 impl LazyStack {
-    unsafe fn as_raw<'a>(&mut self) -> *mut dyn FnOnce(NodeFactory<'a>) -> VNode<'a> {
-        let LazyStack { buf, .. } = self;
-        let data = buf.as_ref();
-
-        let info_size = mem::size_of::<*mut dyn FnOnce(NodeFactory<'a>) -> VNode<'a>>()
-            / mem::size_of::<usize>()
-            - 1;
-
-        let info_ofs = data.len() - info_size;
-
-        make_fat_ptr(data[..].as_ptr() as usize, &data[info_ofs..])
-    }
-
     fn call<'a>(&mut self, f: NodeFactory<'a>) -> VNode<'a> {
         let LazyStack { buf, .. } = self;
         let data = buf.as_ref();
 
         let info_size =
-            mem::size_of::<*mut dyn FnOnce(Option<NodeFactory<'a>>) -> Option<VNode<'a>>>()
+            mem::size_of::<*mut dyn FnMut(Option<NodeFactory<'a>>) -> Option<VNode<'a>>>()
                 / mem::size_of::<usize>()
                 - 1;
 
@@ -190,13 +173,11 @@ impl LazyStack {
 impl Drop for LazyStack {
     fn drop(&mut self) {
         if !self.dropped {
-            log::debug!("manually dropping lazy nodes");
-
             let LazyStack { buf, .. } = self;
             let data = buf.as_ref();
 
             let info_size = mem::size_of::<
-                *mut dyn FnOnce(Option<NodeFactory<'_>>) -> Option<VNode<'_>>,
+                *mut dyn FnMut(Option<NodeFactory<'_>>) -> Option<VNode<'_>>,
             >() / mem::size_of::<usize>()
                 - 1;
 

+ 1 - 1
packages/core/src/nodes.rs

@@ -177,7 +177,7 @@ impl<'src> VNode<'src> {
 
     pub fn children(&self) -> &[VNode<'src>] {
         match &self {
-            VNode::Fragment(f) => &f.children,
+            VNode::Fragment(f) => f.children,
             VNode::Component(c) => todo!("children are not accessible through this"),
             _ => &[],
         }

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

@@ -45,7 +45,6 @@ impl ScopeArena {
         parent_scope: Option<*mut ScopeState>,
         height: u32,
         subtree: u32,
-        sender: UnboundedSender<SchedulerMsg>,
     ) -> ScopeId {
         if let Some(id) = self.free_scopes.pop() {
             // have already called drop on it - the slot is still chillin tho
@@ -59,7 +58,7 @@ impl ScopeArena {
             let vcomp = unsafe { std::mem::transmute(vcomp as *const VComponent) };
 
             let new_scope = ScopeState {
-                sender,
+                sender: self.sender.clone(),
                 parent_scope,
                 our_arena_idx: id,
                 height,

+ 12 - 15
packages/core/src/virtual_dom.rs

@@ -69,7 +69,7 @@ use std::{
 pub struct VirtualDom {
     base_scope: ScopeId,
 
-    root_props: Rc<dyn Any>,
+    _root_props: Rc<dyn Any>,
 
     // we need to keep the allocation around, but we don't necessarily use it
     _root_caller: Box<dyn Any>,
@@ -156,7 +156,7 @@ impl VirtualDom {
         sender: UnboundedSender<SchedulerMsg>,
         receiver: UnboundedReceiver<SchedulerMsg>,
     ) -> Self {
-        let mut scopes = ScopeArena::new(sender.clone());
+        let mut scopes = ScopeArena::new(sender);
 
         let base_scope = scopes.new_with_key(
             //
@@ -166,7 +166,6 @@ impl VirtualDom {
             None,
             0,
             0,
-            sender.clone(),
         );
 
         Self {
@@ -175,7 +174,7 @@ impl VirtualDom {
             receiver,
             sender,
 
-            root_props: todo!(),
+            _root_props: todo!(),
             _root_caller: todo!(),
 
             pending_messages: VecDeque::new(),
@@ -201,7 +200,7 @@ impl VirtualDom {
     ///
     ///
     pub fn get_scope<'a>(&'a self, id: &ScopeId) -> Option<&'a ScopeState> {
-        self.scopes.get_scope(&id)
+        self.scopes.get_scope(id)
     }
 
     /// Get an [`UnboundedSender`] handle to the channel used by the scheduler.
@@ -265,7 +264,7 @@ impl VirtualDom {
                             // right now, they're bump allocated so this shouldn't matter anyway - they're not going to move
                             let unpinned = unsafe { Pin::new_unchecked(task) };
 
-                            if let Poll::Ready(_) = unpinned.poll(cx) {
+                            if unpinned.poll(cx).is_ready() {
                                 all_pending = false
                             }
                         }
@@ -331,7 +330,7 @@ impl VirtualDom {
     ///
     /// loop {
     ///     let mut timeout = TimeoutFuture::from_ms(16);
-    ///     let deadline = move || timeout.now_or_never();
+    ///     let deadline = move || (&mut timeout).now_or_never();
     ///
     ///     let mutations = dom.run_with_deadline(deadline).await;
     ///
@@ -346,11 +345,8 @@ impl VirtualDom {
     /// applied the edits.
     ///
     /// Mutations are the only link between the RealDOM and the VirtualDOM.
-    pub fn work_with_deadline<'a>(
-        &'a mut self,
-        mut deadline: impl FnMut() -> bool,
-    ) -> Vec<Mutations<'a>> {
-        let mut committed_mutations = Vec::<Mutations>::new();
+    pub fn work_with_deadline(&mut self, mut deadline: impl FnMut() -> bool) -> Vec<Mutations> {
+        let mut committed_mutations = vec![];
 
         while self.has_any_work() {
             while let Ok(Some(msg)) = self.receiver.try_next() {
@@ -375,7 +371,7 @@ impl VirtualDom {
                                 self.pending_messages.push_front(dirty_scope);
                             }
                         } else {
-                            log::debug!("User event without a targetted ElementId. Unsure how to proceed. {:?}", event);
+                            log::debug!("User event without a targetted ElementId. Not currently supported.\nUnsure how to proceed. {:?}", event);
                         }
                     }
                 }
@@ -434,7 +430,8 @@ impl VirtualDom {
 
                 committed_mutations.push(mutations);
             } else {
-                todo!("don't have a mechanism to pause work (yet)");
+                // leave the work in an incomplete state
+                log::debug!("don't have a mechanism to pause work (yet)");
                 return committed_mutations;
             }
         }
@@ -506,7 +503,7 @@ impl VirtualDom {
     pub fn hard_diff<'a>(&'a mut self, scope_id: &ScopeId) -> Option<Mutations<'a>> {
         log::debug!("hard diff {:?}", scope_id);
 
-        if self.run_scope(&scope_id) {
+        if self.run_scope(scope_id) {
             let mut diff_machine = DiffState::new(Mutations::new());
 
             diff_machine.force_diff = true;