Add common sense info to debug (fps, entity count)

main
Elijah Voigt 3 months ago
parent 9f307281f4
commit ca3db16a48

11
Cargo.lock generated

@ -2226,6 +2226,7 @@ dependencies = [
"bevy",
"bevy_rapier3d",
"chrono",
"lipsum",
"serde",
"thiserror 2.0.12",
"walkdir",
@ -2780,6 +2781,16 @@ version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12"
[[package]]
name = "lipsum"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "636860251af8963cc40f6b4baadee105f02e21b28131d76eba8e40ce84ab8064"
dependencies = [
"rand",
"rand_chacha",
]
[[package]]
name = "litrs"
version = "0.4.1"

@ -17,9 +17,9 @@ version = "0.30.0"
version = "0.16.1"
features = ["wayland", "dynamic_linking"]
[dev-dependencies]
lipsum = "*"
[build-dependencies]
chrono = "*"
walkdir = "*"
# [hints]
# mostly-unused = true

@ -5,8 +5,7 @@ use games::*;
fn main() {
let mut app = App::new();
app.add_plugins(BaseGamePlugin::default())
.add_systems(Startup, (setup_list, setup_nav_tree))
.add_systems(Update, run_tree.run_if(any_component_changed::<NavTree>));
.add_systems(Startup, (setup_list, setup_nav_tree));
app.run();
}
@ -40,62 +39,36 @@ fn setup_nav_tree(mut commands: Commands) {
Node {
position_type: PositionType::Absolute,
right: Val::Px(0.0),
width: Val::Px(100.0),
height: Val::Px(100.0),
top: Val::Percent(50.0),
min_width: Val::Px(25.0),
min_height: Val::Px(25.0),
..default()
},
BackgroundColor(RED.into()),
NavTree::Closed,
))
.with_children(|parent| {
parent
.spawn((
Node {
position_type: PositionType::Absolute,
right: Val::Px(100.0),
width: Val::Px(100.0),
height: Val::Px(100.0),
right: Val::Px(25.0),
min_width: Val::Px(25.0),
min_height: Val::Px(25.0),
..default()
},
BackgroundColor(ORANGE.into()),
NavTree::Closed,
))
.with_children(|parent| {
parent.spawn((
Node {
position_type: PositionType::Absolute,
right: Val::Px(100.0),
width: Val::Px(100.0),
height: Val::Px(100.0),
right: Val::Px(25.0),
min_width: Val::Px(25.0),
min_height: Val::Px(25.0),
..default()
},
BackgroundColor(YELLOW.into()),
NavTree::Closed,
));
});
});
}
fn run_tree(
q: Query<(Entity, &NavTree), Changed<NavTree>>,
children: Query<&Children>,
mut query: Query<(&ChildOf, &mut Visibility)>,
) {
q.iter().for_each(|(e, nav)| {
// todo!("Clean this code up please!");
match nav {
NavTree::Open => children.iter_descendants(e).for_each(|child| {
let (co, mut v) = query.get_mut(child).unwrap();
if ChildOf(e) == *co {
*v = Visibility::Inherited;
}
}),
NavTree::Closed => children.iter_descendants(e).for_each(|child| {
let (co, mut v) = query.get_mut(child).unwrap();
if ChildOf(e) == *co {
*v = Visibility::Hidden;
}
}),
}
});
}

