diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs index 9699fe837..c22d32eff 100644 --- a/packages/core/src/diff.rs +++ b/packages/core/src/diff.rs @@ -149,10 +149,14 @@ impl<'a> DiffMachine<'a> { (VNode::Component(cold), VNode::Component(cnew)) => { // todo!("should not happen") + // self.change_list.commit_traversal(); if cold.user_fc == cnew.user_fc { // todo: create a stable addr let caller = Rc::downgrade(&cnew.caller); let id = cold.stable_addr.borrow().unwrap(); + *cnew.stable_addr.borrow_mut() = Some(id); + *cnew.ass_scope.borrow_mut() = *cold.ass_scope.borrow(); + let scope = Rc::downgrade(&cold.ass_scope); self.lifecycle_events .push_back(LifeCycleEvent::PropsChanged { caller, id, scope }); @@ -169,19 +173,6 @@ impl<'a> DiffMachine<'a> { new_scope, }); } - - // let comparator = &cnew.comparator.0; - // let old_props = cold.raw_props.as_ref(); - // let has_changed = comparator(old_props); - - // if has_changed { - // self.lifecycle_events - // .push_back(LifeCycleEvent::PropsChanged); - // return; - // } - - // the component is the same and hasn't changed - // migrate props over (so the addr remains stable) but don't rerun the component } // todo: knock out any listeners @@ -448,13 +439,9 @@ impl<'a> DiffMachine<'a> { if new_is_keyed && old_is_keyed { let t = self.change_list.next_temporary(); - // diff_keyed_children(self.change_list, old, new); - // diff_keyed_children(self.change_list, old, new, cached_roots); - // diff_keyed_children(cached_set, self.change_list, registry, old, new, cached_roots); self.change_list.set_next_temporary(t); } else { self.diff_non_keyed_children(old, new); - // diff_non_keyed_children(cached_set, change_list, registry, old, new, cached_roots); } } @@ -480,8 +467,6 @@ impl<'a> DiffMachine<'a> { // // Upon exiting, the change list stack is in the same state. fn diff_keyed_children(&mut self, old: &[VNode<'a>], new: &[VNode<'a>]) { - // let DiffState { change_list, queue } = &*state; - if cfg!(debug_assertions) { let mut keys = fxhash::FxHashSet::default(); let mut assert_unique_keys = |children: &[VNode]| { diff --git a/packages/core/src/patch.rs b/packages/core/src/patch.rs index caeb9ea9f..cc89efec2 100644 --- a/packages/core/src/patch.rs +++ b/packages/core/src/patch.rs @@ -325,29 +325,17 @@ impl<'a> EditMachine<'a> { pub fn create_text_node(&mut self, text: &'a str) { debug_assert!(self.traversal_is_committed()); - // debug!("emit: create_text_node({:?})", text); - // self.emitter.create_text_node(text); self.emitter.push(Edit::CreateTextNode { text }); } pub fn create_element(&mut self, tag_name: &'a str) { - // debug_assert!(self.traversal_is_committed()); - // debug!("emit: create_element({:?})", tag_name); - // let tag_name_id = self.ensure_string(tag_name); + debug_assert!(self.traversal_is_committed());; self.emitter.push(Edit::CreateElement { tag_name }); - // self.emitter.create_element(tag_name); - // self.emitter.create_element(tag_name_id.into()); } pub fn create_element_ns(&mut self, tag_name: &'a str, ns: &'a str) { debug_assert!(self.traversal_is_committed()); - // debug!("emit: create_element_ns({:?}, {:?})", tag_name, ns); - // let tag_name_id = self.ensure_string(tag_name); - // let ns_id = self.ensure_string(ns); - // self.emitter.create_element_ns(tag_name, ns); self.emitter.push(Edit::CreateElementNs { tag_name, ns }); - // self.emitter - // .create_element_ns(tag_name_id.into(), ns_id.into()); } pub fn push_force_new_listeners(&mut self) -> bool { @@ -364,7 +352,6 @@ impl<'a> EditMachine<'a> { pub fn new_event_listener(&mut self, event: &'a str, scope: ScopeIdx, id: usize) { debug_assert!(self.traversal_is_committed()); self.emitter.push(Edit::NewListener { event, scope, id }); - // log::debug!("emit: new_event_listener({:?})", listener); } pub fn update_event_listener(&mut self, event: &'a str, scope: ScopeIdx, id: usize) { diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index 927767695..7029b7bf8 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -117,8 +117,9 @@ impl VirtualDom { c.run_scope()?; diff_machine.change_list.load_known_root(id); - + diff_machine.diff_node(c.old_frame(), c.new_frame()); + diff_machine.change_list.save_known_root(id); } } LifeCycleEvent::PropsChanged { caller, id, scope } => { @@ -131,7 +132,7 @@ impl VirtualDom { let p = &mut *(very_unsafe_components); // todo, hook up the parent/child indexes properly // let idx = p.insert_with(|f| Scope::new(caller, f, None)); - let c = p.get_mut(idx).unwrap(); + let c = p.get_mut(idx).unwrap(); c.run_scope()?; diff_machine.change_list.load_known_root(id); @@ -193,7 +194,7 @@ impl VirtualDom { component.call_listener(event); component.run_scope()?; - let mut diff_machine = DiffMachine::new(); + // let mut diff_machine = DiffMachine::new(); // let mut diff_machine = DiffMachine::new(&self.diff_bump); // diff_machine.diff_node(component.old_frame(), component.new_frame()); diff --git a/packages/web/examples/rsxt.rs b/packages/web/examples/rsxt.rs index f4702e1b3..19e0827eb 100644 --- a/packages/web/examples/rsxt.rs +++ b/packages/web/examples/rsxt.rs @@ -63,10 +63,12 @@ impl PartialEq for ButtonProps<'_> { fn CustomButton<'a>(ctx: Context<'a>, props: &'a ButtonProps<'a>) -> DomTree { ctx.render(rsx!{ - button { - class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow" - onmouseover: move |_| (props.set_name)() - "{props.name}" + div { + button { + class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow" + onmouseover: move |_| (props.set_name)() + "{props.name}" + } } }) } diff --git a/packages/web/src/interpreter.rs b/packages/web/src/interpreter.rs index 6568a0f85..2147a0a69 100644 --- a/packages/web/src/interpreter.rs +++ b/packages/web/src/interpreter.rs @@ -434,6 +434,7 @@ impl PatchMachine { // 16 Edit::PushChild { n } => { let parent = self.stack.top(); + // log::debug!("PushChild {:#?}", parent); let child = parent.child_nodes().get(n).unwrap(); self.stack.push(child); } diff --git a/packages/web/src/lib.rs b/packages/web/src/lib.rs index d50f90172..50ba8af38 100644 --- a/packages/web/src/lib.rs +++ b/packages/web/src/lib.rs @@ -80,22 +80,31 @@ impl WebsysRenderer { log::debug!("patching with {:?}", edit); patch_machine.handle_edit(edit); }); + + + + patch_machine.reset(); + let root_node = body_element.first_child().unwrap(); + patch_machine.stack.push(root_node.clone()); + // log::debug!("patch stack size {:?}", patch_machine.stack); // Event loop waits for the receiver to finish up // TODO! Connect the sender to the virtual dom's suspense system // Suspense is basically an external event that can force renders to specific nodes while let Ok(event) = receiver.recv().await { + log::debug!("Stack before entrance {:#?}", patch_machine.stack.top()); // log::debug!("patch stack size before {:#?}", patch_machine.stack); // patch_machine.reset(); // patch_machine.stack.push(root_node.clone()); - self.internal_dom - .progress_with_event(event)? - .iter() - .for_each(|edit| { - log::debug!("edit stream {:?}", edit); - patch_machine.handle_edit(edit); - }); + let edits = self.internal_dom.progress_with_event(event)?; + log::debug!("Received edits: {:#?}", edits); + + for edit in &edits { + log::debug!("edit stream {:?}", edit); + log::debug!("Stream stack {:#?}", patch_machine.stack.top()); + patch_machine.handle_edit(edit); + } // log::debug!("patch stack size after {:#?}", patch_machine.stack); patch_machine.reset();