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(
mutations: Mutations,
hierarchy: &mut HashMap<(Entity, u8), Entity>,
element_id_to_bevy_ui_entity: &mut HashMap<ElementId, Entity>,
templates: &mut HashMap<String, BevyTemplate>,
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::<Box<[_]>>();
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(),

View file

@ -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<ElementId, Entity>,
templates: HashMap<String, BevyTemplate>,
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,

View file

@ -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,