@ -56,6 +56,8 @@ fn main() {
.add_observer(remove_tree_monologue)
.add_observer(hide_monologue_preview)
.add_observer(populate_tree)
.add_observer(show_monologue_list)
.add_observer(hide_monologue_list)
.run();
}
@ -119,13 +121,14 @@ fn init_debug_ui(mut commands: Commands) {
commands
.spawn((
Node {
height: Val::Percent(90.0),
max_height: Val::Percent(90.0),
align_self: AlignSelf::Center,
justify_self: JustifySelf::Start,
..default()
},
MonologuesContainer,
GlobalZIndex(i32::MAX - 1),
BackgroundColor(PINK.into()),
DebuggingState::On,
))
.with_children(|parent| {
@ -134,6 +137,7 @@ fn init_debug_ui(mut commands: Commands) {
height: Val::Percent(100.0),
flex_direction: FlexDirection::Column,
padding: UiRect::all(Val::Px(10.0)),
overflow: Overflow::scroll_y(),
..default()
},
BackgroundColor(PINK.with_alpha(0.9).into()),
@ -144,6 +148,7 @@ fn init_debug_ui(mut commands: Commands) {
height: Val::Percent(100.0),
flex_direction: FlexDirection::Column,
padding: UiRect::all(Val::Px(10.0)),
overflow: Overflow::scroll_y(),
..default()
},
BackgroundColor(ORANGE.with_alpha(0.9).into()),
@ -623,6 +628,32 @@ fn preview_monologue(
}
}
fn show_monologue_list(
trigger: Trigger<Pointer<Over>>,
container: Query<Entity, With<MonologuesContainer>>,
children: Query<&Children>,
mut visibility: Query<&mut Visibility>,
) {
if let Ok(root) = container.get(trigger.target()) {
children.iter_descendants(root).for_each(|e| {
*visibility.get_mut(e).unwrap() = Visibility::Inherited;
});
}
}
fn hide_monologue_list(
trigger: Trigger<Pointer<Out>>,
container: Query<Entity, With<MonologuesContainer>>,
children: Query<&Children>,
mut visibility: Query<&mut Visibility>,
) {
if let Ok(root) = container.get(trigger.target()) {
children.iter_descendants(root).for_each(|e| {
*visibility.get_mut(e).unwrap() = Visibility::Hidden;
});
}
}
fn spawn_monologue_tree(
trigger: Trigger<Pointer<Click>>,
tree_monologues: Query<&TreeMonologue, With<Button>>,

@ -1,3 +1,5 @@
use std::collections::VecDeque;
use super::*;
/// Debugging systems, resources, events, etc.
@ -7,6 +9,8 @@ impl Plugin for DebuggingPlugin {
fn build(&self, app: &mut App) {
app.init_state::<DebuggingState>()
.init_resource::<ToolTip>()
.init_resource::<Fps>()
.init_resource::<EntityCount>()
.add_plugins(RapierDebugRenderPlugin::default().disabled())
// Added by Rapier
// .add_plugins(AabbGizmoPlugin)
@ -24,6 +28,10 @@ impl Plugin for DebuggingPlugin {
.run_if(on_event::<Pointer<Over>>.or(on_event::<Pointer<Out>>)),
tooltip_follow.run_if(any_component_changed::<Window>),
sync_resource_to_ui::<ToolTip>.run_if(resource_changed::<ToolTip>),
track_fps,
sync_resource_to_ui::<Fps>.run_if(resource_changed::<Fps>),
track_entity_count,
sync_resource_to_ui::<EntityCount>.run_if(resource_changed::<EntityCount>),
)
.run_if(in_state(DebuggingState::On)),
),
@ -89,6 +97,37 @@ fn init_debug_ui(mut commands: Commands) {
},
));
// Version string for troubleshooting
commands.spawn((
DebuggingState::On,
Name::new("FPS"),
Text::new("FPS: ##.#"),
TextColor(WHITE.into()),
BackgroundColor(BLACK.into()),
SyncResource::<Fps>::default(),
Node {
width: Val::Auto,
align_self: AlignSelf::Start,
justify_self: JustifySelf::End,
..default()
},
));
commands.spawn((
DebuggingState::On,
Name::new("Entity Count"),
Text::new("Entities: ###"),
TextColor(WHITE.into()),
BackgroundColor(BLACK.into()),
SyncResource::<EntityCount>::default(),
Node {
width: Val::Auto,
align_self: AlignSelf::Start,
justify_self: JustifySelf::Center,
..default()
},
));
// Tooltip
commands.spawn((
DebuggingState::On,
@ -260,3 +299,48 @@ fn toggle_aabb_gizmo(
let (_, aabb_group) = config_store.config_mut::<AabbGizmoConfigGroup>();
aabb_group.draw_all = *state.get() == DebuggingState::On;
}
#[derive(Resource, Default, Debug)]
struct Fps(f32);
impl Display for Fps {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
writeln!(f, "FPS: {:0.1}", self.0)
}
}
fn track_fps(
time: Res<Time>,
mut fps: ResMut<Fps>,
mut history: Local<VecDeque<f32>>,
) {
// Get the time to render the last frame
let d = time.delta_secs();
// Add the latest delta to the list
history.push_back(d);
// Ensure the vecdeque doesn't get too long
if history.len() > 64 {
history.pop_front();
}
// Set FPS to 1/averageDeltaTime
fps.0 = 1.0 / (history.iter().fold(0.0, |acc, e| acc + e) / history.len() as f32);
}
#[derive(Resource, Default, Debug)]
struct EntityCount(usize);
impl Display for EntityCount {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
writeln!(f, "Entities: {}", self.0)
}
}
fn track_entity_count(
query: Query<Entity>,
mut count: ResMut<EntityCount>,
) {
count.0 = query.iter().len();
}

@ -4,10 +4,7 @@ pub(crate) struct BaseUiPlugin;
impl Plugin for BaseUiPlugin {
fn build(&self, app: &mut App) {
app.add_systems(
Update,
nav_tree.run_if(on_event::<Pointer<Over>>.or(on_event::<Pointer<Out>>)),
);
// TODO
}
}
@ -46,68 +43,10 @@ pub fn scroll(trigger: Trigger<Pointer<Scroll>>, mut scrollers: Query<&mut Scrol
}
#[derive(Component, Debug)]
pub enum NavTree {
Open,
Closed,
}
impl NavTree {
fn open(&mut self) {
*self = NavTree::Open;
}
fn close(&mut self) {
*self = NavTree::Closed;
}
}
#[relationship(relationship_target = NavParent)]
pub(crate) struct NavChild(Entity);
pub fn nav_tree(
mut over: EventReader<Pointer<Over>>,
mut out: EventReader<Pointer<Out>>,
mut query: Query<&mut NavTree>,
parents: Query<&Children>,
children: Query<&ChildOf>,
) {
// Get the entity that was just moused over (if any)
// Open this nav tree
let opens: Vec<Entity> = over
.read()
.filter_map(|over| {
query
.get_mut(over.target)
.map(|mut n| {
n.open();
over.target
})
.ok()
})
.collect();
// Close this nav tree if it is moused off
// and none of it's descendants were moused over
out.read().for_each(|out| {
if let Ok(mut nav) = query.get_mut(out.target) {
// Check if any of the opened entities is a child of this UI element
let mouse_over_child = parents
.iter_descendants(out.target)
.any(|child| opens.contains(&child));
if !mouse_over_child {
// Mouse still on nav tree
nav.close();
#[derive(Component, Debug)]
#[relationship_target(relationship = NavChild)]
pub(crate) struct NavParent(Vec<Entity>);
// Check if the mouse is over any ancestors
let mouse_over_parent = children
.iter_ancestors(out.target)
.any(|parent| opens.contains(&parent));
if !mouse_over_parent {
info!("Mouse is not over this tree");
children.iter_ancestors(out.target).for_each(|e| {
query.get_mut(e).iter_mut().for_each(|nav| {
nav.close();
});
});
}
}
}
});
}

Loading…
Cancel
Save