Skip to content

Commit 6bc2686

Browse files
authored
impl ExclusiveSystemParam for SystemName (#11163)
# Objective `SystemName` might be useful in systems which accept `&mut World`. ## Solution - `impl ExclusiveSystemParam for SystemName` - move `SystemName` into a separate file, because it no longer belongs to a file which defines `SystemParam` - add a test for new impl, and for existing impl ## Changelog - `impl ExclusiveSystemParam for SystemName`
1 parent c2ab3a0 commit 6bc2686

File tree

3 files changed

+136
-86
lines changed

3 files changed

+136
-86
lines changed

crates/bevy_ecs/src/system/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ mod function_system;
110110
mod query;
111111
#[allow(clippy::module_inception)]
112112
mod system;
113+
mod system_name;
113114
mod system_param;
114115
mod system_registry;
115116

@@ -123,6 +124,7 @@ pub use exclusive_system_param::*;
123124
pub use function_system::*;
124125
pub use query::*;
125126
pub use system::*;
127+
pub use system_name::*;
126128
pub use system_param::*;
127129
pub use system_registry::*;
128130

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
use crate::component::Tick;
2+
use crate::prelude::World;
3+
use crate::system::{ExclusiveSystemParam, ReadOnlySystemParam, SystemMeta, SystemParam};
4+
use crate::world::unsafe_world_cell::UnsafeWorldCell;
5+
use std::borrow::Cow;
6+
use std::ops::Deref;
7+
8+
/// [`SystemParam`] that returns the name of the system which it is used in.
9+
///
10+
/// This is not a reliable identifier, it is more so useful for debugging or logging.
11+
///
12+
/// # Examples
13+
///
14+
/// ```
15+
/// # use bevy_ecs::system::SystemName;
16+
/// # use bevy_ecs::system::SystemParam;
17+
///
18+
/// #[derive(SystemParam)]
19+
/// struct Logger<'s> {
20+
/// system_name: SystemName<'s>,
21+
/// }
22+
///
23+
/// impl<'s> Logger<'s> {
24+
/// fn log(&mut self, message: &str) {
25+
/// eprintln!("{}: {}", self.system_name, message);
26+
/// }
27+
/// }
28+
///
29+
/// fn system1(mut logger: Logger) {
30+
/// // Prints: "crate_name::mod_name::system1: Hello".
31+
/// logger.log("Hello");
32+
/// }
33+
/// ```
34+
#[derive(Debug)]
35+
pub struct SystemName<'s>(&'s str);
36+
37+
impl<'s> SystemName<'s> {
38+
/// Gets the name of the system.
39+
pub fn name(&self) -> &str {
40+
self.0
41+
}
42+
}
43+
44+
impl<'s> Deref for SystemName<'s> {
45+
type Target = str;
46+
fn deref(&self) -> &Self::Target {
47+
self.name()
48+
}
49+
}
50+
51+
impl<'s> AsRef<str> for SystemName<'s> {
52+
fn as_ref(&self) -> &str {
53+
self.name()
54+
}
55+
}
56+
57+
impl<'s> From<SystemName<'s>> for &'s str {
58+
fn from(name: SystemName<'s>) -> &'s str {
59+
name.0
60+
}
61+
}
62+
63+
impl<'s> std::fmt::Display for SystemName<'s> {
64+
#[inline(always)]
65+
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
66+
std::fmt::Display::fmt(&self.name(), f)
67+
}
68+
}
69+
70+
// SAFETY: no component value access
71+
unsafe impl SystemParam for SystemName<'_> {
72+
type State = Cow<'static, str>;
73+
type Item<'w, 's> = SystemName<'s>;
74+
75+
fn init_state(_world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
76+
system_meta.name.clone()
77+
}
78+
79+
#[inline]
80+
unsafe fn get_param<'w, 's>(
81+
name: &'s mut Self::State,
82+
_system_meta: &SystemMeta,
83+
_world: UnsafeWorldCell<'w>,
84+
_change_tick: Tick,
85+
) -> Self::Item<'w, 's> {
86+
SystemName(name)
87+
}
88+
}
89+
90+
// SAFETY: Only reads internal system state
91+
unsafe impl<'s> ReadOnlySystemParam for SystemName<'s> {}
92+
93+
impl ExclusiveSystemParam for SystemName<'_> {
94+
type State = Cow<'static, str>;
95+
type Item<'s> = SystemName<'s>;
96+
97+
fn init(_world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
98+
system_meta.name.clone()
99+
}
100+
101+
fn get_param<'s>(state: &'s mut Self::State, _system_meta: &SystemMeta) -> Self::Item<'s> {
102+
SystemName(state)
103+
}
104+
}
105+
106+
#[cfg(test)]
107+
mod tests {
108+
use crate::system::SystemName;
109+
use crate::world::World;
110+
111+
#[test]
112+
fn test_system_name_regular_param() {
113+
fn testing(name: SystemName) -> String {
114+
name.name().to_owned()
115+
}
116+
117+
let mut world = World::default();
118+
let id = world.register_system(testing);
119+
let name = world.run_system(id).unwrap();
120+
assert!(name.ends_with("testing"));
121+
}
122+
123+
#[test]
124+
fn test_system_name_exclusive_param() {
125+
fn testing(_world: &mut World, name: SystemName) -> String {
126+
name.name().to_owned()
127+
}
128+
129+
let mut world = World::default();
130+
let id = world.register_system(testing);
131+
let name = world.run_system(id).unwrap();
132+
assert!(name.ends_with("testing"));
133+
}
134+
}

