Add Display implementation to DebugName. (#13760)

# Objective

- When writing "in game" debugging tools, quite often you need the name
of an entity (for example an entity tree). DebugName is the usual way of
doing that.
- A recent change to Entity's Debug implementation meant it was no
longer a minimal {index}v{generation} but instead a more verbose auto
generated Debug.
- This made DebugName's Debug implementation also verbose

## Solution

- I changed DebugName to derive Debug automatically and added a new
(preferred) Display implementation for it which is the preferred name
for an entity. If the entity has a Name component its the contents of
that, otherwise it is {index}v{generation} (though this does not use
Display of the Entity as that is more verbose than this).

## Testing

- I've added a new test in name.rs which tests the Display
implementation for DebugName by using to_string.

---

## Migration Guide

- In code which uses DebugName you should now use the Display
implementation rather than the Debug implementation (ie {} instead of
{:?} if you were printing it out).

---------

Co-authored-by: John Payne <20407779+johngpayne@users.noreply.github.com>
Co-authored-by: Jan Hohenheim <jan@hohenheim.ch>
Co-authored-by: Andres O. Vela <andresovela@users.noreply.github.com>
This commit is contained in:
Gagnus 2024-06-25 13:58:53 +01:00 committed by GitHub
parent 54f1c4e21f
commit 1df811e6a5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -100,13 +100,19 @@ impl std::fmt::Debug for Name {
/// for (name, mut score) in &mut scores {
/// score.0 += 1.0;
/// if score.0.is_nan() {
/// bevy_utils::tracing::error!("Score for {:?} is invalid", name);
/// bevy_utils::tracing::error!("Score for {name} is invalid");
/// }
/// }
/// }
/// # bevy_ecs::system::assert_is_system(increment_score);
/// ```
///
/// # Implementation
///
/// The `Display` impl for `DebugName` returns the `Name` where there is one
/// or {index}v{generation} for entities without one.
#[derive(QueryData)]
#[query_data(derive(Debug))]
pub struct DebugName {
/// A [`Name`] that the entity might have that is displayed if available.
pub name: Option<&'static Name>,
@ -114,12 +120,12 @@ pub struct DebugName {
pub entity: Entity,
}
impl<'a> std::fmt::Debug for DebugNameItem<'a> {
impl<'a> std::fmt::Display for DebugNameItem<'a> {
#[inline(always)]
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self.name {
Some(name) => write!(f, "{:?} ({:?})", &name, &self.entity),
None => std::fmt::Debug::fmt(&self.entity, f),
Some(name) => std::fmt::Display::fmt(name, f),
None => write!(f, "{}v{}", self.entity.index(), self.entity.generation()),
}
}
}
@ -198,3 +204,24 @@ impl Deref for Name {
self.name.as_ref()
}
}
#[cfg(test)]
mod tests {
use super::*;
use bevy_ecs::world::World;
#[test]
fn test_display_of_debug_name() {
let mut world = World::new();
let e1 = world.spawn_empty().id();
let name = Name::new("MyName");
let e2 = world.spawn(name.clone()).id();
let mut query = world.query::<DebugName>();
let d1 = query.get(&world, e1).unwrap();
let d2 = query.get(&world, e2).unwrap();
// DebugName Display for entities without a Name should be {index}v{generation}
assert_eq!(d1.to_string(), "0v1");
// DebugName Display for entities with a Name should be the Name
assert_eq!(d2.to_string(), "MyName");
}
}