Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - SystemParam for the name of the system you are currently in #5731

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions crates/bevy_ecs/src/system/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
//! - [`NonSendMut`] and `Option<NonSendMut>`
//! - [`&World`](crate::world::World)
//! - [`RemovedComponents`]
//! - [`SystemName`]
//! - [`SystemChangeTick`]
//! - [`Archetypes`](crate::archetype::Archetypes) (Provides Archetype metadata)
//! - [`Bundles`](crate::bundle::Bundles) (Provides Bundles metadata)
Expand Down
86 changes: 86 additions & 0 deletions crates/bevy_ecs/src/system/system_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ pub use bevy_ecs_macros::SystemParam;
use bevy_ecs_macros::{all_tuples, impl_param_set};
use bevy_ptr::UnsafeCellDeref;
use std::{
borrow::Cow,
fmt::Debug,
marker::PhantomData,
ops::{Deref, DerefMut},
Expand Down Expand Up @@ -1304,6 +1305,91 @@ impl<'w, 's> SystemParamFetch<'w, 's> for SystemChangeTickState {
}
}

/// Name of the system that corresponds to this [`crate::system::SystemState`].
///
/// This is not a reliable identifier, it is more so useful for debugging
/// purposes of finding where a system parameter is being used incorrectly.
pub struct SystemName<'s> {
name: &'s str,
}

impl<'s> SystemName<'s> {
pub fn name(&self) -> &str {
self.name
}
}

impl<'s> Deref for SystemName<'s> {
type Target = str;
fn deref(&self) -> &Self::Target {
self.name()
}
}

impl<'s> AsRef<str> for SystemName<'s> {
fn as_ref(&self) -> &str {
self.name()
}
}

impl<'s> From<SystemName<'s>> for &'s str {
fn from(name: SystemName<'s>) -> &'s str {
name.name
}
}

impl<'s> std::fmt::Debug for SystemName<'s> {
#[inline(always)]
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
f.debug_tuple("SystemName").field(&self.name()).finish()
}
}

impl<'s> std::fmt::Display for SystemName<'s> {
#[inline(always)]
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
std::fmt::Display::fmt(&self.name(), f)
}
}

impl<'s> SystemParam for SystemName<'s> {
type Fetch = SystemNameState;
}

// SAFETY: Only reads internal system state
unsafe impl ReadOnlySystemParamFetch for SystemNameState {}

/// The [`SystemParamState`] of [`SystemName`].
#[doc(hidden)]
pub struct SystemNameState {
name: Cow<'static, str>,
}

// SAFETY: no component value access
unsafe impl SystemParamState for SystemNameState {
fn init(_world: &mut World, system_meta: &mut SystemMeta) -> Self {
Self {
name: system_meta.name.clone(),
}
}
}

impl<'w, 's> SystemParamFetch<'w, 's> for SystemNameState {
type Item = SystemName<'s>;

#[inline]
unsafe fn get_param(
state: &'s mut Self,
_system_meta: &SystemMeta,
_world: &'w World,
_change_tick: u32,
) -> Self::Item {
SystemName {
name: state.name.as_ref(),
}
}
}

macro_rules! impl_system_param_tuple {
($($param: ident),*) => {
impl<$($param: SystemParam),*> SystemParam for ($($param,)*) {
Expand Down