//! Types for declaring and storing [`Component`]s.12mod clone;3mod info;4mod register;5mod required;6mod tick;78pub use clone::*;9pub use info::*;10pub use register::*;11pub use required::*;12pub use tick::*;1314use crate::{15entity::EntityMapper,16lifecycle::ComponentHook,17system::{Local, SystemParam},18world::{FromWorld, World},19};20pub use bevy_ecs_macros::Component;21use core::{fmt::Debug, marker::PhantomData, ops::Deref};2223/// A data type that can be used to store data for an [entity].24///25/// `Component` is a [derivable trait]: this means that a data type can implement it by applying a `#[derive(Component)]` attribute to it.26/// However, components must always satisfy the `Send + Sync + 'static` trait bounds.27///28/// [entity]: crate::entity29/// [derivable trait]: https://doc.rust-lang.org/book/appendix-03-derivable-traits.html30///31/// # Examples32///33/// Components can take many forms: they are usually structs, but can also be of every other kind of data type, like enums or zero sized types.34/// The following examples show how components are laid out in code.35///36/// ```37/// # use bevy_ecs::component::Component;38/// # struct Color;39/// #40/// // A component can contain data...41/// #[derive(Component)]42/// struct LicensePlate(String);43///44/// // ... but it can also be a zero-sized marker.45/// #[derive(Component)]46/// struct Car;47///48/// // Components can also be structs with named fields...49/// #[derive(Component)]50/// struct VehiclePerformance {51/// acceleration: f32,52/// top_speed: f32,53/// handling: f32,54/// }55///56/// // ... or enums.57/// #[derive(Component)]58/// enum WheelCount {59/// Two,60/// Three,61/// Four,62/// }63/// ```64///65/// # Component and data access66///67/// Components can be marked as immutable by adding the `#[component(immutable)]`68/// attribute when using the derive macro.69/// See the documentation for [`ComponentMutability`] for more details around this70/// feature.71///72/// See the [`entity`] module level documentation to learn how to add or remove components from an entity.73///74/// See the documentation for [`Query`] to learn how to access component data from a system.75///76/// [`entity`]: crate::entity#usage77/// [`Query`]: crate::system::Query78/// [`ComponentMutability`]: crate::component::ComponentMutability79///80/// # Choosing a storage type81///82/// Components can be stored in the world using different strategies with their own performance implications.83/// By default, components are added to the [`Table`] storage, which is optimized for query iteration.84///85/// Alternatively, components can be added to the [`SparseSet`] storage, which is optimized for component insertion and removal.86/// This is achieved by adding an additional `#[component(storage = "SparseSet")]` attribute to the derive one:87///88/// ```89/// # use bevy_ecs::component::Component;90/// #91/// #[derive(Component)]92/// #[component(storage = "SparseSet")]93/// struct ComponentA;94/// ```95///96/// [`Table`]: crate::storage::Table97/// [`SparseSet`]: crate::storage::SparseSet98///99/// # Required Components100///101/// Components can specify Required Components. If some [`Component`] `A` requires [`Component`] `B`, then when `A` is inserted,102/// `B` will _also_ be initialized and inserted (if it was not manually specified).103///104/// The [`Default`] constructor will be used to initialize the component, by default:105///106/// ```107/// # use bevy_ecs::prelude::*;108/// #[derive(Component)]109/// #[require(B)]110/// struct A;111///112/// #[derive(Component, Default, PartialEq, Eq, Debug)]113/// struct B(usize);114///115/// # let mut world = World::default();116/// // This will implicitly also insert B with the Default constructor117/// let id = world.spawn(A).id();118/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());119///120/// // This will _not_ implicitly insert B, because it was already provided121/// world.spawn((A, B(11)));122/// ```123///124/// Components can have more than one required component:125///126/// ```127/// # use bevy_ecs::prelude::*;128/// #[derive(Component)]129/// #[require(B, C)]130/// struct A;131///132/// #[derive(Component, Default, PartialEq, Eq, Debug)]133/// #[require(C)]134/// struct B(usize);135///136/// #[derive(Component, Default, PartialEq, Eq, Debug)]137/// struct C(u32);138///139/// # let mut world = World::default();140/// // This will implicitly also insert B and C with their Default constructors141/// let id = world.spawn(A).id();142/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());143/// assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());144/// ```145///146/// You can define inline component values that take the following forms:147/// ```148/// # use bevy_ecs::prelude::*;149/// #[derive(Component)]150/// #[require(151/// B(1), // tuple structs152/// C { // named-field structs153/// x: 1,154/// ..Default::default()155/// },156/// D::One, // enum variants157/// E::ONE, // associated consts158/// F::new(1) // constructors159/// )]160/// struct A;161///162/// #[derive(Component, PartialEq, Eq, Debug)]163/// struct B(u8);164///165/// #[derive(Component, PartialEq, Eq, Debug, Default)]166/// struct C {167/// x: u8,168/// y: u8,169/// }170///171/// #[derive(Component, PartialEq, Eq, Debug)]172/// enum D {173/// Zero,174/// One,175/// }176///177/// #[derive(Component, PartialEq, Eq, Debug)]178/// struct E(u8);179///180/// impl E {181/// pub const ONE: Self = Self(1);182/// }183///184/// #[derive(Component, PartialEq, Eq, Debug)]185/// struct F(u8);186///187/// impl F {188/// fn new(value: u8) -> Self {189/// Self(value)190/// }191/// }192///193/// # let mut world = World::default();194/// let id = world.spawn(A).id();195/// assert_eq!(&B(1), world.entity(id).get::<B>().unwrap());196/// assert_eq!(&C { x: 1, y: 0 }, world.entity(id).get::<C>().unwrap());197/// assert_eq!(&D::One, world.entity(id).get::<D>().unwrap());198/// assert_eq!(&E(1), world.entity(id).get::<E>().unwrap());199/// assert_eq!(&F(1), world.entity(id).get::<F>().unwrap());200/// ````201///202///203/// You can also define arbitrary expressions by using `=`204///205/// ```206/// # use bevy_ecs::prelude::*;207/// #[derive(Component)]208/// #[require(C = init_c())]209/// struct A;210///211/// #[derive(Component, PartialEq, Eq, Debug)]212/// #[require(C = C(20))]213/// struct B;214///215/// #[derive(Component, PartialEq, Eq, Debug)]216/// struct C(usize);217///218/// fn init_c() -> C {219/// C(10)220/// }221///222/// # let mut world = World::default();223/// // This will implicitly also insert C with the init_c() constructor224/// let id = world.spawn(A).id();225/// assert_eq!(&C(10), world.entity(id).get::<C>().unwrap());226///227/// // This will implicitly also insert C with the `|| C(20)` constructor closure228/// let id = world.spawn(B).id();229/// assert_eq!(&C(20), world.entity(id).get::<C>().unwrap());230/// ```231///232/// Required components are _recursive_. This means, if a Required Component has required components,233/// those components will _also_ be inserted if they are missing:234///235/// ```236/// # use bevy_ecs::prelude::*;237/// #[derive(Component)]238/// #[require(B)]239/// struct A;240///241/// #[derive(Component, Default, PartialEq, Eq, Debug)]242/// #[require(C)]243/// struct B(usize);244///245/// #[derive(Component, Default, PartialEq, Eq, Debug)]246/// struct C(u32);247///248/// # let mut world = World::default();249/// // This will implicitly also insert B and C with their Default constructors250/// let id = world.spawn(A).id();251/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());252/// assert_eq!(&C(0), world.entity(id).get::<C>().unwrap());253/// ```254///255/// Note that cycles in the "component require tree" will result in stack overflows when attempting to256/// insert a component.257///258/// This "multiple inheritance" pattern does mean that it is possible to have duplicate requires for a given type259/// at different levels of the inheritance tree:260///261/// ```262/// # use bevy_ecs::prelude::*;263/// #[derive(Component)]264/// struct X(usize);265///266/// #[derive(Component, Default)]267/// #[require(X(1))]268/// struct Y;269///270/// #[derive(Component)]271/// #[require(272/// Y,273/// X(2),274/// )]275/// struct Z;276///277/// # let mut world = World::default();278/// // In this case, the x2 constructor is used for X279/// let id = world.spawn(Z).id();280/// assert_eq!(2, world.entity(id).get::<X>().unwrap().0);281/// ```282///283/// In general, this shouldn't happen often, but when it does the algorithm for choosing the constructor from the tree is simple and predictable:284/// 1. A constructor from a direct `#[require()]`, if one exists, is selected with priority.285/// 2. Otherwise, perform a Depth First Search on the tree of requirements and select the first one found.286///287/// From a user perspective, just think about this as the following:288/// 1. Specifying a required component constructor for Foo directly on a spawned component Bar will result in that constructor being used (and overriding existing constructors lower in the inheritance tree). This is the classic "inheritance override" behavior people expect.289/// 2. For cases where "multiple inheritance" results in constructor clashes, Components should be listed in "importance order". List a component earlier in the requirement list to initialize its inheritance tree earlier.290///291/// ## Registering required components at runtime292///293/// In most cases, required components should be registered using the `require` attribute as shown above.294/// However, in some cases, it may be useful to register required components at runtime.295///296/// This can be done through [`World::register_required_components`] or [`World::register_required_components_with`]297/// for the [`Default`] and custom constructors respectively:298///299/// ```300/// # use bevy_ecs::prelude::*;301/// #[derive(Component)]302/// struct A;303///304/// #[derive(Component, Default, PartialEq, Eq, Debug)]305/// struct B(usize);306///307/// #[derive(Component, PartialEq, Eq, Debug)]308/// struct C(u32);309///310/// # let mut world = World::default();311/// // Register B as required by A and C as required by B.312/// world.register_required_components::<A, B>();313/// world.register_required_components_with::<B, C>(|| C(2));314///315/// // This will implicitly also insert B with its Default constructor316/// // and C with the custom constructor defined by B.317/// let id = world.spawn(A).id();318/// assert_eq!(&B(0), world.entity(id).get::<B>().unwrap());319/// assert_eq!(&C(2), world.entity(id).get::<C>().unwrap());320/// ```321///322/// Similar rules as before apply to duplicate requires fer a given type at different levels323/// of the inheritance tree. `A` requiring `C` directly would take precedence over indirectly324/// requiring it through `A` requiring `B` and `B` requiring `C`.325///326/// Unlike with the `require` attribute, directly requiring the same component multiple times327/// for the same component will result in a panic. This is done to prevent conflicting constructors328/// and confusing ordering dependencies.329///330/// Note that requirements must currently be registered before the requiring component is inserted331/// into the world for the first time. Registering requirements after this will lead to a panic.332///333/// # Relationships between Entities334///335/// Sometimes it is useful to define relationships between entities. A common example is the336/// parent / child relationship. Since Components are how data is stored for Entities, one might337/// naturally think to create a Component which has a field of type [`Entity`].338///339/// To facilitate this pattern, Bevy provides the [`Relationship`](`crate::relationship::Relationship`)340/// trait. You can derive the [`Relationship`](`crate::relationship::Relationship`) and341/// [`RelationshipTarget`](`crate::relationship::RelationshipTarget`) traits in addition to the342/// Component trait in order to implement data driven relationships between entities, see the trait343/// docs for more details.344///345/// In addition, Bevy provides canonical implementations of the parent / child relationship via the346/// [`ChildOf`](crate::hierarchy::ChildOf) [`Relationship`](crate::relationship::Relationship) and347/// the [`Children`](crate::hierarchy::Children)348/// [`RelationshipTarget`](crate::relationship::RelationshipTarget).349///350/// # Adding component's hooks351///352/// See [`ComponentHooks`] for a detailed explanation of component's hooks.353///354/// Alternatively to the example shown in [`ComponentHooks`]' documentation, hooks can be configured using following attributes:355/// - `#[component(on_add = on_add_function)]`356/// - `#[component(on_insert = on_insert_function)]`357/// - `#[component(on_replace = on_replace_function)]`358/// - `#[component(on_remove = on_remove_function)]`359///360/// ```361/// # use bevy_ecs::component::Component;362/// # use bevy_ecs::lifecycle::HookContext;363/// # use bevy_ecs::world::DeferredWorld;364/// # use bevy_ecs::entity::Entity;365/// # use bevy_ecs::component::ComponentId;366/// # use core::panic::Location;367/// #368/// #[derive(Component)]369/// #[component(on_add = my_on_add_hook)]370/// #[component(on_insert = my_on_insert_hook)]371/// // Another possible way of configuring hooks:372/// // #[component(on_add = my_on_add_hook, on_insert = my_on_insert_hook)]373/// //374/// // We don't have a replace or remove hook, so we can leave them out:375/// // #[component(on_replace = my_on_replace_hook, on_remove = my_on_remove_hook)]376/// struct ComponentA;377///378/// fn my_on_add_hook(world: DeferredWorld, context: HookContext) {379/// // ...380/// }381///382/// // You can also destructure items directly in the signature383/// fn my_on_insert_hook(world: DeferredWorld, HookContext { caller, .. }: HookContext) {384/// // ...385/// }386/// ```387///388/// This also supports function calls that yield closures389///390/// ```391/// # use bevy_ecs::component::Component;392/// # use bevy_ecs::lifecycle::HookContext;393/// # use bevy_ecs::world::DeferredWorld;394/// #395/// #[derive(Component)]396/// #[component(on_add = my_msg_hook("hello"))]397/// #[component(on_despawn = my_msg_hook("yoink"))]398/// struct ComponentA;399///400/// // a hook closure generating function401/// fn my_msg_hook(message: &'static str) -> impl Fn(DeferredWorld, HookContext) {402/// move |_world, _ctx| {403/// println!("{message}");404/// }405/// }406///407/// ```408/// # Setting the clone behavior409///410/// You can specify how the [`Component`] is cloned when deriving it.411///412/// Your options are the functions and variants of [`ComponentCloneBehavior`]413/// See [Handlers section of `EntityClonerBuilder`](crate::entity::EntityClonerBuilder#handlers) to understand how this affects handler priority.414/// ```415/// # use bevy_ecs::prelude::*;416///417/// #[derive(Component)]418/// #[component(clone_behavior = Ignore)]419/// struct MyComponent;420///421/// ```422///423/// # Implementing the trait for foreign types424///425/// As a consequence of the [orphan rule], it is not possible to separate into two different crates the implementation of `Component` from the definition of a type.426/// This means that it is not possible to directly have a type defined in a third party library as a component.427/// This important limitation can be easily worked around using the [newtype pattern]:428/// this makes it possible to locally define and implement `Component` for a tuple struct that wraps the foreign type.429/// The following example gives a demonstration of this pattern.430///431/// ```432/// // `Component` is defined in the `bevy_ecs` crate.433/// use bevy_ecs::component::Component;434///435/// // `Duration` is defined in the `std` crate.436/// use std::time::Duration;437///438/// // It is not possible to implement `Component` for `Duration` from this position, as they are439/// // both foreign items, defined in an external crate. However, nothing prevents to define a new440/// // `Cooldown` type that wraps `Duration`. As `Cooldown` is defined in a local crate, it is441/// // possible to implement `Component` for it.442/// #[derive(Component)]443/// struct Cooldown(Duration);444/// ```445///446/// [orphan rule]: https://doc.rust-lang.org/book/ch10-02-traits.html#implementing-a-trait-on-a-type447/// [newtype pattern]: https://doc.rust-lang.org/book/ch19-03-advanced-traits.html#using-the-newtype-pattern-to-implement-external-traits-on-external-types448///449/// # `!Sync` Components450/// A `!Sync` type cannot implement `Component`. However, it is possible to wrap a `Send` but not `Sync`451/// type in [`SyncCell`] or the currently unstable [`Exclusive`] to make it `Sync`. This forces only452/// having mutable access (`&mut T` only, never `&T`), but makes it safe to reference across multiple453/// threads.454///455/// This will fail to compile since `RefCell` is `!Sync`.456/// ```compile_fail457/// # use std::cell::RefCell;458/// # use bevy_ecs::component::Component;459/// #[derive(Component)]460/// struct NotSync {461/// counter: RefCell<usize>,462/// }463/// ```464///465/// This will compile since the `RefCell` is wrapped with `SyncCell`.466/// ```467/// # use std::cell::RefCell;468/// # use bevy_ecs::component::Component;469/// use bevy_platform::cell::SyncCell;470///471/// // This will compile.472/// #[derive(Component)]473/// struct ActuallySync {474/// counter: SyncCell<RefCell<usize>>,475/// }476/// ```477///478/// [`SyncCell`]: bevy_platform::cell::SyncCell479/// [`Exclusive`]: https://doc.rust-lang.org/nightly/std/sync/struct.Exclusive.html480/// [`ComponentHooks`]: crate::lifecycle::ComponentHooks481#[diagnostic::on_unimplemented(482message = "`{Self}` is not a `Component`",483label = "invalid `Component`",484note = "consider annotating `{Self}` with `#[derive(Component)]`"485)]486pub trait Component: Send + Sync + 'static {487/// A constant indicating the storage type used for this component.488const STORAGE_TYPE: StorageType;489490/// A marker type to assist Bevy with determining if this component is491/// mutable, or immutable. Mutable components will have [`Component<Mutability = Mutable>`],492/// while immutable components will instead have [`Component<Mutability = Immutable>`].493///494/// * For a component to be mutable, this type must be [`Mutable`].495/// * For a component to be immutable, this type must be [`Immutable`].496type Mutability: ComponentMutability;497498/// Gets the `on_add` [`ComponentHook`] for this [`Component`] if one is defined.499fn on_add() -> Option<ComponentHook> {500None501}502503/// Gets the `on_insert` [`ComponentHook`] for this [`Component`] if one is defined.504fn on_insert() -> Option<ComponentHook> {505None506}507508/// Gets the `on_replace` [`ComponentHook`] for this [`Component`] if one is defined.509fn on_replace() -> Option<ComponentHook> {510None511}512513/// Gets the `on_remove` [`ComponentHook`] for this [`Component`] if one is defined.514fn on_remove() -> Option<ComponentHook> {515None516}517518/// Gets the `on_despawn` [`ComponentHook`] for this [`Component`] if one is defined.519fn on_despawn() -> Option<ComponentHook> {520None521}522523/// Registers required components.524///525/// # Safety526///527/// - `_required_components` must only contain components valid in `_components`.528fn register_required_components(529_component_id: ComponentId,530_required_components: &mut RequiredComponentsRegistrator,531) {532}533534/// Called when registering this component, allowing to override clone function (or disable cloning altogether) for this component.535///536/// See [Handlers section of `EntityClonerBuilder`](crate::entity::EntityClonerBuilder#handlers) to understand how this affects handler priority.537#[inline]538fn clone_behavior() -> ComponentCloneBehavior {539ComponentCloneBehavior::Default540}541542/// Maps the entities on this component using the given [`EntityMapper`]. This is used to remap entities in contexts like scenes and entity cloning.543/// When deriving [`Component`], this is populated by annotating fields containing entities with `#[entities]`544///545/// ```546/// # use bevy_ecs::{component::Component, entity::Entity};547/// #[derive(Component)]548/// struct Inventory {549/// #[entities]550/// items: Vec<Entity>551/// }552/// ```553///554/// Fields with `#[entities]` must implement [`MapEntities`](crate::entity::MapEntities).555///556/// Bevy provides various implementations of [`MapEntities`](crate::entity::MapEntities), so that arbitrary combinations like these are supported with `#[entities]`:557///558/// ```rust559/// # use bevy_ecs::{component::Component, entity::Entity};560/// #[derive(Component)]561/// struct Inventory {562/// #[entities]563/// items: Vec<Option<Entity>>564/// }565/// ```566///567/// You might need more specialized logic. A likely cause of this is your component contains collections of entities that568/// don't implement [`MapEntities`](crate::entity::MapEntities). In that case, you can annotate your component with569/// `#[component(map_entities)]`. Using this attribute, you must implement `MapEntities` for the570/// component itself, and this method will simply call that implementation.571///572/// ```573/// # use bevy_ecs::{component::Component, entity::{Entity, MapEntities, EntityMapper}};574/// # use std::collections::HashMap;575/// #[derive(Component)]576/// #[component(map_entities)]577/// struct Inventory {578/// items: HashMap<Entity, usize>579/// }580///581/// impl MapEntities for Inventory {582/// fn map_entities<M: EntityMapper>(&mut self, entity_mapper: &mut M) {583/// self.items = self.items584/// .drain()585/// .map(|(id, count)|(entity_mapper.get_mapped(id), count))586/// .collect();587/// }588/// }589/// # let a = Entity::from_bits(0x1_0000_0001);590/// # let b = Entity::from_bits(0x1_0000_0002);591/// # let mut inv = Inventory { items: Default::default() };592/// # inv.items.insert(a, 10);593/// # <Inventory as Component>::map_entities(&mut inv, &mut (a,b));594/// # assert_eq!(inv.items.get(&b), Some(&10));595/// ````596///597/// Alternatively, you can specify the path to a function with `#[component(map_entities = function_path)]`, similar to component hooks.598/// In this case, the inputs of the function should mirror the inputs to this method, with the second parameter being generic.599///600/// ```601/// # use bevy_ecs::{component::Component, entity::{Entity, MapEntities, EntityMapper}};602/// # use std::collections::HashMap;603/// #[derive(Component)]604/// #[component(map_entities = map_the_map)]605/// // Also works: map_the_map::<M> or map_the_map::<_>606/// struct Inventory {607/// items: HashMap<Entity, usize>608/// }609///610/// fn map_the_map<M: EntityMapper>(inv: &mut Inventory, entity_mapper: &mut M) {611/// inv.items = inv.items612/// .drain()613/// .map(|(id, count)|(entity_mapper.get_mapped(id), count))614/// .collect();615/// }616/// # let a = Entity::from_bits(0x1_0000_0001);617/// # let b = Entity::from_bits(0x1_0000_0002);618/// # let mut inv = Inventory { items: Default::default() };619/// # inv.items.insert(a, 10);620/// # <Inventory as Component>::map_entities(&mut inv, &mut (a,b));621/// # assert_eq!(inv.items.get(&b), Some(&10));622/// ````623///624/// You can use the turbofish (`::<A,B,C>`) to specify parameters when a function is generic, using either M or _ for the type of the mapper parameter.625#[inline]626fn map_entities<E: EntityMapper>(_this: &mut Self, _mapper: &mut E) {}627}628629mod private {630pub trait Seal {}631}632633/// The mutability option for a [`Component`]. This can either be:634/// * [`Mutable`]635/// * [`Immutable`]636///637/// This is controlled through either [`Component::Mutability`] or `#[component(immutable)]`638/// when using the derive macro.639///640/// Immutable components are guaranteed to never have an exclusive reference,641/// `&mut ...`, created while inserted onto an entity.642/// In all other ways, they are identical to mutable components.643/// This restriction allows hooks to observe all changes made to an immutable644/// component, effectively turning the `Insert` and `Replace` hooks into a645/// `OnMutate` hook.646/// This is not practical for mutable components, as the runtime cost of invoking647/// a hook for every exclusive reference created would be far too high.648///649/// # Examples650///651/// ```rust652/// # use bevy_ecs::component::Component;653/// #654/// #[derive(Component)]655/// #[component(immutable)]656/// struct ImmutableFoo;657/// ```658pub trait ComponentMutability: private::Seal + 'static {659/// Boolean to indicate if this mutability setting implies a mutable or immutable660/// component.661const MUTABLE: bool;662}663664/// Parameter indicating a [`Component`] is immutable.665///666/// See [`ComponentMutability`] for details.667pub struct Immutable;668669impl private::Seal for Immutable {}670671impl ComponentMutability for Immutable {672const MUTABLE: bool = false;673}674675/// Parameter indicating a [`Component`] is mutable.676///677/// See [`ComponentMutability`] for details.678pub struct Mutable;679680impl private::Seal for Mutable {}681682impl ComponentMutability for Mutable {683const MUTABLE: bool = true;684}685686/// The storage used for a specific component type.687///688/// # Examples689/// The [`StorageType`] for a component is configured via the derive attribute690///691/// ```692/// # use bevy_ecs::{prelude::*, component::*};693/// #[derive(Component)]694/// #[component(storage = "SparseSet")]695/// struct A;696/// ```697#[derive(Debug, Copy, Clone, Default, Eq, PartialEq)]698pub enum StorageType {699/// Provides fast and cache-friendly iteration, but slower addition and removal of components.700/// This is the default storage type.701#[default]702Table,703/// Provides fast addition and removal of components, but slower iteration.704SparseSet,705}706707/// A [`SystemParam`] that provides access to the [`ComponentId`] for a specific component type.708///709/// # Example710/// ```711/// # use bevy_ecs::{system::Local, component::{Component, ComponentId, ComponentIdFor}};712/// #[derive(Component)]713/// struct Player;714/// fn my_system(component_id: ComponentIdFor<Player>) {715/// let component_id: ComponentId = component_id.get();716/// // ...717/// }718/// ```719#[derive(SystemParam)]720pub struct ComponentIdFor<'s, T: Component>(Local<'s, InitComponentId<T>>);721722impl<T: Component> ComponentIdFor<'_, T> {723/// Gets the [`ComponentId`] for the type `T`.724#[inline]725pub fn get(&self) -> ComponentId {726**self727}728}729730impl<T: Component> Deref for ComponentIdFor<'_, T> {731type Target = ComponentId;732fn deref(&self) -> &Self::Target {733&self.0.component_id734}735}736737impl<T: Component> From<ComponentIdFor<'_, T>> for ComponentId {738#[inline]739fn from(to_component_id: ComponentIdFor<T>) -> ComponentId {740*to_component_id741}742}743744/// Initializes the [`ComponentId`] for a specific type when used with [`FromWorld`].745struct InitComponentId<T: Component> {746component_id: ComponentId,747marker: PhantomData<T>,748}749750impl<T: Component> FromWorld for InitComponentId<T> {751fn from_world(world: &mut World) -> Self {752Self {753component_id: world.register_component::<T>(),754marker: PhantomData,755}756}757}758759760