crates/bevy_ecs/src/system/system_param.rs

Lines changed: 0 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ pub use bevy_ecs_macros::SystemParam;
1818
use bevy_ptr::UnsafeCellDeref;
1919
use bevy_utils::{all_tuples, synccell::SyncCell};
2020
use std::{
21-
borrow::Cow,
2221
fmt::Debug,
2322
marker::PhantomData,
2423
ops::{Deref, DerefMut},
@@ -1287,91 +1286,6 @@ unsafe impl SystemParam for SystemChangeTick {
12871286
}
12881287
}
12891288

1290-
/// [`SystemParam`] that returns the name of the system which it is used in.
1291-
///
1292-
/// This is not a reliable identifier, it is more so useful for debugging or logging.
1293-
///
1294-
/// # Examples
1295-
///
1296-
/// ```
1297-
/// # use bevy_ecs::system::SystemName;
1298-
/// # use bevy_ecs::system::SystemParam;
1299-
///
1300-
/// #[derive(SystemParam)]
1301-
/// struct Logger<'s> {
1302-
/// system_name: SystemName<'s>,
1303-
/// }
1304-
///
1305-
/// impl<'s> Logger<'s> {
1306-
/// fn log(&mut self, message: &str) {
1307-
/// eprintln!("{}: {}", self.system_name, message);
1308-
/// }
1309-
/// }
1310-
///
1311-
/// fn system1(mut logger: Logger) {
1312-
/// // Prints: "crate_name::mod_name::system1: Hello".
1313-
/// logger.log("Hello");
1314-
/// }
1315-
/// ```
1316-
#[derive(Debug)]
1317-
pub struct SystemName<'s>(&'s str);
1318-
1319-
impl<'s> SystemName<'s> {
1320-
/// Gets the name of the system.
1321-
pub fn name(&self) -> &str {
1322-
self.0
1323-
}
1324-
}
1325-
1326-
impl<'s> Deref for SystemName<'s> {
1327-
type Target = str;
1328-
fn deref(&self) -> &Self::Target {
1329-
self.name()
1330-
}
1331-
}
1332-
1333-
impl<'s> AsRef<str> for SystemName<'s> {
1334-
fn as_ref(&self) -> &str {
1335-
self.name()
1336-
}
1337-
}
1338-
1339-
impl<'s> From<SystemName<'s>> for &'s str {
1340-
fn from(name: SystemName<'s>) -> &'s str {
1341-
name.0
1342-
}
1343-
}
1344-
1345-
impl<'s> std::fmt::Display for SystemName<'s> {
1346-
#[inline(always)]
1347-
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1348-
std::fmt::Display::fmt(&self.name(), f)
1349-
}
1350-
}
1351-
1352-
// SAFETY: no component value access
1353-
unsafe impl SystemParam for SystemName<'_> {
1354-
type State = Cow<'static, str>;
1355-
type Item<'w, 's> = SystemName<'s>;
1356-
1357-
fn init_state(_world: &mut World, system_meta: &mut SystemMeta) -> Self::State {
1358-
system_meta.name.clone()
1359-
}
1360-
1361-
#[inline]
1362-
unsafe fn get_param<'w, 's>(
1363-
name: &'s mut Self::State,
1364-
_system_meta: &SystemMeta,
1365-
_world: UnsafeWorldCell<'w>,
1366-
_change_tick: Tick,
1367-
) -> Self::Item<'w, 's> {
1368-
SystemName(name)
1369-
}
1370-
}
1371-
1372-
// SAFETY: Only reads internal system state
1373-
unsafe impl<'s> ReadOnlySystemParam for SystemName<'s> {}
1374-
13751289
macro_rules! impl_system_param_tuple {
13761290
($($param: ident),*) => {
13771291
// SAFETY: tuple consists only of ReadOnlySystemParams

0 commit comments

Comments
 (0)