From 0900104891382b49a69e1a19f53edadff6bf682e Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Sun, 10 Dec 2023 13:50:10 -0800 Subject: [PATCH] More mutation work --- src/apply_mutations.rs | 55 ++++++++++++++++++++++++++++++------------ src/lib.rs | 2 ++ src/tick.rs | 5 +++- 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/src/apply_mutations.rs b/src/apply_mutations.rs index 7baefdc..3b8c4a5 100644 --- a/src/apply_mutations.rs +++ b/src/apply_mutations.rs @@ -10,6 +10,7 @@ use dioxus::core::{ElementId, Mutation, Mutations, Template, TemplateNode}; pub fn apply_mutations( mutations: Mutations, + hierarchy: &mut HashMap<(Entity, u8), Entity>, element_id_to_bevy_ui_entity: &mut HashMap, templates: &mut HashMap, root_entity: Entity, @@ -30,21 +31,37 @@ pub fn apply_mutations( match edit { Mutation::AppendChildren { id, m } => { let mut parent = commands.entity(map[&id]); - for _ in 0..m { - parent.add_child(stack.pop().unwrap()); + let parent_existing_children_count = + hierarchy.keys().filter(|(p, _)| *p == parent.id()).count(); + for i in 1..=m { + let child = stack.pop().unwrap(); + parent.add_child(child); + hierarchy.insert( + (parent.id(), (parent_existing_children_count + i) as u8), + child, + ); } } Mutation::AssignId { path, id } => todo!(), Mutation::CreatePlaceholder { id } => todo!(), Mutation::CreateTextNode { value, id } => { let entity = BevyTemplateNode::from_dioxus(&TemplateNode::Text { text: value }) - .spawn(commands); + .spawn(commands, hierarchy); map.insert(id, entity); stack.push(entity); } - Mutation::HydrateText { path, value, id } => todo!(), + Mutation::HydrateText { path, value, id } => { + let mut entity = *stack.last().unwrap(); + for index in path { + entity = hierarchy[&(entity, *index)]; + } + commands + .entity(entity) + .insert(Text::from_section(value, TextStyle::default())); + map.insert(id, entity); + } Mutation::LoadTemplate { name, index, id } => { - let entity = templates[name].roots[index].spawn(commands); + let entity = templates[name].roots[index].spawn(commands, hierarchy); map.insert(id, entity); stack.push(entity); } @@ -106,31 +123,39 @@ impl BevyTemplateNode { children: children.iter().map(Self::from_dioxus).collect(), } } - TemplateNode::Text { text } => { Self::TextNode(Text::from_section(*text, TextStyle::default())) } - - TemplateNode::Dynamic { id } => todo!(), - - TemplateNode::DynamicText { id } => todo!(), + TemplateNode::Dynamic { id: _ } => Self::Node { + children: Box::new([]), + }, + TemplateNode::DynamicText { id: _ } => { + Self::TextNode(Text::from_section("", TextStyle::default())) + } } } - fn spawn(&self, commands: &mut Commands) -> Entity { + fn spawn( + &self, + commands: &mut Commands, + hierarchy: &mut HashMap<(Entity, u8), Entity>, + ) -> Entity { match self { BevyTemplateNode::Node { children } => { // TODO: Can probably use with_children() instead let children = children .iter() - .map(|child| child.spawn(commands)) + .map(|child| child.spawn(commands, hierarchy)) .collect::>(); - commands + let parent = commands .spawn(NodeBundle::default()) .push_children(&children) - .id() + .id(); + for (i, child) in children.iter().enumerate() { + hierarchy.insert((parent, i as u8), *child); + } + parent } - Self::TextNode(text) => commands .spawn(TextBundle { text: text.clone(), diff --git a/src/lib.rs b/src/lib.rs index febb5a7..ff2f1e3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -40,6 +40,7 @@ pub struct DioxusUiBundle { #[derive(Component)] pub struct DioxusUiRoot { virtual_dom: VirtualDomUnsafe, + hierarchy: HashMap<(Entity, u8), Entity>, element_id_to_bevy_ui_entity: HashMap, templates: HashMap, needs_rebuild: bool, @@ -49,6 +50,7 @@ impl DioxusUiRoot { pub fn new(root_component: fn(Scope) -> Element) -> Self { Self { virtual_dom: VirtualDomUnsafe::new(root_component), + hierarchy: HashMap::new(), element_id_to_bevy_ui_entity: HashMap::new(), templates: HashMap::new(), needs_rebuild: true, diff --git a/src/tick.rs b/src/tick.rs index a099193..2dc1fa4 100644 --- a/src/tick.rs +++ b/src/tick.rs @@ -27,9 +27,10 @@ pub fn tick_dioxus_ui(world: &mut World) { } { let DioxusUiRoot { virtual_dom, - needs_rebuild, + hierarchy, element_id_to_bevy_ui_entity, templates, + needs_rebuild, } = &mut *dioxus_ui_root; let virtual_dom = virtual_dom.get(); @@ -43,6 +44,7 @@ pub fn tick_dioxus_ui(world: &mut World) { if *needs_rebuild { apply_mutations( virtual_dom.rebuild(), + hierarchy, element_id_to_bevy_ui_entity, templates, root_entity, @@ -53,6 +55,7 @@ pub fn tick_dioxus_ui(world: &mut World) { apply_mutations( virtual_dom.render_immediate(), + hierarchy, element_id_to_bevy_ui_entity, templates, root_entity,