More mutation work

This commit is contained in:
JMS55 2023-12-10 13:50:10 -08:00
parent f7896d5135
commit 0900104891
3 changed files with 46 additions and 16 deletions

View file

@ -10,6 +10,7 @@ use dioxus::core::{ElementId, Mutation, Mutations, Template, TemplateNode};
pub fn apply_mutations( pub fn apply_mutations(
mutations: Mutations, mutations: Mutations,
hierarchy: &mut HashMap<(Entity, u8), Entity>,
element_id_to_bevy_ui_entity: &mut HashMap<ElementId, Entity>, element_id_to_bevy_ui_entity: &mut HashMap<ElementId, Entity>,
templates: &mut HashMap<String, BevyTemplate>, templates: &mut HashMap<String, BevyTemplate>,
root_entity: Entity, root_entity: Entity,
@ -30,21 +31,37 @@ pub fn apply_mutations(
match edit { match edit {
Mutation::AppendChildren { id, m } => { Mutation::AppendChildren { id, m } => {
let mut parent = commands.entity(map[&id]); let mut parent = commands.entity(map[&id]);
for _ in 0..m { let parent_existing_children_count =
parent.add_child(stack.pop().unwrap()); 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::AssignId { path, id } => todo!(),
Mutation::CreatePlaceholder { id } => todo!(), Mutation::CreatePlaceholder { id } => todo!(),
Mutation::CreateTextNode { value, id } => { Mutation::CreateTextNode { value, id } => {
let entity = BevyTemplateNode::from_dioxus(&TemplateNode::Text { text: value }) let entity = BevyTemplateNode::from_dioxus(&TemplateNode::Text { text: value })
.spawn(commands); .spawn(commands, hierarchy);
map.insert(id, entity); map.insert(id, entity);
stack.push(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 } => { 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); map.insert(id, entity);
stack.push(entity); stack.push(entity);
} }
@ -106,31 +123,39 @@ impl BevyTemplateNode {
children: children.iter().map(Self::from_dioxus).collect(), children: children.iter().map(Self::from_dioxus).collect(),
} }
} }
TemplateNode::Text { text } => { TemplateNode::Text { text } => {
Self::TextNode(Text::from_section(*text, TextStyle::default())) Self::TextNode(Text::from_section(*text, TextStyle::default()))
} }
TemplateNode::Dynamic { id: _ } => Self::Node {
TemplateNode::Dynamic { id } => todo!(), children: Box::new([]),
},
TemplateNode::DynamicText { id } => todo!(), 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 { match self {
BevyTemplateNode::Node { children } => { BevyTemplateNode::Node { children } => {
// TODO: Can probably use with_children() instead // TODO: Can probably use with_children() instead
let children = children let children = children
.iter() .iter()
.map(|child| child.spawn(commands)) .map(|child| child.spawn(commands, hierarchy))
.collect::<Box<[_]>>(); .collect::<Box<[_]>>();
commands let parent = commands
.spawn(NodeBundle::default()) .spawn(NodeBundle::default())
.push_children(&children) .push_children(&children)
.id() .id();
for (i, child) in children.iter().enumerate() {
hierarchy.insert((parent, i as u8), *child);
}
parent
} }
Self::TextNode(text) => commands Self::TextNode(text) => commands
.spawn(TextBundle { .spawn(TextBundle {
text: text.clone(), text: text.clone(),

View file

@ -40,6 +40,7 @@ pub struct DioxusUiBundle {
#[derive(Component)] #[derive(Component)]
pub struct DioxusUiRoot { pub struct DioxusUiRoot {
virtual_dom: VirtualDomUnsafe, virtual_dom: VirtualDomUnsafe,
hierarchy: HashMap<(Entity, u8), Entity>,
element_id_to_bevy_ui_entity: HashMap<ElementId, Entity>, element_id_to_bevy_ui_entity: HashMap<ElementId, Entity>,
templates: HashMap<String, BevyTemplate>, templates: HashMap<String, BevyTemplate>,
needs_rebuild: bool, needs_rebuild: bool,
@ -49,6 +50,7 @@ impl DioxusUiRoot {
pub fn new(root_component: fn(Scope) -> Element) -> Self { pub fn new(root_component: fn(Scope) -> Element) -> Self {
Self { Self {
virtual_dom: VirtualDomUnsafe::new(root_component), virtual_dom: VirtualDomUnsafe::new(root_component),
hierarchy: HashMap::new(),
element_id_to_bevy_ui_entity: HashMap::new(), element_id_to_bevy_ui_entity: HashMap::new(),
templates: HashMap::new(), templates: HashMap::new(),
needs_rebuild: true, needs_rebuild: true,

View file

@ -27,9 +27,10 @@ pub fn tick_dioxus_ui(world: &mut World) {
} { } {
let DioxusUiRoot { let DioxusUiRoot {
virtual_dom, virtual_dom,
needs_rebuild, hierarchy,
element_id_to_bevy_ui_entity, element_id_to_bevy_ui_entity,
templates, templates,
needs_rebuild,
} = &mut *dioxus_ui_root; } = &mut *dioxus_ui_root;
let virtual_dom = virtual_dom.get(); let virtual_dom = virtual_dom.get();
@ -43,6 +44,7 @@ pub fn tick_dioxus_ui(world: &mut World) {
if *needs_rebuild { if *needs_rebuild {
apply_mutations( apply_mutations(
virtual_dom.rebuild(), virtual_dom.rebuild(),
hierarchy,
element_id_to_bevy_ui_entity, element_id_to_bevy_ui_entity,
templates, templates,
root_entity, root_entity,
@ -53,6 +55,7 @@ pub fn tick_dioxus_ui(world: &mut World) {
apply_mutations( apply_mutations(
virtual_dom.render_immediate(), virtual_dom.render_immediate(),
hierarchy,
element_id_to_bevy_ui_entity, element_id_to_bevy_ui_entity,
templates, templates,
root_entity, root_entity,