Skip to content

Commit

Permalink
SystemParam for the name of the system you are currently in (bevyengi…
Browse files Browse the repository at this point in the history
…ne#5731)

# Objective
- Similar to `SystemChangeTick`, probably somewhat useful for debugging messages.

---

## Changelog

- Added `SystemName` which copies the `SystemMeta::name` field so it can be accessed within a system.
  • Loading branch information
Aceeri authored and james7132 committed Oct 28, 2022
1 parent 5c5337c commit cb00604
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 0 deletions.
1 change: 1 addition & 0 deletions crates/bevy_ecs/src/system/mod.rs
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
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

0 comments on commit cb00604

Please sign in to comment.