More work on the entity inspector
This commit is contained in:
parent
20c710f993
commit
5a4b1d60e9
|
@ -2,7 +2,10 @@ use bevy::{
|
||||||
app::{App, Startup},
|
app::{App, Startup},
|
||||||
core::{DebugName, Name},
|
core::{DebugName, Name},
|
||||||
core_pipeline::core_2d::Camera2dBundle,
|
core_pipeline::core_2d::Camera2dBundle,
|
||||||
ecs::{entity::Entity, query::Without, system::Commands, world::World},
|
ecs::{
|
||||||
|
entity::Entity, query::Without, reflect::AppTypeRegistry, system::Commands, world::World,
|
||||||
|
},
|
||||||
|
reflect::TypeInfo,
|
||||||
ui::{node_bundles::NodeBundle, Node},
|
ui::{node_bundles::NodeBundle, Node},
|
||||||
DefaultPlugins,
|
DefaultPlugins,
|
||||||
};
|
};
|
||||||
|
@ -92,30 +95,33 @@ fn SceneTree<'a>(cx: Scope, selected_entity: &'a UseState<Option<Entity>>) -> El
|
||||||
#[component]
|
#[component]
|
||||||
fn EntityInspector<'a>(cx: Scope, selected_entity: &'a UseState<Option<Entity>>) -> Element {
|
fn EntityInspector<'a>(cx: Scope, selected_entity: &'a UseState<Option<Entity>>) -> Element {
|
||||||
let world = use_world(cx);
|
let world = use_world(cx);
|
||||||
|
let type_registry = use_resource::<AppTypeRegistry>(cx).read();
|
||||||
let components = if let Some(selected_entity) = selected_entity.get() {
|
let components = selected_entity
|
||||||
let entity_ref = world.get_entity(*selected_entity).unwrap();
|
.get()
|
||||||
let archetype = entity_ref.archetype();
|
.map(|selected_entity| {
|
||||||
let mut components = archetype
|
let entity_ref = world.get_entity(selected_entity).unwrap();
|
||||||
.components()
|
let mut components = entity_ref
|
||||||
.map(|component_id| {
|
.archetype()
|
||||||
let info = world.components().get_info(component_id).unwrap();
|
.components()
|
||||||
let name = info.name();
|
.map(|component_id| {
|
||||||
|
let component_info = world.components().get_info(component_id).unwrap();
|
||||||
(name, component_id, info.type_id(), info.layout().size())
|
let type_info = component_info
|
||||||
})
|
.type_id()
|
||||||
.collect::<Vec<_>>();
|
.and_then(|type_id| type_registry.get_type_info(type_id));
|
||||||
components.sort_by(|(name_a, ..), (name_b, ..)| name_a.cmp(name_b));
|
let (module, name) = component_info.name().rsplit_once("::").unwrap();
|
||||||
components
|
(name, module, type_info)
|
||||||
} else {
|
})
|
||||||
vec![]
|
.collect::<Vec<_>>();
|
||||||
};
|
components.sort_by_key(|(name, _, _)| *name);
|
||||||
|
components
|
||||||
|
})
|
||||||
|
.unwrap_or_default();
|
||||||
|
|
||||||
render! {
|
render! {
|
||||||
if selected_entity.is_none() {
|
if selected_entity.is_none() {
|
||||||
rsx! {
|
rsx! {
|
||||||
node {
|
node {
|
||||||
padding: "8",
|
margin: "8",
|
||||||
"Select an entity to view its components"
|
"Select an entity to view its components"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -123,11 +129,21 @@ fn EntityInspector<'a>(cx: Scope, selected_entity: &'a UseState<Option<Entity>>)
|
||||||
rsx! {
|
rsx! {
|
||||||
node {
|
node {
|
||||||
flex_direction: "column",
|
flex_direction: "column",
|
||||||
for (name, _component_id, _type_id, _size) in components {
|
margin: "8",
|
||||||
|
text { text: "Entity Inspector", text_size: "24" }
|
||||||
|
for (name, module, type_info) in components {
|
||||||
node {
|
node {
|
||||||
padding: "8",
|
flex_direction: "column",
|
||||||
background_color: NEUTRAL_800,
|
margin_bottom: "6",
|
||||||
"Component: {name}"
|
node {
|
||||||
|
column_gap: "6",
|
||||||
|
align_items: "baseline",
|
||||||
|
text { text: name, text_size: "18" }
|
||||||
|
text { text: module, text_size: "14", text_color: NEUTRAL_400 }
|
||||||
|
}
|
||||||
|
if let Some(type_info) = type_info {
|
||||||
|
rsx!{ ComponentInspector { type_info: type_info } }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -136,6 +152,26 @@ fn EntityInspector<'a>(cx: Scope, selected_entity: &'a UseState<Option<Entity>>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[component]
|
||||||
|
fn ComponentInspector<'a>(cx: Scope, type_info: &'a TypeInfo) -> Element {
|
||||||
|
render! {
|
||||||
|
match type_info {
|
||||||
|
TypeInfo::Struct(info) => rsx! {
|
||||||
|
for field in info.iter() {
|
||||||
|
format!("{}: {}", field.name(), field.type_path())
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TypeInfo::TupleStruct(_) => rsx! { "TODO" },
|
||||||
|
TypeInfo::Tuple(_) => rsx! { "TODO" },
|
||||||
|
TypeInfo::List(_) => rsx! { "TODO" },
|
||||||
|
TypeInfo::Array(_) => rsx! { "TODO" },
|
||||||
|
TypeInfo::Map(_) => rsx! { "TODO" },
|
||||||
|
TypeInfo::Enum(_) => rsx! { "TODO" },
|
||||||
|
TypeInfo::Value(_) => rsx! { "TODO" },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn Button<'a>(cx: Scope<'a, ButtonProps<'a>>) -> Element<'a> {
|
fn Button<'a>(cx: Scope<'a, ButtonProps<'a>>) -> Element<'a> {
|
||||||
let clicked = use_state(cx, || false);
|
let clicked = use_state(cx, || false);
|
||||||
|
|
Loading…
Reference in a new issue