Make names of closure systems changable (#14369)

# Objective

When using tracing or
[`bevy_mod_debugdump`](https://github.com/jakobhellermann/bevy_mod_debugdump),
the names of function systems produced by closures are either ambiguous
(like `game::mainapp::{closure}` when tracing) or too long
(`bevy_mod_debugdump` includes full type signature if no name given),
which makes debugging with tracing difficult.

## Solution
Add a function `with_name` to rename a system. The proposed API can be
used in the following way:
```rust
app
    .add_systems(Startup, IntoSystem::into_system(|name: SystemName| {
        println!("System name: {}", name.name().to_owned());
    }).with_name("print_test_system"));
```

## Testing
- There is a test in
`bevy_ecs::system:system_name::test_closure_system_name_regular_param`
This commit is contained in:
Lars Frost 2024-07-18 20:07:47 +02:00 committed by GitHub
parent 26fc4c7198
commit dcbd30200e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 55 additions and 1 deletions

View file

@ -30,6 +30,19 @@ where
marker: PhantomData<fn() -> Marker>,
}
impl<Marker, F> ExclusiveFunctionSystem<Marker, F>
where
F: ExclusiveSystemParamFunction<Marker>,
{
/// Return this system with a new name.
///
/// Useful to give closure systems more readable and unique names for debugging and tracing.
pub fn with_name(mut self, new_name: impl Into<Cow<'static, str>>) -> Self {
self.system_meta.set_name(new_name.into());
self
}
}
/// A marker type used to distinguish exclusive function systems from regular function systems.
#[doc(hidden)]
pub struct IsExclusiveFunctionSystem;

View file

@ -56,6 +56,20 @@ impl SystemMeta {
&self.name
}
/// Sets the name of of this system.
///
/// Useful to give closure systems more readable and unique names for debugging and tracing.
pub fn set_name(&mut self, new_name: impl Into<Cow<'static, str>>) {
let new_name: Cow<'static, str> = new_name.into();
#[cfg(feature = "trace")]
{
let name = new_name.as_ref();
self.system_span = info_span!("system", name = name);
self.commands_span = info_span!("system_commands", name = name);
}
self.name = new_name;
}
/// Returns true if the system is [`Send`].
#[inline]
pub fn is_send(&self) -> bool {
@ -422,6 +436,14 @@ where
marker: PhantomData,
}
}
/// Return this system with a new name.
///
/// Useful to give closure systems more readable and unique names for debugging and tracing.
pub fn with_name(mut self, new_name: impl Into<Cow<'static, str>>) -> Self {
self.system_meta.set_name(new_name.into());
self
}
}
// De-initializes the cloned system.

View file

@ -105,7 +105,7 @@ impl ExclusiveSystemParam for SystemName<'_> {
#[cfg(test)]
mod tests {
use crate::system::SystemName;
use crate::system::{IntoSystem, RunSystemOnce, SystemName};
use crate::world::World;
#[test]
@ -131,4 +131,23 @@ mod tests {
let name = world.run_system(id).unwrap();
assert!(name.ends_with("testing"));
}
#[test]
fn test_closure_system_name_regular_param() {
let mut world = World::default();
let system =
IntoSystem::into_system(|name: SystemName| name.name().to_owned()).with_name("testing");
let name = world.run_system_once(system);
assert_eq!(name, "testing");
}
#[test]
fn test_exclusive_closure_system_name_regular_param() {
let mut world = World::default();
let system =
IntoSystem::into_system(|_world: &mut World, name: SystemName| name.name().to_owned())
.with_name("testing");
let name = world.run_system_once(system);
assert_eq!(name, "testing");
}
}