diff --git a/crates/bevy_ecs/src/component.rs b/crates/bevy_ecs/src/component.rs index 27917d5fd6..2e5700f2fd 100644 --- a/crates/bevy_ecs/src/component.rs +++ b/crates/bevy_ecs/src/component.rs @@ -1,9 +1,10 @@ //! Types for declaring and storing [`Component`]s. use crate::{ + self as bevy_ecs, change_detection::MAX_CHANGE_AGE, storage::{SparseSetIndex, Storages}, - system::{Local, Resource}, + system::{Local, Resource, SystemParam}, world::{FromWorld, World}, TypeIdMap, }; @@ -795,47 +796,54 @@ impl ComponentTicks { } } -/// Initialize and fetch a [`ComponentId`] for a specific type. +/// A [`SystemParam`] that provides access to the [`ComponentId`] for a specific type. /// /// # Example /// ```rust /// # use bevy_ecs::{system::Local, component::{Component, ComponentId, ComponentIdFor}}; /// #[derive(Component)] /// struct Player; -/// fn my_system(component_id: Local>) { -/// let component_id: ComponentId = component_id.into(); +/// fn my_system(component_id: ComponentIdFor) { +/// let component_id: ComponentId = component_id.get(); /// // ... /// } /// ``` -pub struct ComponentIdFor { - component_id: ComponentId, - phantom: PhantomData, -} +#[derive(SystemParam)] +pub struct ComponentIdFor<'s, T: Component>(Local<'s, InitComponentId>); -impl FromWorld for ComponentIdFor { - fn from_world(world: &mut World) -> Self { - Self { - component_id: world.init_component::(), - phantom: PhantomData, - } +impl ComponentIdFor<'_, T> { + /// Gets the [`ComponentId`] for the type `T`. + #[inline] + pub fn get(&self) -> ComponentId { + **self } } -impl std::ops::Deref for ComponentIdFor { +impl std::ops::Deref for ComponentIdFor<'_, T> { type Target = ComponentId; fn deref(&self) -> &Self::Target { - &self.component_id + &self.0.component_id } } -impl From> for ComponentId { +impl From> for ComponentId { + #[inline] fn from(to_component_id: ComponentIdFor) -> ComponentId { *to_component_id } } -impl<'s, T: Component> From>> for ComponentId { - fn from(to_component_id: Local>) -> ComponentId { - **to_component_id +/// Initializes the [`ComponentId`] for a specific type when used with [`FromWorld`]. +struct InitComponentId { + component_id: ComponentId, + marker: PhantomData, +} + +impl FromWorld for InitComponentId { + fn from_world(world: &mut World) -> Self { + Self { + component_id: world.init_component::(), + marker: PhantomData, + } } } diff --git a/crates/bevy_ecs/src/removal_detection.rs b/crates/bevy_ecs/src/removal_detection.rs index 81146371ad..5546f17eac 100644 --- a/crates/bevy_ecs/src/removal_detection.rs +++ b/crates/bevy_ecs/src/removal_detection.rs @@ -136,7 +136,7 @@ impl RemovedComponentEvents { /// ``` #[derive(SystemParam)] pub struct RemovedComponents<'w, 's, T: Component> { - component_id: Local<'s, ComponentIdFor>, + component_id: ComponentIdFor<'s, T>, reader: Local<'s, RemovedComponentReader>, event_sets: &'w RemovedComponentEvents, } @@ -180,7 +180,7 @@ impl<'w, 's, T: Component> RemovedComponents<'w, 's, T> { /// Fetch underlying [`Events`]. pub fn events(&self) -> Option<&Events> { - self.event_sets.get(**self.component_id) + self.event_sets.get(self.component_id.get()) } /// Destructures to get a mutable reference to the `ManualEventReader` @@ -195,7 +195,7 @@ impl<'w, 's, T: Component> RemovedComponents<'w, 's, T> { &Events, )> { self.event_sets - .get(**self.component_id) + .get(self.component_id.get()) .map(|events| (&mut *self.reader, events)) }