Simplify the ComponentIdFor type (#8845)
# Objective
`ComponentIdFor` is a type that gives you access to a component's
`ComponentId` in a system. It is currently awkward to use, since it must
be wrapped in a `Local<>` to be used.
## Solution
Make `ComponentIdFor` a proper SystemParam.
---
## Changelog
- Refactored the type `ComponentIdFor` in order to simplify how it is
used.
## Migration Guide
The type `ComponentIdFor<T>` now implements `SystemParam` instead of
`FromWorld` -- this means it should be used as the parameter for a
system directly instead of being used in a `Local`.
```rust
// Before:
fn my_system(
component_id: Local<ComponentIdFor<MyComponent>>,
) {
let component_id = **component_id;
}
// After:
fn my_system(
component_id: ComponentIdFor<MyComponent>,
) {
let component_id = component_id.get();
}
```
This commit is contained in:
parent
13f50c7a53
commit
96a9d0405a
@ -1,9 +1,10 @@
|
|||||||
//! Types for declaring and storing [`Component`]s.
|
//! Types for declaring and storing [`Component`]s.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
|
self as bevy_ecs,
|
||||||
change_detection::MAX_CHANGE_AGE,
|
change_detection::MAX_CHANGE_AGE,
|
||||||
storage::{SparseSetIndex, Storages},
|
storage::{SparseSetIndex, Storages},
|
||||||
system::{Local, Resource},
|
system::{Local, Resource, SystemParam},
|
||||||
world::{FromWorld, World},
|
world::{FromWorld, World},
|
||||||
TypeIdMap,
|
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
|
/// # Example
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use bevy_ecs::{system::Local, component::{Component, ComponentId, ComponentIdFor}};
|
/// # use bevy_ecs::{system::Local, component::{Component, ComponentId, ComponentIdFor}};
|
||||||
/// #[derive(Component)]
|
/// #[derive(Component)]
|
||||||
/// struct Player;
|
/// struct Player;
|
||||||
/// fn my_system(component_id: Local<ComponentIdFor<Player>>) {
|
/// fn my_system(component_id: ComponentIdFor<Player>) {
|
||||||
/// let component_id: ComponentId = component_id.into();
|
/// let component_id: ComponentId = component_id.get();
|
||||||
/// // ...
|
/// // ...
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
pub struct ComponentIdFor<T: Component> {
|
#[derive(SystemParam)]
|
||||||
component_id: ComponentId,
|
pub struct ComponentIdFor<'s, T: Component>(Local<'s, InitComponentId<T>>);
|
||||||
phantom: PhantomData<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Component> FromWorld for ComponentIdFor<T> {
|
impl<T: Component> ComponentIdFor<'_, T> {
|
||||||
fn from_world(world: &mut World) -> Self {
|
/// Gets the [`ComponentId`] for the type `T`.
|
||||||
Self {
|
#[inline]
|
||||||
component_id: world.init_component::<T>(),
|
pub fn get(&self) -> ComponentId {
|
||||||
phantom: PhantomData,
|
**self
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Component> std::ops::Deref for ComponentIdFor<T> {
|
impl<T: Component> std::ops::Deref for ComponentIdFor<'_, T> {
|
||||||
type Target = ComponentId;
|
type Target = ComponentId;
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.component_id
|
&self.0.component_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Component> From<ComponentIdFor<T>> for ComponentId {
|
impl<T: Component> From<ComponentIdFor<'_, T>> for ComponentId {
|
||||||
|
#[inline]
|
||||||
fn from(to_component_id: ComponentIdFor<T>) -> ComponentId {
|
fn from(to_component_id: ComponentIdFor<T>) -> ComponentId {
|
||||||
*to_component_id
|
*to_component_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'s, T: Component> From<Local<'s, ComponentIdFor<T>>> for ComponentId {
|
/// Initializes the [`ComponentId`] for a specific type when used with [`FromWorld`].
|
||||||
fn from(to_component_id: Local<ComponentIdFor<T>>) -> ComponentId {
|
struct InitComponentId<T: Component> {
|
||||||
**to_component_id
|
component_id: ComponentId,
|
||||||
|
marker: PhantomData<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Component> FromWorld for InitComponentId<T> {
|
||||||
|
fn from_world(world: &mut World) -> Self {
|
||||||
|
Self {
|
||||||
|
component_id: world.init_component::<T>(),
|
||||||
|
marker: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,7 +136,7 @@ impl RemovedComponentEvents {
|
|||||||
/// ```
|
/// ```
|
||||||
#[derive(SystemParam)]
|
#[derive(SystemParam)]
|
||||||
pub struct RemovedComponents<'w, 's, T: Component> {
|
pub struct RemovedComponents<'w, 's, T: Component> {
|
||||||
component_id: Local<'s, ComponentIdFor<T>>,
|
component_id: ComponentIdFor<'s, T>,
|
||||||
reader: Local<'s, RemovedComponentReader<T>>,
|
reader: Local<'s, RemovedComponentReader<T>>,
|
||||||
event_sets: &'w RemovedComponentEvents,
|
event_sets: &'w RemovedComponentEvents,
|
||||||
}
|
}
|
||||||
@ -180,7 +180,7 @@ impl<'w, 's, T: Component> RemovedComponents<'w, 's, T> {
|
|||||||
|
|
||||||
/// Fetch underlying [`Events`].
|
/// Fetch underlying [`Events`].
|
||||||
pub fn events(&self) -> Option<&Events<RemovedComponentEntity>> {
|
pub fn events(&self) -> Option<&Events<RemovedComponentEntity>> {
|
||||||
self.event_sets.get(**self.component_id)
|
self.event_sets.get(self.component_id.get())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Destructures to get a mutable reference to the `ManualEventReader`
|
/// Destructures to get a mutable reference to the `ManualEventReader`
|
||||||
@ -195,7 +195,7 @@ impl<'w, 's, T: Component> RemovedComponents<'w, 's, T> {
|
|||||||
&Events<RemovedComponentEntity>,
|
&Events<RemovedComponentEntity>,
|
||||||
)> {
|
)> {
|
||||||
self.event_sets
|
self.event_sets
|
||||||
.get(**self.component_id)
|
.get(self.component_id.get())
|
||||||
.map(|events| (&mut *self.reader, events))
|
.map(|events| (&mut *self.reader, events))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user