diff --git a/crates/bevy_ecs/src/schedule/executor/mod.rs b/crates/bevy_ecs/src/schedule/executor/mod.rs index 6c76abbd1a421..fdc11fe326c47 100644 --- a/crates/bevy_ecs/src/schedule/executor/mod.rs +++ b/crates/bevy_ecs/src/schedule/executor/mod.rs @@ -104,7 +104,7 @@ pub fn apply_deferred(world: &mut World) {} /// Returns `true` if the [`System`](crate::system::System) is an instance of [`apply_deferred`]. pub(super) fn is_apply_deferred(system: &BoxedSystem) -> bool { - use std::any::Any; + use crate::system::IntoSystem; // deref to use `System::type_id` instead of `Any::type_id` - system.as_ref().type_id() == apply_deferred.type_id() + system.as_ref().type_id() == apply_deferred.system_type_id() } diff --git a/crates/bevy_ecs/src/schedule/stepping.rs b/crates/bevy_ecs/src/schedule/stepping.rs index 0a5348b126dec..b82fd6da76468 100644 --- a/crates/bevy_ecs/src/schedule/stepping.rs +++ b/crates/bevy_ecs/src/schedule/stepping.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use crate::{ schedule::{InternedScheduleLabel, NodeId, Schedule, ScheduleLabel}, - system::{IntoSystem, ResMut, Resource, System}, + system::{IntoSystem, ResMut, Resource}, }; use bevy_utils::{ thiserror::Error, @@ -252,10 +252,7 @@ impl Stepping { schedule: impl ScheduleLabel, system: impl IntoSystem<(), (), Marker>, ) -> &mut Self { - // PERF: ideally we don't actually need to construct the system to retrieve the TypeId. - // Unfortunately currently IntoSystem::into_system(system).type_id() != TypeId::of::() - // If these are aligned, we can use TypeId::of::() here - let type_id = IntoSystem::into_system(system).type_id(); + let type_id = system.system_type_id(); self.updates.push(Update::SetBehavior( schedule.intern(), SystemIdentifier::Type(type_id), @@ -281,7 +278,7 @@ impl Stepping { schedule: impl ScheduleLabel, system: impl IntoSystem<(), (), Marker>, ) -> &mut Self { - let type_id = IntoSystem::into_system(system).type_id(); + let type_id = system.system_type_id(); self.updates.push(Update::SetBehavior( schedule.intern(), SystemIdentifier::Type(type_id), @@ -307,7 +304,7 @@ impl Stepping { schedule: impl ScheduleLabel, system: impl IntoSystem<(), (), Marker>, ) -> &mut Self { - let type_id = IntoSystem::into_system(system).type_id(); + let type_id = system.system_type_id(); self.updates.push(Update::SetBehavior( schedule.intern(), SystemIdentifier::Type(type_id), @@ -354,7 +351,7 @@ impl Stepping { schedule: impl ScheduleLabel, system: impl IntoSystem<(), (), Marker>, ) -> &mut Self { - let type_id = IntoSystem::into_system(system).type_id(); + let type_id = system.system_type_id(); self.updates.push(Update::ClearBehavior( schedule.intern(), SystemIdentifier::Type(type_id), diff --git a/crates/bevy_ecs/src/system/adapter_system.rs b/crates/bevy_ecs/src/system/adapter_system.rs index 0ccd2cf0991bd..24b32b899996f 100644 --- a/crates/bevy_ecs/src/system/adapter_system.rs +++ b/crates/bevy_ecs/src/system/adapter_system.rs @@ -81,10 +81,6 @@ where self.name.clone() } - fn type_id(&self) -> std::any::TypeId { - std::any::TypeId::of::() - } - fn component_access(&self) -> &crate::query::Access { self.system.component_access() } diff --git a/crates/bevy_ecs/src/system/combinator.rs b/crates/bevy_ecs/src/system/combinator.rs index 5a7a403c47169..4594eae39b639 100644 --- a/crates/bevy_ecs/src/system/combinator.rs +++ b/crates/bevy_ecs/src/system/combinator.rs @@ -142,10 +142,6 @@ where self.name.clone() } - fn type_id(&self) -> std::any::TypeId { - std::any::TypeId::of::() - } - fn component_access(&self) -> &Access { &self.component_access } diff --git a/crates/bevy_ecs/src/system/exclusive_function_system.rs b/crates/bevy_ecs/src/system/exclusive_function_system.rs index 1d9e1241d2232..aa5037b228274 100644 --- a/crates/bevy_ecs/src/system/exclusive_function_system.rs +++ b/crates/bevy_ecs/src/system/exclusive_function_system.rs @@ -11,7 +11,7 @@ use crate::{ }; use bevy_utils::all_tuples; -use std::{any::TypeId, borrow::Cow, marker::PhantomData}; +use std::{borrow::Cow, marker::PhantomData}; /// A function system that runs with exclusive [`World`] access. /// @@ -65,11 +65,6 @@ where self.system_meta.name.clone() } - #[inline] - fn type_id(&self) -> TypeId { - TypeId::of::() - } - #[inline] fn component_access(&self) -> &Access { self.system_meta.component_access_set.combined_access() @@ -250,3 +245,44 @@ macro_rules! impl_exclusive_system_function { // Note that we rely on the highest impl to be <= the highest order of the tuple impls // of `SystemParam` created. all_tuples!(impl_exclusive_system_function, 0, 16, F); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn into_system_type_id_consistency() { + fn test(function: T) + where + T: IntoSystem + Copy, + { + fn reference_system(_world: &mut World) {} + + use std::any::TypeId; + + let system = IntoSystem::into_system(function); + + assert_eq!( + system.type_id(), + function.system_type_id(), + "System::type_id should be consistent with IntoSystem::system_type_id" + ); + + assert_eq!( + system.type_id(), + TypeId::of::(), + "System::type_id should be consistent with TypeId::of::()" + ); + + assert_ne!( + system.type_id(), + IntoSystem::into_system(reference_system).type_id(), + "Different systems should have different TypeIds" + ); + } + + fn exclusive_function_system(_world: &mut World) {} + + test(exclusive_function_system); + } +} diff --git a/crates/bevy_ecs/src/system/function_system.rs b/crates/bevy_ecs/src/system/function_system.rs index 98f58b69242b5..3911ba83b57c0 100644 --- a/crates/bevy_ecs/src/system/function_system.rs +++ b/crates/bevy_ecs/src/system/function_system.rs @@ -9,7 +9,7 @@ use crate::{ }; use bevy_utils::all_tuples; -use std::{any::TypeId, borrow::Cow, marker::PhantomData}; +use std::{borrow::Cow, marker::PhantomData}; #[cfg(feature = "trace")] use bevy_utils::tracing::{info_span, Span}; @@ -453,11 +453,6 @@ where self.system_meta.name.clone() } - #[inline] - fn type_id(&self) -> TypeId { - TypeId::of::() - } - #[inline] fn component_access(&self) -> &Access { self.system_meta.component_access_set.combined_access() @@ -695,3 +690,44 @@ macro_rules! impl_system_function { // Note that we rely on the highest impl to be <= the highest order of the tuple impls // of `SystemParam` created. all_tuples!(impl_system_function, 0, 16, F); + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn into_system_type_id_consistency() { + fn test(function: T) + where + T: IntoSystem + Copy, + { + fn reference_system() {} + + use std::any::TypeId; + + let system = IntoSystem::into_system(function); + + assert_eq!( + system.type_id(), + function.system_type_id(), + "System::type_id should be consistent with IntoSystem::system_type_id" + ); + + assert_eq!( + system.type_id(), + TypeId::of::(), + "System::type_id should be consistent with TypeId::of::()" + ); + + assert_ne!( + system.type_id(), + IntoSystem::into_system(reference_system).type_id(), + "Different systems should have different TypeIds" + ); + } + + fn function_system() {} + + test(function_system); + } +} diff --git a/crates/bevy_ecs/src/system/mod.rs b/crates/bevy_ecs/src/system/mod.rs index c5d1dfb5c535e..a89e189670fc0 100644 --- a/crates/bevy_ecs/src/system/mod.rs +++ b/crates/bevy_ecs/src/system/mod.rs @@ -114,7 +114,7 @@ mod system_name; mod system_param; mod system_registry; -use std::borrow::Cow; +use std::{any::TypeId, borrow::Cow}; pub use adapter_system::*; pub use combinator::*; @@ -195,6 +195,12 @@ pub trait IntoSystem: Sized { let name = system.name(); AdapterSystem::new(f, system, name) } + + /// Get the [`TypeId`] of the [`System`] produced after calling [`into_system`](`IntoSystem::into_system`). + #[inline] + fn system_type_id(&self) -> TypeId { + TypeId::of::() + } } // All systems implicitly implement IntoSystem. diff --git a/crates/bevy_ecs/src/system/system.rs b/crates/bevy_ecs/src/system/system.rs index 073c93085937c..3cceb36ef8553 100644 --- a/crates/bevy_ecs/src/system/system.rs +++ b/crates/bevy_ecs/src/system/system.rs @@ -31,7 +31,10 @@ pub trait System: Send + Sync + 'static { /// Returns the system's name. fn name(&self) -> Cow<'static, str>; /// Returns the [`TypeId`] of the underlying system type. - fn type_id(&self) -> TypeId; + #[inline] + fn type_id(&self) -> TypeId { + TypeId::of::() + } /// Returns the system's component [`Access`]. fn component_access(&self) -> &Access; /// Returns the system's archetype component [`Access`].