From 3c0057d9612dc26557f165815a9f6c96f8054722 Mon Sep 17 00:00:00 2001 From: JMS55 <47158642+JMS55@users.noreply.github.com> Date: Thu, 7 Dec 2023 20:27:42 -0800 Subject: [PATCH] WIP: Cursed reflected attributes --- src/apply_mutations.rs | 74 +++++++++++++++++++++++++++++++++++------- src/bsn.rs | 1 - src/lib.rs | 4 +-- 3 files changed, 64 insertions(+), 15 deletions(-) delete mode 100644 src/bsn.rs diff --git a/src/apply_mutations.rs b/src/apply_mutations.rs index f0a70fb..bf6d709 100644 --- a/src/apply_mutations.rs +++ b/src/apply_mutations.rs @@ -1,16 +1,22 @@ -use crate::bsn::Bsn; use bevy::{ - ecs::{entity::Entity, system::Commands}, + ecs::{ + entity::Entity, + reflect::{AppTypeRegistry, ReflectComponent}, + system::{Command, Commands}, + world::Mut, + }, hierarchy::{BuildChildren, DespawnRecursiveExt}, - ui::node_bundles::TextBundle, + prelude::World, + reflect::Reflect, utils::HashMap, }; -use dioxus_core::{ElementId, Mutation, Mutations}; +use dioxus_core::{BorrowedAttributeValue, ElementId, Mutation, Mutations}; +use std::sync::Arc; pub fn apply_mutations( mutations: Mutations, element_id_to_bevy_ui_entity: &mut HashMap, - templates: &mut HashMap, + templates: &mut HashMap, root_entity: Entity, commands: &mut Commands, ) { @@ -34,10 +40,12 @@ pub fn apply_mutations( Mutation::CreatePlaceholder { id } => { map.insert(id, commands.spawn(()).id()); } - Mutation::CreateTextNode { value, id } => { - map.insert(id, commands.spawn(TextBundle::from(value)).id()); + Mutation::CreateTextNode { .. } => { + unreachable!("Should not be used by bevy_dioxus elements"); + } + Mutation::HydrateText { .. } => { + unreachable!("Should not be used by bevy_dioxus elements"); } - Mutation::HydrateText { path, value, id } => todo!(), Mutation::LoadTemplate { name, index, id } => todo!(), Mutation::ReplaceWith { id, m } => todo!(), Mutation::ReplacePlaceholder { path, m } => todo!(), @@ -47,9 +55,22 @@ pub fn apply_mutations( name, value, id, - ns, - } => todo!(), - Mutation::SetText { value, id } => todo!(), + ns: _, + } => commands.add(SetReflectedComponent { + entity: map[&id], + component_type_path: name.to_owned(), + component_value: match value { + BorrowedAttributeValue::Any(value) => Some(Arc::clone( + value + .as_any() + .downcast_ref::>() + .expect("Attribute value does not impl Reflect"), + )), + BorrowedAttributeValue::None => None, + _ => unreachable!("Should not be used by bevy_dioxus elements"), + }, + }), + Mutation::SetText { .. } => unreachable!("Should not be used by bevy_dioxus elements"), Mutation::NewEventListener { name, id } => todo!(), Mutation::RemoveEventListener { name, id } => todo!(), Mutation::Remove { id } => { @@ -61,3 +82,34 @@ pub fn apply_mutations( } } } + +struct SetReflectedComponent { + entity: Entity, + component_type_path: String, + component_value: Option>, +} + +impl Command for SetReflectedComponent { + fn apply(self, world: &mut World) { + world.resource_scope(|world: &mut World, type_registry: Mut| { + let type_registry = type_registry.read(); + let reflected_component = type_registry + .get_with_type_path(&self.component_type_path) + .expect(&format!( + "Encountered an attribute with name {} that was not registered", + self.component_type_path + )) + .data::() + .expect(&format!( + "Encountered an attribute with name {} that did not reflect Component", + self.component_type_path + )); + + let entity_mut = &mut world.entity_mut(self.entity); + match self.component_value { + Some(value) => reflected_component.apply_or_insert(entity_mut, &*value), + None => reflected_component.remove(entity_mut), + } + }); + } +} diff --git a/src/bsn.rs b/src/bsn.rs deleted file mode 100644 index d1bd8ef..0000000 --- a/src/bsn.rs +++ /dev/null @@ -1 +0,0 @@ -pub struct Bsn {} diff --git a/src/lib.rs b/src/lib.rs index eecb9af..461f3d3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,11 +1,9 @@ mod apply_mutations; -mod bsn; mod deferred_system; mod hooks; mod tick; use self::{ - bsn::Bsn, deferred_system::DeferredSystemRegistry, tick::{tick_dioxus_ui, VirtualDomUnsafe}, }; @@ -35,7 +33,7 @@ impl Plugin for DioxusUiPlugin { pub struct DioxusUiRoot { virtual_dom: VirtualDomUnsafe, element_id_to_bevy_ui_entity: HashMap, - templates: HashMap, + templates: HashMap, needs_rebuild: bool, }