This commit is contained in:
rewin
2024-02-19 20:39:03 +03:00
parent c104e01adc
commit a5ffacdf2c
4 changed files with 264 additions and 221 deletions
+2 -4
View File
@@ -6,13 +6,11 @@ use wasm_bindgen::prelude::*;
pub struct BlockingPlugin;
impl Plugin for BlockingPlugin {
fn build(&self, app: &mut App) {
}
fn build(&self, app: &mut App) {}
}
#[cfg_attr(feature = "wasm", wasm_bindgen(js_name = test_blocking))]
pub fn test_blocking() -> bool {
info!("test_blocking");
true
}
}
+1 -1
View File
@@ -8,6 +8,7 @@ use bevy_web_asset::WebAssetPlugin;
use wasm_bindgen::prelude::*;
mod anim;
pub mod blocking;
mod bvh;
mod camera_controller;
mod debug;
@@ -23,7 +24,6 @@ mod scene;
mod skybox;
mod ui;
pub mod viewport;
pub mod blocking;
mod world_grid;
+86 -50
View File
@@ -1,76 +1,106 @@
use std::{any::Any, sync::{Arc, Mutex, RwLock}, thread::yield_now};
use std::{
any::Any,
sync::{Arc, Mutex, RwLock},
thread::yield_now,
};
use bevy::{ecs::{component::ComponentId, world::unsafe_world_cell::{UnsafeEntityCell, UnsafeWorldCell}}, prelude::*, reflect::{ReflectFromPtr, TypeData}, utils::{hashbrown::HashMap, tracing::field}, window::PrimaryWindow};
use bevy::{
ecs::{
component::ComponentId,
world::unsafe_world_cell::{UnsafeEntityCell, UnsafeWorldCell},
},
prelude::*,
reflect::{ReflectFromPtr, TypeData},
utils::{hashbrown::HashMap, tracing::field},
window::PrimaryWindow,
};
use serde::{Deserialize, Serialize};
use space_editor::{prelude::Selected, space_editor_ui::inspector::inspect};
use wasm_bindgen::JsCast;
use web_sys::HtmlElement;
use crate::{ui::inspector::wasm::notify_dom_changed, wasm::{StaticBuffer, WasmMessageBuffer}};
use crate::{
ui::inspector::wasm::notify_dom_changed,
wasm::{StaticBuffer, WasmMessageBuffer},
};
use super::utils::{show_reflect, ComponentProp, Element, InspectedEntity, ReflectChange, VComponent, VNode, VirtualDom};
use super::utils::{
show_reflect, ComponentProp, Element, InspectedEntity, ReflectChange, VComponent, VNode,
VirtualDom,
};
pub struct InspectorPlugin;
impl Plugin for InspectorPlugin {
fn build(&self, app: &mut App) {
app.init_resource::<InspectorFunctions>();
app.add_systems(Update, show_selected);
app.world.resource_mut::<InspectorFunctions>().add_simple::<Name>();
app.world.resource_mut::<InspectorFunctions>().add_simple::<Transform>();
app.world
.resource_mut::<InspectorFunctions>()
.add_simple::<Name>();
app.world
.resource_mut::<InspectorFunctions>()
.add_simple::<Transform>();
}
}
#[derive(Resource, Default)]
struct InspectorFunctions {
get_reflects: Vec<Box<dyn FnMut(&UnsafeEntityCell<'_>) -> Option<Box<dyn Reflect>> + Send + Sync>>
get_reflects:
Vec<Box<dyn FnMut(&UnsafeEntityCell<'_>) -> Option<Box<dyn Reflect>> + Send + Sync>>,
}
impl InspectorFunctions {
fn add_getter<F: FnMut(&UnsafeEntityCell<'_>) -> Option<Box<dyn Reflect>> + Send + Sync + 'static>(&mut self, f: F) {
fn add_getter<
F: FnMut(&UnsafeEntityCell<'_>) -> Option<Box<dyn Reflect>> + Send + Sync + 'static,
>(
&mut self,
f: F,
) {
self.get_reflects.push(Box::new(f));
}
fn add_simple<T>(&mut self) where T: bevy::prelude::Component + Reflect + FromReflect + 'static {
fn add_simple<T>(&mut self)
where
T: bevy::prelude::Component + Reflect + FromReflect + 'static,
{
unsafe {
self.add_getter(
|cell| {
if let Some(val) = cell.get::<T>() {
Some(Box::new(<T as FromReflect>::from_reflect(val).unwrap()) as Box<dyn Reflect>)
} else {
None
}
self.add_getter(|cell| {
if let Some(val) = cell.get::<T>() {
Some(Box::new(<T as FromReflect>::from_reflect(val).unwrap())
as Box<dyn Reflect>)
} else {
None
}
)
})
}
}
fn get_reflect_copy(&mut self, cell: &UnsafeEntityCell<'_>) -> Vec<Box<dyn Reflect>> {
self.get_reflects.iter_mut().map(|f| (*f)(cell)).flatten().collect()
self.get_reflects
.iter_mut()
.map(|f| (*f)(cell))
.flatten()
.collect()
}
}
fn show_selected(
world: &mut World
) {
fn show_selected(world: &mut World) {
if !world.is_resource_added::<VirtualDom>() {
world.init_resource::<VirtualDom>();
}
unsafe {
let cell = world.as_unsafe_world_cell();
let mut virtial_dom = cell.get_resource_mut::<VirtualDom>().unwrap();
let Some(selection) = cell.get_resource::<crate::interaction::Selection>() else {
let muts = virtial_dom.render(None);
let q_window = cell.world_mut().query_filtered::<&Window, With<PrimaryWindow>>().single(cell.world());
let q_window = cell
.world_mut()
.query_filtered::<&Window, With<PrimaryWindow>>()
.single(cell.world());
let _ = notify_dom_changed(q_window, serde_json::to_string(&muts).unwrap());
return;
@@ -86,11 +116,12 @@ fn show_selected(
if let Some(changes) = super::utils::wasm::ONCHAGE_BUFFER.take_message() {
for (id, value) in changes {
info!("change: {} : {}", id, value);
virtial_dom.on_change_events.execute(cell.world_mut(), id, value);
virtial_dom
.on_change_events
.execute(cell.world_mut(), id, value);
}
}
let mut inspected = InspectedEntity::none();
inspected.id = Some(e.id());
inspected.components = functions.get_reflect_copy(&e);
@@ -101,17 +132,29 @@ fn show_selected(
let element = Element::Component(super::utils::Component {
tag: "div".to_string(),
attributes: vec![
("style".to_string(), "display: flex; flex-direction: column; height: 100%; overflow: auto;".to_string()),
("class".to_string(), "inspector".to_string())
(
"style".to_string(),
"display: flex; flex-direction: column; height: 100%; overflow: auto;"
.to_string(),
),
("class".to_string(), "inspector".to_string()),
],
children: inspected.components.into_iter().map(|c| {
children: inspected
.components
.into_iter()
.map(|c| {
show_reflect(
c.as_ref(),
c.as_ref(),
ReflectChange {
entity_id: id,
reflect_path: "".to_string(),
compoent_id: format!("{:?}", components.get_id(c.get_represented_type_info().unwrap().type_id()).unwrap()),
}
compoent_id: format!(
"{:?}",
components
.get_id(c.get_represented_type_info().unwrap().type_id())
.unwrap()
),
},
)
})
.filter_map(|v| v)
@@ -120,23 +163,22 @@ fn show_selected(
});
let muts = virtial_dom.render(Some(element));
let q_window = cell.world_mut().query_filtered::<&Window, With<PrimaryWindow>>().single(cell.world());
let q_window = cell
.world_mut()
.query_filtered::<&Window, With<PrimaryWindow>>()
.single(cell.world());
let _ = notify_dom_changed(q_window, serde_json::to_string(&muts).unwrap());
}
}
#[cfg(feature = "wasm")]
mod wasm {
use crate::wasm::*;
use bevy::{prelude::*, window::PrimaryWindow};
use serde_json::json;
use wasm_bindgen::prelude::*;
use crate::wasm::*;
use super::*;
@@ -158,13 +200,7 @@ declare global {
}
"#;
pub(super) fn notify_dom_changed(
q_window: &Window,
msg : String,
) -> Result<(), String> {
pub(super) fn notify_dom_changed(q_window: &Window, msg: String) -> Result<(), String> {
wasm::dispatch_to_js(q_window, "inspector-dom-changed", &msg)
}
}
+175 -166
View File
@@ -1,49 +1,50 @@
use std::any::Any;
use ::serde::{Deserialize, Serialize};
use bevy::{ecs::component::ComponentId, prelude::*, reflect::ReflectFromPtr, utils::HashMap};
use ::serde::{Serialize, Deserialize};
use uuid::*;
trait NodeProp : Clone + PartialEq {
}
trait NodeProp: Clone + PartialEq {}
#[derive(Serialize, Deserialize)]
pub enum Mutation {
SetAttibute{id : String, attribute : String, value : String},
SetAttibute {
id: String,
attribute: String,
value: String,
},
ReplaceAll(VNode),
RemoveAll
RemoveAll,
}
#[derive(Default)]
pub struct Component {
pub tag : String,
pub attributes : Vec<(String, String)>,
pub children : Vec<Element>,
pub onchange: Option<Box<dyn WebEventExecutor + Send + Sync>>
pub tag: String,
pub attributes: Vec<(String, String)>,
pub children: Vec<Element>,
pub onchange: Option<Box<dyn WebEventExecutor + Send + Sync>>,
}
pub enum Element {
Text(String),
Component(Component)
Component(Component),
}
pub trait WebEventExecutor {
fn execute(&mut self, world: &mut World, data: String);
fn execute(&mut self, world: &mut World, data: String);
}
#[derive(Default)]
pub struct WebEventStorage {
pub events : HashMap<String, Box<dyn WebEventExecutor + Send + Sync>>,
pub events: HashMap<String, Box<dyn WebEventExecutor + Send + Sync>>,
}
impl WebEventStorage {
pub fn add_event(&mut self, id : String, event : Box<dyn WebEventExecutor + Send + Sync>) {
pub fn add_event(&mut self, id: String, event: Box<dyn WebEventExecutor + Send + Sync>) {
self.events.insert(id, event);
}
pub fn execute(&mut self, world: &mut World, id : String, data : String) {
pub fn execute(&mut self, world: &mut World, id: String, data: String) {
if let Some(event) = self.events.get_mut(&id) {
event.execute(world, data);
} else {
@@ -54,12 +55,11 @@ impl WebEventStorage {
#[derive(Default, Resource)]
pub struct VirtualDom {
last_node : Option<VNode>,
last_node: Option<VNode>,
pub on_change_events: WebEventStorage,
}
impl VirtualDom {
pub fn render(&mut self, element: Option<Element>) -> Vec<Mutation> {
let mut id_counter = 0;
@@ -71,11 +71,10 @@ impl VirtualDom {
}
}
fn recursive_unpack_element(&mut self, counter : &mut usize, element : Element) -> VNode {
fn recursive_unpack_element(&mut self, counter: &mut usize, element: Element) -> VNode {
match element {
Element::Text(text) => VNode::Text(text),
Element::Component(component) => {
let id = format!("node_{}", *counter);
*counter += 1;
@@ -90,20 +89,22 @@ impl VirtualDom {
attributes: component.attributes.into_iter().collect(),
id: Some(id),
onchange: onchange_enabled,
children: component.children.into_iter().map(|e| self.recursive_unpack_element(counter, e)).collect()
children: component
.children
.into_iter()
.map(|e| self.recursive_unpack_element(counter, e))
.collect(),
})
},
}
}
}
}
pub fn create_mutations(&mut self, node : VNode) -> Vec<Mutation> {
pub fn create_mutations(&mut self, node: VNode) -> Vec<Mutation> {
if self.last_node == Some(node.clone()) {
return vec![]
return vec![];
} else {
if let Some(last_node) = &self.last_node {
if last_node.is_same_structure(&node) {
let muts = node.get_same_structure_muts(&last_node);
self.last_node = Some(node.clone());
return muts;
@@ -111,7 +112,7 @@ impl VirtualDom {
}
self.last_node = Some(node.clone());
return vec![Mutation::ReplaceAll(node)]
return vec![Mutation::ReplaceAll(node)];
}
}
}
@@ -125,7 +126,7 @@ pub mod wasm {
pub static ONCHAGE_BUFFER: WasmMessageBuffer<Vec<(String, String)>> = WasmMessageBuffer::new();
#[wasm_bindgen(js_name = register_new_change)]
pub fn register_new_change(id : String, value : String) {
pub fn register_new_change(id: String, value: String) {
let mut data = ONCHAGE_BUFFER.take_message().unwrap_or_default();
data.push((id, value));
ONCHAGE_BUFFER.write_message(data);
@@ -133,11 +134,11 @@ pub mod wasm {
}
struct ReflectValueExecutor {
change : ReflectChange
change: ReflectChange,
}
impl From<ReflectChange> for ReflectValueExecutor {
fn from(change : ReflectChange) -> Self {
fn from(change: ReflectChange) -> Self {
ReflectValueExecutor { change }
}
}
@@ -146,18 +147,33 @@ impl WebEventExecutor for ReflectValueExecutor {
fn execute(&mut self, world: &mut World, value: String) {
unsafe {
let world = world.as_unsafe_world_cell();
let app_type_registry: &AppTypeRegistry = world.get_resource::<AppTypeRegistry>().unwrap();
let app_type_registry: &AppTypeRegistry =
world.get_resource::<AppTypeRegistry>().unwrap();
let type_registry = app_type_registry.read();
let mut e = world.get_entity(self.change.entity_id).unwrap();
let c_id = ComponentId::new(
self.change.compoent_id.split('(').nth(1).unwrap().split(')').next().unwrap().parse().unwrap()
self.change
.compoent_id
.split('(')
.nth(1)
.unwrap()
.split(')')
.next()
.unwrap()
.parse()
.unwrap(),
);
if let Some(mut c) = e.get_mut_by_id(c_id) {
let mut refl = type_registry.get_type_data::<ReflectFromPtr>(world.components().get_info_unchecked(c_id).type_id().unwrap())
let mut refl = type_registry
.get_type_data::<ReflectFromPtr>(
world
.components()
.get_info_unchecked(c_id)
.type_id()
.unwrap(),
)
.unwrap()
.as_reflect_mut(c.as_mut());
@@ -200,8 +216,8 @@ impl WebEventExecutor for ReflectValueExecutor {
}
struct EntityChangeExecutor {
entity : Entity,
func : Box<dyn Fn(&mut World, Entity, String) + Send + Sync>,
entity: Entity,
func: Box<dyn Fn(&mut World, Entity, String) + Send + Sync>,
}
impl WebEventExecutor for EntityChangeExecutor {
@@ -211,50 +227,58 @@ impl WebEventExecutor for EntityChangeExecutor {
}
impl EntityChangeExecutor {
fn new(entity : Entity, func : impl Fn(&mut World, Entity, String) + Send + Sync + 'static) -> Self {
EntityChangeExecutor { entity, func : Box::new(func) }
fn new(
entity: Entity,
func: impl Fn(&mut World, Entity, String) + Send + Sync + 'static,
) -> Self {
EntityChangeExecutor {
entity,
func: Box::new(func),
}
}
fn new_boxed(entity : Entity, func : impl Fn(&mut World, Entity, String) + Send + Sync + 'static) -> Box<Self> {
fn new_boxed(
entity: Entity,
func: impl Fn(&mut World, Entity, String) + Send + Sync + 'static,
) -> Box<Self> {
Box::new(EntityChangeExecutor::new(entity, func))
}
}
fn euler_to_degrees(euler : (f32, f32, f32)) -> (f32, f32, f32) {
fn euler_to_degrees(euler: (f32, f32, f32)) -> (f32, f32, f32) {
(
euler.0.to_degrees(),
euler.1.to_degrees(),
euler.2.to_degrees()
euler.2.to_degrees(),
)
}
fn degrees_to_euler(degrees : (f32, f32, f32)) -> (f32, f32, f32) {
fn degrees_to_euler(degrees: (f32, f32, f32)) -> (f32, f32, f32) {
(
degrees.0.to_radians(),
degrees.1.to_radians(),
degrees.2.to_radians()
degrees.2.to_radians(),
)
}
fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Element> {
fn check_predefined(r: &dyn Reflect, onchange: ReflectChange) -> Option<Element> {
if let Some(name) = r.downcast_ref::<Name>() {
Some(Element::Component(Component {
tag: "div".to_string(),
attributes: vec![
("style".to_string(), "font-weight: bold; font-size: 24px".to_string()),
],
children: vec![
Element::Text(format!("{}", &name)),
],
onchange: None
attributes: vec![(
"style".to_string(),
"font-weight: bold; font-size: 24px".to_string(),
)],
children: vec![Element::Text(format!("{}", &name))],
onchange: None,
}))
} else if let Some(transform) = r.downcast_ref::<Transform>() {
Some(Element::Component(Component {
tag: "div".to_string(),
attributes: vec![
("style".to_string(), "display: flex; flex-direction: column".to_string()),
],
attributes: vec![(
"style".to_string(),
"display: flex; flex-direction: column".to_string(),
)],
children: vec![
Element::Text("Pos: ".to_string()),
show_reflect(&transform.translation, onchange.add_path("translation")).unwrap(),
@@ -263,57 +287,64 @@ fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Elemen
Element::Text("Scale: ".to_string()),
show_reflect(&transform.scale, onchange.add_path("scale")).unwrap(),
],
onchange: None
onchange: None,
}))
} else if let Some(quat) = r.downcast_ref::<Quat>() {
let euler = quat.to_euler(EulerRot::XYZ);
let degrees = euler_to_degrees(euler);
Some(Element::Component(Component {
tag: "div".to_string(),
attributes: vec![
("class".to_string(), "struct-grid".to_string()),
],
attributes: vec![("class".to_string(), "struct-grid".to_string())],
children: vec![
Element::Text("X: ".to_string()),
Element::Component(Component {
tag: "input".to_string(),
attributes: vec![
("type".to_string(), "number".to_string()),
("value".to_string(), format!("{:.2}",degrees.0)),
("value".to_string(), format!("{:.2}", degrees.0)),
("step".to_string(), "0.01".to_string()),
],
children: vec![],
onchange: Some(EntityChangeExecutor::new_boxed(
onchange.entity_id,
|world : &mut World, entity, value : String| {
let Some(mut value) = value.parse::<f32>().ok() else { return; };
if value == -180.0 { value = 180.0; }
|world: &mut World, entity, value: String| {
let Some(mut value) = value.parse::<f32>().ok() else {
return;
};
if value == -180.0 {
value = 180.0;
}
let value = value.to_radians();
let mut e = world.get_entity_mut(entity).unwrap();
let mut transform = e.get_mut::<Transform>().unwrap();
if transform.is_changed() {
return;
}
let euler = transform.rotation.to_euler(EulerRot::XYZ);
transform.rotation = Quat::from_euler(EulerRot::XYZ, value, euler.1, euler.2);
}
))
transform.rotation =
Quat::from_euler(EulerRot::XYZ, value, euler.1, euler.2);
},
)),
}),
Element::Text("Y: ".to_string()),
Element::Component(Component {
tag: "input".to_string(),
attributes: vec![
("type".to_string(), "number".to_string()),
("value".to_string(), format!("{:.2}",degrees.1)),
("value".to_string(), format!("{:.2}", degrees.1)),
("step".to_string(), "0.01".to_string()),
],
children: vec![],
onchange: Some(EntityChangeExecutor::new_boxed(
onchange.entity_id,
|world : &mut World, entity, value : String| {
let Some(mut value) = value.parse::<f32>().ok() else { return; };
if value == -180.0 { value = 180.0; }
|world: &mut World, entity, value: String| {
let Some(mut value) = value.parse::<f32>().ok() else {
return;
};
if value == -180.0 {
value = 180.0;
}
let mut e = world.get_entity_mut(entity).unwrap();
let mut transform = e.get_mut::<Transform>().unwrap();
if transform.is_changed() {
@@ -321,24 +352,29 @@ fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Elemen
}
let value = value.to_radians();
let euler = transform.rotation.to_euler(EulerRot::XYZ);
transform.rotation = transform.rotation * Quat::from_axis_angle(Vec3::Y, value - euler.1);
}
))
transform.rotation = transform.rotation
* Quat::from_axis_angle(Vec3::Y, value - euler.1);
},
)),
}),
Element::Text("Z: ".to_string()),
Element::Component(Component {
tag: "input".to_string(),
tag: "input".to_string(),
attributes: vec![
("type".to_string(), "number".to_string()),
("value".to_string(), format!("{:.2}",degrees.2)),
("value".to_string(), format!("{:.2}", degrees.2)),
("step".to_string(), "0.01".to_string()),
],
children: vec![],
onchange: Some(EntityChangeExecutor::new_boxed(
onchange.entity_id,
|world : &mut World, entity, value : String| {
let Some(mut value) = value.parse::<f32>().ok() else { return; };
if value == -180.0 { value = 180.0; }
|world: &mut World, entity, value: String| {
let Some(mut value) = value.parse::<f32>().ok() else {
return;
};
if value == -180.0 {
value = 180.0;
}
let value = value.to_radians();
let mut e = world.get_entity_mut(entity).unwrap();
let mut transform = e.get_mut::<Transform>().unwrap();
@@ -346,20 +382,18 @@ fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Elemen
return;
}
let euler = transform.rotation.to_euler(EulerRot::XYZ);
transform.rotation = Quat::from_euler(EulerRot::XYZ, euler.0, euler.1, value);
}
))
})
transform.rotation =
Quat::from_euler(EulerRot::XYZ, euler.0, euler.1, value);
},
)),
}),
],
onchange: None
onchange: None,
}))
}
else if let Some(vec) = r.downcast_ref::<Vec3>() {
} else if let Some(vec) = r.downcast_ref::<Vec3>() {
Some(Element::Component(Component {
tag: "div".to_string(),
attributes: vec![
("class".to_string(), "struct-grid".to_string()),
],
attributes: vec![("class".to_string(), "struct-grid".to_string())],
children: vec![
Element::Text("X: ".to_string()),
Element::Component(Component {
@@ -368,10 +402,9 @@ fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Elemen
("type".to_string(), "number".to_string()),
("value".to_string(), format!("{:.2}", vec.x)),
("step".to_string(), "0.01".to_string()),
],
children: vec![],
onchange: Some(Box::new(ReflectValueExecutor::from(onchange.add_path("x"))))
onchange: Some(Box::new(ReflectValueExecutor::from(onchange.add_path("x")))),
}),
Element::Text("Y: ".to_string()),
Element::Component(Component {
@@ -382,7 +415,7 @@ fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Elemen
("step".to_string(), "0.01".to_string()),
],
children: vec![],
onchange: Some(Box::new(ReflectValueExecutor::from(onchange.add_path("y"))))
onchange: Some(Box::new(ReflectValueExecutor::from(onchange.add_path("y")))),
}),
Element::Text("Z: ".to_string()),
Element::Component(Component {
@@ -393,46 +426,29 @@ fn check_predefined(r : &dyn Reflect, onchange : ReflectChange) -> Option<Elemen
("step".to_string(), "0.01".to_string()),
],
children: vec![],
onchange: Some(Box::new(ReflectValueExecutor::from(onchange.add_path("z"))))
})
onchange: Some(Box::new(ReflectValueExecutor::from(onchange.add_path("z")))),
}),
],
onchange: None
}))
onchange: None,
}))
} else {
None
}
}
pub fn show_reflect(r : &dyn Reflect, reflect: ReflectChange) -> Option<Element> {
pub fn show_reflect(r: &dyn Reflect, reflect: ReflectChange) -> Option<Element> {
if let Some(vnode) = check_predefined(r, reflect.clone()) {
return Some(vnode);
}
match r.reflect_ref() {
bevy::reflect::ReflectRef::Struct(v) => {
None
},
bevy::reflect::ReflectRef::TupleStruct(_) => {
None
},
bevy::reflect::ReflectRef::Tuple(_) => {
None
},
bevy::reflect::ReflectRef::List(_) => {
None
},
bevy::reflect::ReflectRef::Array(_) => {
None
},
bevy::reflect::ReflectRef::Map(_) => {
None
},
bevy::reflect::ReflectRef::Enum(_) => {
None
},
bevy::reflect::ReflectRef::Struct(v) => None,
bevy::reflect::ReflectRef::TupleStruct(_) => None,
bevy::reflect::ReflectRef::Tuple(_) => None,
bevy::reflect::ReflectRef::List(_) => None,
bevy::reflect::ReflectRef::Array(_) => None,
bevy::reflect::ReflectRef::Map(_) => None,
bevy::reflect::ReflectRef::Enum(_) => None,
bevy::reflect::ReflectRef::Value(v) => {
if let Some(s) = v.downcast_ref::<String>() {
Some(Element::Component(Component {
@@ -442,7 +458,7 @@ pub fn show_reflect(r : &dyn Reflect, reflect: ReflectChange) -> Option<Element>
("value".to_string(), s.to_string()),
],
children: vec![],
onchange: Some(Box::new(ReflectValueExecutor::from(reflect)))
onchange: Some(Box::new(ReflectValueExecutor::from(reflect))),
}))
} else if let Some(b) = v.downcast_ref::<bool>() {
Some(Element::Component(Component {
@@ -452,7 +468,7 @@ pub fn show_reflect(r : &dyn Reflect, reflect: ReflectChange) -> Option<Element>
("value".to_string(), b.to_string()),
],
children: vec![],
onchange: Some(Box::new(ReflectValueExecutor::from(reflect)))
onchange: Some(Box::new(ReflectValueExecutor::from(reflect))),
}))
} else if let Some(i) = v.downcast_ref::<i32>() {
Some(Element::Component(Component {
@@ -462,7 +478,7 @@ pub fn show_reflect(r : &dyn Reflect, reflect: ReflectChange) -> Option<Element>
("value".to_string(), i.to_string()),
],
children: vec![],
onchange: Some(Box::new(ReflectValueExecutor::from(reflect)))
onchange: Some(Box::new(ReflectValueExecutor::from(reflect))),
}))
} else if let Some(f) = v.downcast_ref::<f32>() {
Some(Element::Component(Component {
@@ -472,20 +488,20 @@ pub fn show_reflect(r : &dyn Reflect, reflect: ReflectChange) -> Option<Element>
("value".to_string(), f.to_string()),
],
children: vec![],
onchange: Some(Box::new(ReflectValueExecutor::from(reflect)))
onchange: Some(Box::new(ReflectValueExecutor::from(reflect))),
}))
} else {
Some(Element::Text(format!("{:?}", v)))
}
},
}
}
}
impl<T: Clone + PartialEq> NodeProp for T {}
pub fn show_string(s : &str) -> Option<VNode> {
Some(VNode::Text(s.to_string())
)}
pub fn show_string(s: &str) -> Option<VNode> {
Some(VNode::Text(s.to_string()))
}
#[derive(Clone, PartialEq, Serialize, Deserialize, Default)]
pub struct VComponent {
@@ -503,47 +519,41 @@ pub enum VNode {
}
impl VNode {
pub fn is_same_structure(&self, other : &VNode) -> bool {
pub fn is_same_structure(&self, other: &VNode) -> bool {
match (self, other) {
(VNode::Text(s1), VNode::Text(s2)) => s1 == s2,
(VNode::Text(_), VNode::Component(_)) => false,
(VNode::Component(_), VNode::Text(_)) => false,
(VNode::Component(c1), VNode::Component(c2)) => {
if c1.tag != c2.tag {
return false
return false;
} else if c1.children.len() != c2.children.len() {
return false
return false;
} else {
for i in 0..c1.children.len() {
if !c1.children[i].is_same_structure(&c2.children[i]) {
return false
return false;
}
}
return true
return true;
}
},
}
}
}
pub fn get_same_structure_muts(&self, older : &VNode) -> Vec<Mutation> {
pub fn get_same_structure_muts(&self, older: &VNode) -> Vec<Mutation> {
let mut res = vec![];
match (self, older) {
(VNode::Text(s1), VNode::Text(s2)) => {
res
}
(VNode::Text(_), VNode::Component(_)) => {
res
}
(VNode::Component(_), VNode::Text(_)) => {
res
}
(VNode::Text(s1), VNode::Text(s2)) => res,
(VNode::Text(_), VNode::Component(_)) => res,
(VNode::Component(_), VNode::Text(_)) => res,
(VNode::Component(new), VNode::Component(old)) => {
for idx in 0..new.attributes.len() {
if new.attributes.get(idx) != old.attributes.get(idx) {
res.push(Mutation::SetAttibute {
id: old.id.as_ref().unwrap().clone(),
attribute: new.attributes[idx].0.clone(),
value: new.attributes[idx].1.clone()
value: new.attributes[idx].1.clone(),
});
}
}
@@ -568,24 +578,24 @@ pub struct ComponentProp {
impl Clone for ComponentProp {
fn clone(&self) -> Self {
Self {
component: self.component.clone_value()
component: self.component.clone_value(),
}
}
}
#[derive(Serialize, Deserialize, Clone)]
pub struct ReflectChange {
pub entity_id : Entity,
pub entity_id: Entity,
pub reflect_path: String,
pub compoent_id: String
pub compoent_id: String,
}
impl ReflectChange {
pub fn add_path(&self, path : &str) -> ReflectChange {
pub fn add_path(&self, path: &str) -> ReflectChange {
ReflectChange {
entity_id : self.entity_id,
compoent_id : self.compoent_id.clone(),
reflect_path : format!("{}.{}", self.reflect_path, path)
entity_id: self.entity_id,
compoent_id: self.compoent_id.clone(),
reflect_path: format!("{}.{}", self.reflect_path, path),
}
}
@@ -600,7 +610,7 @@ impl<'a> PartialEq for ComponentProp {
}
}
pub fn recursive_reflect_eq(a : &dyn Reflect, b : &dyn Reflect) -> bool {
pub fn recursive_reflect_eq(a: &dyn Reflect, b: &dyn Reflect) -> bool {
let ref_a = a.reflect_ref();
let ref_b = b.reflect_ref();
@@ -619,7 +629,7 @@ pub fn recursive_reflect_eq(a : &dyn Reflect, b : &dyn Reflect) -> bool {
return false;
}
}
},
}
bevy::reflect::ReflectRef::TupleStruct(a) => {
let bevy::reflect::ReflectRef::TupleStruct(b) = b.reflect_ref() else {
return false;
@@ -634,7 +644,7 @@ pub fn recursive_reflect_eq(a : &dyn Reflect, b : &dyn Reflect) -> bool {
return false;
}
}
},
}
bevy::reflect::ReflectRef::Tuple(a) => {
let bevy::reflect::ReflectRef::Tuple(b) = b.reflect_ref() else {
return false;
@@ -649,7 +659,7 @@ pub fn recursive_reflect_eq(a : &dyn Reflect, b : &dyn Reflect) -> bool {
return false;
}
}
},
}
bevy::reflect::ReflectRef::List(a) => {
let bevy::reflect::ReflectRef::List(b) = b.reflect_ref() else {
return false;
@@ -664,7 +674,7 @@ pub fn recursive_reflect_eq(a : &dyn Reflect, b : &dyn Reflect) -> bool {
return false;
}
}
},
}
bevy::reflect::ReflectRef::Array(a) => {
let bevy::reflect::ReflectRef::Array(b) = b.reflect_ref() else {
return false;
@@ -679,7 +689,7 @@ pub fn recursive_reflect_eq(a : &dyn Reflect, b : &dyn Reflect) -> bool {
return false;
}
}
},
}
bevy::reflect::ReflectRef::Map(a) => {
let bevy::reflect::ReflectRef::Map(b) = b.reflect_ref() else {
return false;
@@ -699,7 +709,7 @@ pub fn recursive_reflect_eq(a : &dyn Reflect, b : &dyn Reflect) -> bool {
return false;
}
}
},
}
bevy::reflect::ReflectRef::Enum(a) => {
let bevy::reflect::ReflectRef::Enum(b) = b.reflect_ref() else {
return false;
@@ -718,7 +728,7 @@ pub fn recursive_reflect_eq(a : &dyn Reflect, b : &dyn Reflect) -> bool {
return false;
}
}
},
}
bevy::reflect::ReflectRef::Value(a) => {
let bevy::reflect::ReflectRef::Value(b) = b.reflect_ref() else {
return false;
@@ -729,7 +739,7 @@ pub fn recursive_reflect_eq(a : &dyn Reflect, b : &dyn Reflect) -> bool {
} else {
return false;
}
},
}
}
false
@@ -746,7 +756,6 @@ impl PartialEq for InspectedEntity {
}
for i in 0..self.components.len() {
if !recursive_reflect_eq(self.components[i].as_ref(), other.components[i].as_ref()) {
return false;
}
@@ -763,4 +772,4 @@ impl InspectedEntity {
components: Vec::new(),
}
}
}
}