From 289d2f2518cef937a6fc823495a8bd32f287b84e Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Sun, 7 Nov 2021 09:58:19 -0500 Subject: [PATCH] wip: a few things left, slme cleanup --- packages/core/src/diff.rs | 33 ++++++++++---------------------- packages/core/src/lazynodes.rs | 31 ++++++------------------------ packages/core/src/nodes.rs | 2 +- packages/core/src/scopearena.rs | 3 +-- packages/core/src/virtual_dom.rs | 27 ++++++++++++-------------- 5 files changed, 30 insertions(+), 66 deletions(-) diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs index 7322cc96b..98ba2f3fd 100644 --- a/packages/core/src/diff.rs +++ b/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 { + fn find_last_element(&'bump self, vnode: &'bump VNode<'bump>) -> Option { 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 { + fn find_first_element_id(&'bump self, vnode: &'bump VNode<'bump>) -> Option { 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) } diff --git a/packages/core/src/lazynodes.rs b/packages/core/src/lazynodes.rs index e01eb78f0..72bb8dfb7 100644 --- a/packages/core/src/lazynodes.rs +++ b/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>| { + 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::() - - 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>) -> Option>>() + mem::size_of::<*mut dyn FnMut(Option>) -> Option>>() / mem::size_of::() - 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>) -> Option>, + *mut dyn FnMut(Option>) -> Option>, >() / mem::size_of::() - 1; diff --git a/packages/core/src/nodes.rs b/packages/core/src/nodes.rs index e4b4823e3..d6988c503 100644 --- a/packages/core/src/nodes.rs +++ b/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"), _ => &[], } diff --git a/packages/core/src/scopearena.rs b/packages/core/src/scopearena.rs index f419e410a..48732841c 100644 --- a/packages/core/src/scopearena.rs +++ b/packages/core/src/scopearena.rs @@ -45,7 +45,6 @@ impl ScopeArena { parent_scope: Option<*mut ScopeState>, height: u32, subtree: u32, - sender: UnboundedSender, ) -> 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, diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index 5531e4ff2..59eed261c 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -69,7 +69,7 @@ use std::{ pub struct VirtualDom { base_scope: ScopeId, - root_props: Rc, + _root_props: Rc, // we need to keep the allocation around, but we don't necessarily use it _root_caller: Box, @@ -156,7 +156,7 @@ impl VirtualDom { sender: UnboundedSender, receiver: UnboundedReceiver, ) -> 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> { - let mut committed_mutations = Vec::::new(); + pub fn work_with_deadline(&mut self, mut deadline: impl FnMut() -> bool) -> Vec { + 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> { 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;