Skip to main content

bevy_ecs/
lifecycle.rs

1//! This module contains various tools to allow you to react to component insertion or removal,
2//! as well as entity spawning and despawning.
3//!
4//! There are four main ways to react to these lifecycle events:
5//!
6//! 1. Using component hooks, which act as inherent constructors and destructors for components.
7//! 2. Using [observers], which are a user-extensible way to respond to events, including component lifecycle events.
8//! 3. Using the [`RemovedComponents`] system parameter, which offers an event-style interface.
9//! 4. Using the [`Added`] query filter, which checks each component to see if it has been added since the last time a system ran.
10//!
11//! [observers]: crate::observer
12//! [`Added`]: crate::query::Added
13//!
14//! # Types of lifecycle events
15//!
16//! There are five types of lifecycle events, split into two categories. First, we have lifecycle events that are triggered
17//! when a component is added to an entity:
18//!
19//! - [`Add`]: Triggered when a component is added to an entity that did not already have it.
20//! - [`Insert`]: Triggered when a component is added to an entity, regardless of whether it already had it.
21//!
22//! When both events occur, [`Add`] hooks are evaluated before [`Insert`].
23//!
24//! Next, we have lifecycle events that are triggered when a component is removed from an entity:
25//!
26//! - [`Discard`]: Triggered when a component is removed from an entity, regardless if it is then replaced with a new value.
27//! - [`Remove`]: Triggered when a component is removed from an entity and not replaced, before the component is removed.
28//! - [`Despawn`]: Triggered for each component on an entity when it is despawned.
29//!
30//! [`Discard`] hooks are evaluated before [`Remove`] hooks. When an entity is despawned,
31//! [`Despawn`] hooks are evaluated first, followed by [`Discard`] and then [`Remove`] hooks.
32//!
33//! [`Add`] and [`Remove`] are counterparts: they are only triggered when a component is added or removed
34//! from an entity in such a way as to cause a change in the component's presence on that entity.
35//! Similarly, [`Insert`] and [`Discard`] are counterparts: they are triggered when a component is added or overwritten
36//! on an entity, regardless of whether this results in a change in the component's presence on that entity.
37//!
38//! To reliably synchronize data structures using with component lifecycle events,
39//! you can combine [`Insert`] and [`Discard`] to fully capture any changes to the data.
40//! This is particularly useful in combination with immutable components,
41//! to avoid any lifecycle-bypassing mutations.
42//!
43//! ## Lifecycle events and component types
44//!
45//! Despite the absence of generics, each lifecycle event is associated with a specific component.
46//! When defining a component hook for a [`Component`] type, that component is used.
47//! When observers watch lifecycle events, the `B: Bundle` generic is used.
48//!
49//! Each of these lifecycle events also corresponds to a fixed [`ComponentId`],
50//! which are assigned during [`World`] initialization.
51//! For example, [`Add`] corresponds to [`ADD`].
52//! This is used to skip [`TypeId`](core::any::TypeId) lookups in hot paths.
53use crate::{
54    change_detection::{MaybeLocation, Tick},
55    component::{Component, ComponentId, ComponentIdFor},
56    entity::Entity,
57    event::{EntityComponentsTrigger, EntityEvent, EventKey},
58    message::{
59        Message, MessageCursor, MessageId, MessageIterator, MessageIteratorWithId, Messages,
60    },
61    query::FilteredAccessSet,
62    relationship::RelationshipHookMode,
63    storage::SparseSet,
64    system::{Local, ReadOnlySystemParam, SystemMeta, SystemParam, SystemParamValidationError},
65    world::{unsafe_world_cell::UnsafeWorldCell, DeferredWorld, World},
66};
67
68use derive_more::derive::Into;
69
70#[cfg(feature = "bevy_reflect")]
71use bevy_reflect::Reflect;
72use core::{
73    fmt::Debug,
74    iter,
75    marker::PhantomData,
76    ops::{Deref, DerefMut},
77    option,
78};
79
80/// The type used for [`Component`] lifecycle hooks such as `on_add`, `on_insert` or `on_remove`.
81pub type ComponentHook = for<'w> fn(DeferredWorld<'w>, HookContext);
82
83/// Context provided to a [`ComponentHook`].
84#[derive(#[automatically_derived]
impl ::core::clone::Clone for HookContext {
    #[inline]
    fn clone(&self) -> HookContext {
        let _: ::core::clone::AssertParamIsClone<Entity>;
        let _: ::core::clone::AssertParamIsClone<ComponentId>;
        let _: ::core::clone::AssertParamIsClone<MaybeLocation>;
        let _: ::core::clone::AssertParamIsClone<RelationshipHookMode>;
        *self
    }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for HookContext { }Copy, #[automatically_derived]
impl ::core::fmt::Debug for HookContext {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "HookContext",
            "entity", &self.entity, "component_id", &self.component_id,
            "caller", &self.caller, "relationship_hook_mode",
            &&self.relationship_hook_mode)
    }
}Debug)]
85pub struct HookContext {
86    /// The [`Entity`] this hook was invoked for.
87    pub entity: Entity,
88    /// The [`ComponentId`] this hook was invoked for.
89    pub component_id: ComponentId,
90    /// The caller location is `Some` if the `track_caller` feature is enabled.
91    pub caller: MaybeLocation,
92    /// Configures how relationship hooks will run
93    pub relationship_hook_mode: RelationshipHookMode,
94}
95
96/// [`World`]-mutating functions that run as part of lifecycle events of a [`Component`].
97///
98/// Hooks are functions that run when a component is added, overwritten, or removed from an entity.
99/// These are intended to be used for structural side effects that need to happen when a component is added or removed,
100/// and are not intended for general-purpose logic.
101///
102/// For example, you might use a hook to update a cached index when a component is added,
103/// to clean up resources when a component is removed,
104/// or to keep hierarchical data structures across entities in sync.
105///
106/// This information is stored in the [`ComponentInfo`](crate::component::ComponentInfo) of the associated component.
107///
108/// There are two ways of configuring hooks for a component:
109/// 1. Defining the relevant hooks on the [`Component`] implementation
110/// 2. Using the [`World::register_component_hooks`] method
111///
112/// # Example
113///
114/// ```
115/// use bevy_ecs::prelude::*;
116/// use bevy_ecs::entity::EntityHashSet;
117///
118/// #[derive(Component)]
119/// struct MyTrackedComponent;
120///
121/// #[derive(Resource, Default)]
122/// struct TrackedEntities(EntityHashSet);
123///
124/// let mut world = World::new();
125/// world.init_resource::<TrackedEntities>();
126///
127/// // No entities with `MyTrackedComponent` have been added yet, so we can safely add component hooks
128/// let mut tracked_component_query = world.query::<&MyTrackedComponent>();
129/// assert!(tracked_component_query.iter(&world).next().is_none());
130///
131/// world.register_component_hooks::<MyTrackedComponent>().on_add(|mut world, context| {
132///    let mut tracked_entities = world.resource_mut::<TrackedEntities>();
133///   tracked_entities.0.insert(context.entity);
134/// });
135///
136/// world.register_component_hooks::<MyTrackedComponent>().on_remove(|mut world, context| {
137///   let mut tracked_entities = world.resource_mut::<TrackedEntities>();
138///   tracked_entities.0.remove(&context.entity);
139/// });
140///
141/// let entity = world.spawn(MyTrackedComponent).id();
142/// let tracked_entities = world.resource::<TrackedEntities>();
143/// assert!(tracked_entities.0.contains(&entity));
144///
145/// world.despawn(entity);
146/// let tracked_entities = world.resource::<TrackedEntities>();
147/// assert!(!tracked_entities.0.contains(&entity));
148/// ```
149#[derive(#[automatically_derived]
impl ::core::fmt::Debug for ComponentHooks {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field5_finish(f,
            "ComponentHooks", "on_add", &self.on_add, "on_insert",
            &self.on_insert, "on_discard", &self.on_discard, "on_remove",
            &self.on_remove, "on_despawn", &&self.on_despawn)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for ComponentHooks {
    #[inline]
    fn clone(&self) -> ComponentHooks {
        ComponentHooks {
            on_add: ::core::clone::Clone::clone(&self.on_add),
            on_insert: ::core::clone::Clone::clone(&self.on_insert),
            on_discard: ::core::clone::Clone::clone(&self.on_discard),
            on_remove: ::core::clone::Clone::clone(&self.on_remove),
            on_despawn: ::core::clone::Clone::clone(&self.on_despawn),
        }
    }
}Clone, #[automatically_derived]
impl ::core::default::Default for ComponentHooks {
    #[inline]
    fn default() -> ComponentHooks {
        ComponentHooks {
            on_add: ::core::default::Default::default(),
            on_insert: ::core::default::Default::default(),
            on_discard: ::core::default::Default::default(),
            on_remove: ::core::default::Default::default(),
            on_despawn: ::core::default::Default::default(),
        }
    }
}Default)]
150pub struct ComponentHooks {
151    pub(crate) on_add: Option<ComponentHook>,
152    pub(crate) on_insert: Option<ComponentHook>,
153    pub(crate) on_discard: Option<ComponentHook>,
154    pub(crate) on_remove: Option<ComponentHook>,
155    pub(crate) on_despawn: Option<ComponentHook>,
156}
157
158impl ComponentHooks {
159    pub(crate) fn update_from_component<C: Component + ?Sized>(&mut self) -> &mut Self {
160        if let Some(hook) = C::on_add() {
161            self.on_add(hook);
162        }
163        if let Some(hook) = C::on_insert() {
164            self.on_insert(hook);
165        }
166        if let Some(hook) = C::on_discard() {
167            self.on_discard(hook);
168        }
169        if let Some(hook) = C::on_remove() {
170            self.on_remove(hook);
171        }
172        if let Some(hook) = C::on_despawn() {
173            self.on_despawn(hook);
174        }
175
176        self
177    }
178
179    /// Register a [`ComponentHook`] that will be run when this component is added to an entity.
180    /// An `on_add` hook will always run before `on_insert` hooks. Spawning an entity counts as
181    /// adding all of its components.
182    ///
183    /// # Panics
184    ///
185    /// Will panic if the component already has an `on_add` hook
186    pub fn on_add(&mut self, hook: ComponentHook) -> &mut Self {
187        self.try_on_add(hook)
188            .expect("Component already has an on_add hook")
189    }
190
191    /// Register a [`ComponentHook`] that will be run when this component is added (with `.insert`)
192    /// or replaced.
193    ///
194    /// An `on_insert` hook always runs after any `on_add` hooks (if the entity didn't already have the component).
195    ///
196    /// # Warning
197    ///
198    /// The hook won't run if the component is already present and is only mutated, such as in a system via a query.
199    /// As a result, this needs to be combined with immutable components to serve as a mechanism for reliably updating indexes and other caches.
200    ///
201    /// # Panics
202    ///
203    /// Will panic if the component already has an `on_insert` hook
204    pub fn on_insert(&mut self, hook: ComponentHook) -> &mut Self {
205        self.try_on_insert(hook)
206            .expect("Component already has an on_insert hook")
207    }
208
209    /// Register a [`ComponentHook`] that will be run when this component is about to be dropped,
210    /// such as being replaced (with `.insert`) or removed.
211    ///
212    /// If this component is inserted onto an entity that already has it, this hook will run before the value is replaced,
213    /// allowing access to the previous data just before it is dropped.
214    /// This hook does *not* run if the entity did not already have this component.
215    ///
216    /// An `on_discard` hook always runs before any `on_remove` hooks (if the component is being removed from the entity).
217    ///
218    /// # Warning
219    ///
220    /// The hook won't run if the component is already present and is only mutated, such as in a system via a query.
221    /// As a result, this needs to be combined with immutable components to serve as a mechanism for reliably updating indexes and other caches.
222    ///
223    /// # Panics
224    ///
225    /// Will panic if the component already has an `on_discard` hook
226    pub fn on_discard(&mut self, hook: ComponentHook) -> &mut Self {
227        self.try_on_discard(hook)
228            .expect("Component already has an on_discard hook")
229    }
230
231    /// Register a [`ComponentHook`] that will be run when this component is removed from an entity.
232    /// Despawning an entity counts as removing all of its components.
233    ///
234    /// # Panics
235    ///
236    /// Will panic if the component already has an `on_remove` hook
237    pub fn on_remove(&mut self, hook: ComponentHook) -> &mut Self {
238        self.try_on_remove(hook)
239            .expect("Component already has an on_remove hook")
240    }
241
242    /// Register a [`ComponentHook`] that will be run for each component on an entity when it is despawned.
243    ///
244    /// # Panics
245    ///
246    /// Will panic if the component already has an `on_despawn` hook
247    pub fn on_despawn(&mut self, hook: ComponentHook) -> &mut Self {
248        self.try_on_despawn(hook)
249            .expect("Component already has an on_despawn hook")
250    }
251
252    /// Attempt to register a [`ComponentHook`] that will be run when this component is added to an entity.
253    ///
254    /// This is a fallible version of [`Self::on_add`].
255    ///
256    /// Returns `None` if the component already has an `on_add` hook.
257    pub fn try_on_add(&mut self, hook: ComponentHook) -> Option<&mut Self> {
258        if self.on_add.is_some() {
259            return None;
260        }
261        self.on_add = Some(hook);
262        Some(self)
263    }
264
265    /// Attempt to register a [`ComponentHook`] that will be run when this component is added (with `.insert`)
266    ///
267    /// This is a fallible version of [`Self::on_insert`].
268    ///
269    /// Returns `None` if the component already has an `on_insert` hook.
270    pub fn try_on_insert(&mut self, hook: ComponentHook) -> Option<&mut Self> {
271        if self.on_insert.is_some() {
272            return None;
273        }
274        self.on_insert = Some(hook);
275        Some(self)
276    }
277
278    /// Attempt to register a [`ComponentHook`] that will be run when this component is replaced (with `.insert`) or removed
279    ///
280    /// This is a fallible version of [`Self::on_discard`].
281    ///
282    /// Returns `None` if the component already has an `on_discard` hook.
283    pub fn try_on_discard(&mut self, hook: ComponentHook) -> Option<&mut Self> {
284        if self.on_discard.is_some() {
285            return None;
286        }
287        self.on_discard = Some(hook);
288        Some(self)
289    }
290
291    /// Attempt to register a [`ComponentHook`] that will be run when this component is removed from an entity.
292    ///
293    /// This is a fallible version of [`Self::on_remove`].
294    ///
295    /// Returns `None` if the component already has an `on_remove` hook.
296    pub fn try_on_remove(&mut self, hook: ComponentHook) -> Option<&mut Self> {
297        if self.on_remove.is_some() {
298            return None;
299        }
300        self.on_remove = Some(hook);
301        Some(self)
302    }
303
304    /// Attempt to register a [`ComponentHook`] that will be run for each component on an entity when it is despawned.
305    ///
306    /// This is a fallible version of [`Self::on_despawn`].
307    ///
308    /// Returns `None` if the component already has an `on_despawn` hook.
309    pub fn try_on_despawn(&mut self, hook: ComponentHook) -> Option<&mut Self> {
310        if self.on_despawn.is_some() {
311            return None;
312        }
313        self.on_despawn = Some(hook);
314        Some(self)
315    }
316}
317
318/// [`EventKey`] for [`Add`]
319pub const ADD: EventKey = EventKey(ComponentId::new(crate::component::ADD));
320/// [`EventKey`] for [`Insert`]
321pub const INSERT: EventKey = EventKey(ComponentId::new(crate::component::INSERT));
322/// [`EventKey`] for [`Discard`]
323pub const DISCARD: EventKey = EventKey(ComponentId::new(crate::component::DISCARD));
324/// [`EventKey`] for [`Remove`]
325pub const REMOVE: EventKey = EventKey(ComponentId::new(crate::component::REMOVE));
326/// [`EventKey`] for [`Despawn`]
327pub const DESPAWN: EventKey = EventKey(ComponentId::new(crate::component::DESPAWN));
328
329/// Trigger emitted when a component is inserted onto an entity that does not already have that
330/// component. Runs before `Insert`.
331/// See [`ComponentHooks::on_add`](`crate::lifecycle::ComponentHooks::on_add`) for more information.
332#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Add {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "Add", "entity",
            &&self.entity)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Add {
    #[inline]
    fn clone(&self) -> Add {
        Add { entity: ::core::clone::Clone::clone(&self.entity) }
    }
}Clone, impl bevy_ecs::event::EntityEvent for Add where Self: ::core::marker::Send +
    ::core::marker::Sync + 'static {
    fn event_target(&self) -> bevy_ecs::entity::Entity {
        bevy_ecs::entity::ContainsEntity::entity(&self.entity)
    }
}EntityEvent)]
333#[entity_event(trigger = EntityComponentsTrigger<'a>)]
334#[cfg_attr(feature = "bevy_reflect", derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for Add where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Entity as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for Add where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Entity>("entity")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for Add where  {
            fn type_path() -> &'static str { "bevy_ecs::lifecycle::Add" }
            fn short_type_path() -> &'static str { "Add" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("Add")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle")
            }
        }
        impl bevy_reflect::Reflect for Add where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl bevy_reflect::func::args::GetOwnership for Add where  {
            fn ownership() -> bevy_reflect::func::args::Ownership {
                bevy_reflect::func::args::Ownership::Owned
            }
        }
        impl bevy_reflect::func::args::FromArg for Add where  {
            type This<'from_arg> = Add;
            fn from_arg(arg: bevy_reflect::func::args::Arg)
                ->
                    ::core::result::Result<Self::This<'_>,
                    bevy_reflect::func::args::ArgError> {
                arg.take_owned()
            }
        }
        impl bevy_reflect::func::IntoReturn for Add where  {
            fn into_return<'into_return>(self)
                -> bevy_reflect::func::Return<'into_return> where
                Self: 'into_return {
                bevy_reflect::func::Return::Owned(bevy_reflect::__macro_exports::alloc_utils::Box::new(self))
            }
        }
        impl bevy_reflect::structs::Struct for Add where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "entity" => ::core::option::Option::Some(&self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "entity" => ::core::option::Option::Some(&mut self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("entity"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "entity" => ::core::option::Option::Some(0usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 1usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("entity",
                    bevy_reflect::PartialReflect::to_dynamic(&self.entity));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for Add where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            entity: <Entity as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.entity)?,
                        }))
            }
        }
        impl bevy_reflect::FromReflect for Add where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            entity: <Entity as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "entity")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect))]
335#[cfg_attr(feature = "bevy_reflect", reflect(Debug))]
336#[doc(alias = "OnAdd")]
337pub struct Add {
338    /// The entity this component was added to.
339    pub entity: Entity,
340}
341
342/// Trigger emitted when a component is inserted, regardless of whether or not the entity already
343/// had that component. Runs after `Add`, if it ran.
344/// See [`ComponentHooks::on_insert`](`crate::lifecycle::ComponentHooks::on_insert`) for more information.
345#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Insert {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "Insert",
            "entity", &&self.entity)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Insert {
    #[inline]
    fn clone(&self) -> Insert {
        Insert { entity: ::core::clone::Clone::clone(&self.entity) }
    }
}Clone, impl bevy_ecs::event::EntityEvent for Insert where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    fn event_target(&self) -> bevy_ecs::entity::Entity {
        bevy_ecs::entity::ContainsEntity::entity(&self.entity)
    }
}EntityEvent)]
346#[entity_event(trigger = EntityComponentsTrigger<'a>)]
347#[cfg_attr(feature = "bevy_reflect", derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for Insert where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Entity as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for Insert where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Entity>("entity")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for Insert where  {
            fn type_path() -> &'static str { "bevy_ecs::lifecycle::Insert" }
            fn short_type_path() -> &'static str { "Insert" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("Insert")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle")
            }
        }
        impl bevy_reflect::Reflect for Insert where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl bevy_reflect::func::args::GetOwnership for Insert where  {
            fn ownership() -> bevy_reflect::func::args::Ownership {
                bevy_reflect::func::args::Ownership::Owned
            }
        }
        impl bevy_reflect::func::args::FromArg for Insert where  {
            type This<'from_arg> = Insert;
            fn from_arg(arg: bevy_reflect::func::args::Arg)
                ->
                    ::core::result::Result<Self::This<'_>,
                    bevy_reflect::func::args::ArgError> {
                arg.take_owned()
            }
        }
        impl bevy_reflect::func::IntoReturn for Insert where  {
            fn into_return<'into_return>(self)
                -> bevy_reflect::func::Return<'into_return> where
                Self: 'into_return {
                bevy_reflect::func::Return::Owned(bevy_reflect::__macro_exports::alloc_utils::Box::new(self))
            }
        }
        impl bevy_reflect::structs::Struct for Insert where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "entity" => ::core::option::Option::Some(&self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "entity" => ::core::option::Option::Some(&mut self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("entity"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "entity" => ::core::option::Option::Some(0usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 1usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("entity",
                    bevy_reflect::PartialReflect::to_dynamic(&self.entity));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for Insert where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            entity: <Entity as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.entity)?,
                        }))
            }
        }
        impl bevy_reflect::FromReflect for Insert where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            entity: <Entity as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "entity")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect))]
348#[cfg_attr(feature = "bevy_reflect", reflect(Debug))]
349#[doc(alias = "OnInsert")]
350pub struct Insert {
351    /// The entity this component was inserted into.
352    pub entity: Entity,
353}
354
355/// Trigger emitted when a component is removed from an entity, regardless
356/// of whether or not it is later replaced.
357///
358/// Runs before the value is replaced, so you can still access the original component data.
359/// See [`ComponentHooks::on_discard`](`crate::lifecycle::ComponentHooks::on_discard`) for more information.
360#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Discard {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "Discard",
            "entity", &&self.entity)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Discard {
    #[inline]
    fn clone(&self) -> Discard {
        Discard { entity: ::core::clone::Clone::clone(&self.entity) }
    }
}Clone, impl bevy_ecs::event::EntityEvent for Discard where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    fn event_target(&self) -> bevy_ecs::entity::Entity {
        bevy_ecs::entity::ContainsEntity::entity(&self.entity)
    }
}EntityEvent)]
361#[entity_event(trigger = EntityComponentsTrigger<'a>)]
362#[cfg_attr(feature = "bevy_reflect", derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for Discard where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Entity as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for Discard where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Entity>("entity")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for Discard where  {
            fn type_path() -> &'static str { "bevy_ecs::lifecycle::Discard" }
            fn short_type_path() -> &'static str { "Discard" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("Discard")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle")
            }
        }
        impl bevy_reflect::Reflect for Discard where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl bevy_reflect::func::args::GetOwnership for Discard where  {
            fn ownership() -> bevy_reflect::func::args::Ownership {
                bevy_reflect::func::args::Ownership::Owned
            }
        }
        impl bevy_reflect::func::args::FromArg for Discard where  {
            type This<'from_arg> = Discard;
            fn from_arg(arg: bevy_reflect::func::args::Arg)
                ->
                    ::core::result::Result<Self::This<'_>,
                    bevy_reflect::func::args::ArgError> {
                arg.take_owned()
            }
        }
        impl bevy_reflect::func::IntoReturn for Discard where  {
            fn into_return<'into_return>(self)
                -> bevy_reflect::func::Return<'into_return> where
                Self: 'into_return {
                bevy_reflect::func::Return::Owned(bevy_reflect::__macro_exports::alloc_utils::Box::new(self))
            }
        }
        impl bevy_reflect::structs::Struct for Discard where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "entity" => ::core::option::Option::Some(&self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "entity" => ::core::option::Option::Some(&mut self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("entity"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "entity" => ::core::option::Option::Some(0usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 1usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("entity",
                    bevy_reflect::PartialReflect::to_dynamic(&self.entity));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for Discard where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            entity: <Entity as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.entity)?,
                        }))
            }
        }
        impl bevy_reflect::FromReflect for Discard where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            entity: <Entity as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "entity")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect))]
363#[cfg_attr(feature = "bevy_reflect", reflect(Debug))]
364#[doc(alias = "OnDiscard")]
365#[doc(alias = "OnReplace")]
366#[doc(alias = "Replace")]
367pub struct Discard {
368    /// The entity that held this component before it was discarded.
369    pub entity: Entity,
370}
371
372/// Trigger emitted when a component is removed from an entity, and runs before the component is
373/// removed, so you can still access the component data.
374/// See [`ComponentHooks::on_remove`](`crate::lifecycle::ComponentHooks::on_remove`) for more information.
375#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Remove {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "Remove",
            "entity", &&self.entity)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Remove {
    #[inline]
    fn clone(&self) -> Remove {
        Remove { entity: ::core::clone::Clone::clone(&self.entity) }
    }
}Clone, impl bevy_ecs::event::EntityEvent for Remove where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    fn event_target(&self) -> bevy_ecs::entity::Entity {
        bevy_ecs::entity::ContainsEntity::entity(&self.entity)
    }
}EntityEvent)]
376#[entity_event(trigger = EntityComponentsTrigger<'a>)]
377#[cfg_attr(feature = "bevy_reflect", derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for Remove where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Entity as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for Remove where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Entity>("entity")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for Remove where  {
            fn type_path() -> &'static str { "bevy_ecs::lifecycle::Remove" }
            fn short_type_path() -> &'static str { "Remove" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("Remove")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle")
            }
        }
        impl bevy_reflect::Reflect for Remove where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl bevy_reflect::func::args::GetOwnership for Remove where  {
            fn ownership() -> bevy_reflect::func::args::Ownership {
                bevy_reflect::func::args::Ownership::Owned
            }
        }
        impl bevy_reflect::func::args::FromArg for Remove where  {
            type This<'from_arg> = Remove;
            fn from_arg(arg: bevy_reflect::func::args::Arg)
                ->
                    ::core::result::Result<Self::This<'_>,
                    bevy_reflect::func::args::ArgError> {
                arg.take_owned()
            }
        }
        impl bevy_reflect::func::IntoReturn for Remove where  {
            fn into_return<'into_return>(self)
                -> bevy_reflect::func::Return<'into_return> where
                Self: 'into_return {
                bevy_reflect::func::Return::Owned(bevy_reflect::__macro_exports::alloc_utils::Box::new(self))
            }
        }
        impl bevy_reflect::structs::Struct for Remove where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "entity" => ::core::option::Option::Some(&self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "entity" => ::core::option::Option::Some(&mut self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("entity"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "entity" => ::core::option::Option::Some(0usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 1usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("entity",
                    bevy_reflect::PartialReflect::to_dynamic(&self.entity));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for Remove where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            entity: <Entity as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.entity)?,
                        }))
            }
        }
        impl bevy_reflect::FromReflect for Remove where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            entity: <Entity as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "entity")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect))]
378#[cfg_attr(feature = "bevy_reflect", reflect(Debug))]
379#[doc(alias = "OnRemove")]
380pub struct Remove {
381    /// The entity this component was removed from.
382    pub entity: Entity,
383}
384
385/// [`EntityEvent`] emitted for each component on an entity when it is despawned.
386/// See [`ComponentHooks::on_despawn`](`crate::lifecycle::ComponentHooks::on_despawn`) for more information.
387#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Despawn {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f, "Despawn",
            "entity", &&self.entity)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Despawn {
    #[inline]
    fn clone(&self) -> Despawn {
        Despawn { entity: ::core::clone::Clone::clone(&self.entity) }
    }
}Clone, impl bevy_ecs::event::EntityEvent for Despawn where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {
    fn event_target(&self) -> bevy_ecs::entity::Entity {
        bevy_ecs::entity::ContainsEntity::entity(&self.entity)
    }
}EntityEvent)]
388#[entity_event(trigger = EntityComponentsTrigger<'a>)]
389#[cfg_attr(feature = "bevy_reflect", derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for Despawn where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Entity as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for Despawn where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::Struct(bevy_reflect::structs::StructInfo::new::<Self>(&[bevy_reflect::NamedField::new::<Entity>("entity")]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for Despawn where  {
            fn type_path() -> &'static str { "bevy_ecs::lifecycle::Despawn" }
            fn short_type_path() -> &'static str { "Despawn" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("Despawn")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle")
            }
        }
        impl bevy_reflect::Reflect for Despawn where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl bevy_reflect::func::args::GetOwnership for Despawn where  {
            fn ownership() -> bevy_reflect::func::args::Ownership {
                bevy_reflect::func::args::Ownership::Owned
            }
        }
        impl bevy_reflect::func::args::FromArg for Despawn where  {
            type This<'from_arg> = Despawn;
            fn from_arg(arg: bevy_reflect::func::args::Arg)
                ->
                    ::core::result::Result<Self::This<'_>,
                    bevy_reflect::func::args::ArgError> {
                arg.take_owned()
            }
        }
        impl bevy_reflect::func::IntoReturn for Despawn where  {
            fn into_return<'into_return>(self)
                -> bevy_reflect::func::Return<'into_return> where
                Self: 'into_return {
                bevy_reflect::func::Return::Owned(bevy_reflect::__macro_exports::alloc_utils::Box::new(self))
            }
        }
        impl bevy_reflect::structs::Struct for Despawn where  {
            fn field(&self, name: &str)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match name {
                    "entity" => ::core::option::Option::Some(&self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, name: &str)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match name {
                    "entity" => ::core::option::Option::Some(&mut self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_at_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.entity),
                    _ => ::core::option::Option::None,
                }
            }
            fn name_at(&self, index: usize) -> ::core::option::Option<&str> {
                match index {
                    0usize => ::core::option::Option::Some("entity"),
                    _ => ::core::option::Option::None,
                }
            }
            fn index_of_name(&self, name: &str)
                -> ::core::option::Option<usize> {
                match name {
                    "entity" => ::core::option::Option::Some(0usize),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_len(&self) -> usize { 1usize }
            fn iter_fields(&self) -> bevy_reflect::structs::FieldIter {
                bevy_reflect::structs::FieldIter::new(self)
            }
            fn to_dynamic_struct(&self)
                -> bevy_reflect::structs::DynamicStruct {
                let mut dynamic: bevy_reflect::structs::DynamicStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed("entity",
                    bevy_reflect::PartialReflect::to_dynamic(&self.entity));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for Despawn where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::Struct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (name, value) in
                        bevy_reflect::structs::Struct::iter_fields(struct_value) {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::structs::Struct::field_mut(self, name) {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::Struct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::Struct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::Struct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::Struct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::Struct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::structs::struct_partial_eq)(self, value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::structs::struct_partial_cmp)(self, value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            #[allow(unreachable_code, reason =
            "Ignored fields without a `clone` attribute will early-return with an error")]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(Self {
                            entity: <Entity as
                                        bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.entity)?,
                        }))
            }
        }
        impl bevy_reflect::FromReflect for Despawn where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::Struct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            entity: <Entity as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::structs::Struct::field(__ref_struct,
                                            "entity")?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect))]
390#[cfg_attr(feature = "bevy_reflect", reflect(Debug))]
391#[doc(alias = "OnDespawn")]
392pub struct Despawn {
393    /// The entity that held this component before it was despawned.
394    pub entity: Entity,
395}
396
397/// Wrapper around [`Entity`] for [`RemovedComponents`].
398/// Internally, `RemovedComponents` uses these as an [`Messages<RemovedComponentEntity>`].
399#[derive(impl bevy_ecs::message::Message for RemovedComponentEntity where
    Self: ::core::marker::Send + ::core::marker::Sync + 'static {}Message, #[automatically_derived]
impl ::core::fmt::Debug for RemovedComponentEntity {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_tuple_field1_finish(f,
            "RemovedComponentEntity", &&self.0)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for RemovedComponentEntity {
    #[inline]
    fn clone(&self) -> RemovedComponentEntity {
        RemovedComponentEntity(::core::clone::Clone::clone(&self.0))
    }
}Clone, #[allow(clippy :: unused_unit)]
#[allow(deprecated)]
#[automatically_derived]
impl derive_more::core::convert::From<RemovedComponentEntity> for (Entity) {
    #[inline]
    fn from(value: RemovedComponentEntity) -> Self {
        (<Entity as derive_more::core::convert::From<_>>::from(value.0))
    }
}Into)]
400#[cfg_attr(feature = "bevy_reflect", derive(const _: () =
    {
        impl bevy_reflect::GetTypeRegistration for RemovedComponentEntity
            where  {
            fn get_type_registration() -> bevy_reflect::TypeRegistration {
                let mut registration =
                    bevy_reflect::TypeRegistration::of::<Self>();
                registration.insert::<bevy_reflect::ReflectFromPtr>(bevy_reflect::FromType::<Self>::from_type());
                registration.insert::<bevy_reflect::ReflectFromReflect>(bevy_reflect::FromType::<Self>::from_type());
                registration
            }
            #[inline(never)]
            fn register_type_dependencies(registry:
                    &mut bevy_reflect::TypeRegistry) {
                <Entity as
                        bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
            }
        }
        impl bevy_reflect::Typed for RemovedComponentEntity where  {
            #[inline]
            fn type_info() -> &'static bevy_reflect::TypeInfo {
                static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
                    bevy_reflect::utility::NonGenericTypeInfoCell::new();
                CELL.get_or_set(||
                        {
                            bevy_reflect::TypeInfo::TupleStruct(bevy_reflect::tuple_struct::TupleStructInfo::new::<Self>(&[bevy_reflect::UnnamedField::new::<Entity>(0usize)]))
                        })
            }
        }
        #[allow(deprecated, reason =
        "derives on a deprecated type shouldn't be considered a usage")]
        impl bevy_reflect::TypePath for RemovedComponentEntity where  {
            fn type_path() -> &'static str {
                "bevy_ecs::lifecycle::RemovedComponentEntity"
            }
            fn short_type_path() -> &'static str { "RemovedComponentEntity" }
            fn type_ident() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("RemovedComponentEntity")
            }
            fn crate_name() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle".split(':').next().unwrap())
            }
            fn module_path() -> ::core::option::Option<&'static str> {
                ::core::option::Option::Some("bevy_ecs::lifecycle")
            }
        }
        impl bevy_reflect::Reflect for RemovedComponentEntity where  {
            #[inline]
            fn into_any(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn ::core::any::Any> {
                self
            }
            #[inline]
            fn as_any(&self) -> &dyn ::core::any::Any { self }
            #[inline]
            fn as_any_mut(&mut self) -> &mut dyn ::core::any::Any { self }
            #[inline]
            fn into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect> {
                self
            }
            #[inline]
            fn as_reflect(&self) -> &dyn bevy_reflect::Reflect { self }
            #[inline]
            fn as_reflect_mut(&mut self) -> &mut dyn bevy_reflect::Reflect {
                self
            }
            #[inline]
            fn set(&mut self,
                value:
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>)
                ->
                    ::core::result::Result<(),
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>> {
                *self = <dyn bevy_reflect::Reflect>::take(value)?;
                ::core::result::Result::Ok(())
            }
        }
        impl bevy_reflect::func::args::GetOwnership for RemovedComponentEntity
            where  {
            fn ownership() -> bevy_reflect::func::args::Ownership {
                bevy_reflect::func::args::Ownership::Owned
            }
        }
        impl bevy_reflect::func::args::FromArg for RemovedComponentEntity
            where  {
            type This<'from_arg> = RemovedComponentEntity;
            fn from_arg(arg: bevy_reflect::func::args::Arg)
                ->
                    ::core::result::Result<Self::This<'_>,
                    bevy_reflect::func::args::ArgError> {
                arg.take_owned()
            }
        }
        impl bevy_reflect::func::IntoReturn for RemovedComponentEntity where
            {
            fn into_return<'into_return>(self)
                -> bevy_reflect::func::Return<'into_return> where
                Self: 'into_return {
                bevy_reflect::func::Return::Owned(bevy_reflect::__macro_exports::alloc_utils::Box::new(self))
            }
        }
        impl bevy_reflect::tuple_struct::TupleStruct for
            RemovedComponentEntity where  {
            fn field(&self, index: usize)
                -> ::core::option::Option<&dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&self.0),
                    _ => ::core::option::Option::None,
                }
            }
            fn field_mut(&mut self, index: usize)
                ->
                    ::core::option::Option<&mut dyn bevy_reflect::PartialReflect> {
                match index {
                    0usize => ::core::option::Option::Some(&mut self.0),
                    _ => ::core::option::Option::None,
                }
            }
            #[inline]
            fn field_len(&self) -> usize { 1usize }
            #[inline]
            fn iter_fields(&self)
                -> bevy_reflect::tuple_struct::TupleStructFieldIter {
                bevy_reflect::tuple_struct::TupleStructFieldIter::new(self)
            }
            fn to_dynamic_tuple_struct(&self)
                -> bevy_reflect::tuple_struct::DynamicTupleStruct {
                let mut dynamic:
                        bevy_reflect::tuple_struct::DynamicTupleStruct =
                    ::core::default::Default::default();
                dynamic.set_represented_type(bevy_reflect::PartialReflect::get_represented_type_info(self));
                dynamic.insert_boxed(bevy_reflect::PartialReflect::to_dynamic(&self.0));
                dynamic
            }
        }
        impl bevy_reflect::PartialReflect for RemovedComponentEntity where  {
            #[inline]
            fn get_represented_type_info(&self)
                -> ::core::option::Option<&'static bevy_reflect::TypeInfo> {
                ::core::option::Option::Some(<Self as
                            bevy_reflect::Typed>::type_info())
            }
            #[inline]
            fn try_apply(&mut self, value: &dyn bevy_reflect::PartialReflect)
                -> ::core::result::Result<(), bevy_reflect::ApplyError> {
                if let bevy_reflect::ReflectRef::TupleStruct(struct_value) =
                        bevy_reflect::PartialReflect::reflect_ref(value) {
                    for (i, value) in
                        ::core::iter::Iterator::enumerate(bevy_reflect::tuple_struct::TupleStruct::iter_fields(struct_value))
                        {
                        if let ::core::option::Option::Some(v) =
                                bevy_reflect::tuple_struct::TupleStruct::field_mut(self, i)
                            {
                            bevy_reflect::PartialReflect::try_apply(v, value)?;
                        }
                    }
                } else {
                    return ::core::result::Result::Err(bevy_reflect::ApplyError::MismatchedKinds {
                                from_kind: bevy_reflect::PartialReflect::reflect_kind(value),
                                to_kind: bevy_reflect::ReflectKind::TupleStruct,
                            });
                }
                ::core::result::Result::Ok(())
            }
            #[inline]
            fn reflect_kind(&self) -> bevy_reflect::ReflectKind {
                bevy_reflect::ReflectKind::TupleStruct
            }
            #[inline]
            fn reflect_ref(&self) -> bevy_reflect::ReflectRef {
                bevy_reflect::ReflectRef::TupleStruct(self)
            }
            #[inline]
            fn reflect_mut(&mut self) -> bevy_reflect::ReflectMut {
                bevy_reflect::ReflectMut::TupleStruct(self)
            }
            #[inline]
            fn reflect_owned(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                -> bevy_reflect::ReflectOwned {
                bevy_reflect::ReflectOwned::TupleStruct(self)
            }
            #[inline]
            fn try_into_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect>> {
                ::core::result::Result::Ok(self)
            }
            #[inline]
            fn try_as_reflect(&self)
                -> ::core::option::Option<&dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn try_as_reflect_mut(&mut self)
                -> ::core::option::Option<&mut dyn bevy_reflect::Reflect> {
                ::core::option::Option::Some(self)
            }
            #[inline]
            fn into_partial_reflect(self:
                    bevy_reflect::__macro_exports::alloc_utils::Box<Self>)
                ->
                    bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::PartialReflect> {
                self
            }
            #[inline]
            fn as_partial_reflect(&self)
                -> &dyn bevy_reflect::PartialReflect {
                self
            }
            #[inline]
            fn as_partial_reflect_mut(&mut self)
                -> &mut dyn bevy_reflect::PartialReflect {
                self
            }
            fn reflect_partial_eq(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<bool> {
                (bevy_reflect::tuple_struct::tuple_struct_partial_eq)(self,
                    value)
            }
            fn reflect_partial_cmp(&self,
                value: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<::core::cmp::Ordering> {
                (bevy_reflect::tuple_struct::tuple_struct_partial_cmp)(self,
                    value)
            }
            fn debug(&self, f: &mut ::core::fmt::Formatter<'_>)
                -> ::core::fmt::Result {
                ::core::fmt::Debug::fmt(self, f)
            }
            #[inline]
            fn reflect_clone(&self)
                ->
                    ::core::result::Result<bevy_reflect::__macro_exports::alloc_utils::Box<dyn bevy_reflect::Reflect>,
                    bevy_reflect::ReflectCloneError> {
                ::core::result::Result::Ok(bevy_reflect::__macro_exports::alloc_utils::Box::new(::core::clone::Clone::clone(self)))
            }
        }
        impl bevy_reflect::FromReflect for RemovedComponentEntity where  {
            fn from_reflect(reflect: &dyn bevy_reflect::PartialReflect)
                -> ::core::option::Option<Self> {
                if let bevy_reflect::ReflectRef::TupleStruct(__ref_struct) =
                        bevy_reflect::PartialReflect::reflect_ref(reflect) {
                    let __this =
                        Self {
                            0: <Entity as
                                        bevy_reflect::FromReflect>::from_reflect(bevy_reflect::tuple_struct::TupleStruct::field(__ref_struct,
                                            0)?)?,
                        };
                    ::core::option::Option::Some(__this)
                } else { ::core::option::Option::None }
            }
        }
    };Reflect))]
401#[cfg_attr(feature = "bevy_reflect", reflect(Debug, Clone))]
402pub struct RemovedComponentEntity(Entity);
403
404/// Wrapper around a [`MessageCursor<RemovedComponentEntity>`] so that we
405/// can differentiate messages between components.
406#[derive(#[automatically_derived]
impl<T: ::core::fmt::Debug> ::core::fmt::Debug for RemovedComponentReader<T>
    where T: Component {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field2_finish(f,
            "RemovedComponentReader", "reader", &self.reader, "marker",
            &&self.marker)
    }
}Debug)]
407pub struct RemovedComponentReader<T>
408where
409    T: Component,
410{
411    reader: MessageCursor<RemovedComponentEntity>,
412    marker: PhantomData<T>,
413}
414
415impl<T: Component> Default for RemovedComponentReader<T> {
416    fn default() -> Self {
417        Self {
418            reader: Default::default(),
419            marker: PhantomData,
420        }
421    }
422}
423
424impl<T: Component> Deref for RemovedComponentReader<T> {
425    type Target = MessageCursor<RemovedComponentEntity>;
426    fn deref(&self) -> &Self::Target {
427        &self.reader
428    }
429}
430
431impl<T: Component> DerefMut for RemovedComponentReader<T> {
432    fn deref_mut(&mut self) -> &mut Self::Target {
433        &mut self.reader
434    }
435}
436
437/// Stores the [`RemovedComponents`] event buffers for all types of component in a given [`World`].
438#[derive(#[automatically_derived]
impl ::core::default::Default for RemovedComponentMessages {
    #[inline]
    fn default() -> RemovedComponentMessages {
        RemovedComponentMessages {
            event_sets: ::core::default::Default::default(),
        }
    }
}Default, #[automatically_derived]
impl ::core::fmt::Debug for RemovedComponentMessages {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field1_finish(f,
            "RemovedComponentMessages", "event_sets", &&self.event_sets)
    }
}Debug)]
439pub struct RemovedComponentMessages {
440    event_sets: SparseSet<ComponentId, Messages<RemovedComponentEntity>>,
441}
442
443impl RemovedComponentMessages {
444    /// Creates an empty storage buffer for component removal messages.
445    pub fn new() -> Self {
446        Self::default()
447    }
448
449    /// For each type of component, swaps the event buffers and clears the oldest event buffer.
450    /// In general, this should be called once per frame/update.
451    pub fn update(&mut self) {
452        for (_component_id, messages) in self.event_sets.iter_mut() {
453            messages.update();
454        }
455    }
456
457    /// Returns an iterator over components and their entity messages.
458    pub fn iter(&self) -> impl Iterator<Item = (&ComponentId, &Messages<RemovedComponentEntity>)> {
459        self.event_sets.iter()
460    }
461
462    /// Gets the event storage for a given component.
463    pub fn get(
464        &self,
465        component_id: impl Into<ComponentId>,
466    ) -> Option<&Messages<RemovedComponentEntity>> {
467        self.event_sets.get(component_id.into())
468    }
469
470    /// Writes a removal message for the specified component.
471    pub fn write(&mut self, component_id: impl Into<ComponentId>, entity: Entity) {
472        self.event_sets
473            .get_or_insert_with(component_id.into(), Default::default)
474            .write(RemovedComponentEntity(entity));
475    }
476}
477
478/// A [`SystemParam`] that yields entities that had their `T` [`Component`]
479/// removed or have been despawned with it.
480///
481/// This acts effectively the same as a [`MessageReader`](crate::message::MessageReader).
482///
483/// Unlike hooks or observers (see the [lifecycle](crate) module docs),
484/// this does not allow you to see which data existed before removal.
485///
486/// If you are using `bevy_ecs` as a standalone crate,
487/// note that the [`RemovedComponents`] list will not be automatically cleared for you,
488/// and will need to be manually flushed using [`World::clear_trackers`](World::clear_trackers).
489///
490/// For users of `bevy` and `bevy_app`, [`World::clear_trackers`](World::clear_trackers) is
491/// automatically called by `bevy_app::App::update` and `bevy_app::SubApp::update`.
492/// For the main world, this is delayed until after all `SubApp`s have run.
493///
494/// # Examples
495///
496/// Basic usage:
497///
498/// ```
499/// # use bevy_ecs::component::Component;
500/// # use bevy_ecs::system::IntoSystem;
501/// # use bevy_ecs::lifecycle::RemovedComponents;
502/// #
503/// # #[derive(Component)]
504/// # struct MyComponent;
505/// fn react_on_removal(mut removed: RemovedComponents<MyComponent>) {
506///     removed.read().for_each(|removed_entity| println!("{}", removed_entity));
507/// }
508/// # bevy_ecs::system::assert_is_system(react_on_removal);
509/// ```
510#[derive(const _: () =
    {
        type __StructFieldsAlias<'w, 's, T> =
            (ComponentIdFor<'s, T>, Local<'s, RemovedComponentReader<T>>,
            &'w RemovedComponentMessages);
        #[doc(hidden)]
        pub struct FetchState<T: Component> {
            state: <__StructFieldsAlias<'static, 'static, T> as
            bevy_ecs::system::SystemParam>::State,
        }
        unsafe impl<T: Component> bevy_ecs::system::SystemParam for
            RemovedComponents<'_, '_, T> {
            type State = FetchState<T>;
            type Item<'w, 's> = RemovedComponents<'w, 's, T>;
            fn init_state(world: &mut bevy_ecs::world::World) -> Self::State {
                FetchState {
                    state: <__StructFieldsAlias<'_, '_, T> as
                            bevy_ecs::system::SystemParam>::init_state(world),
                }
            }
            fn init_access(state: &Self::State,
                system_meta: &mut bevy_ecs::system::SystemMeta,
                component_access_set: &mut bevy_ecs::query::FilteredAccessSet,
                world: &mut bevy_ecs::world::World) {
                <__StructFieldsAlias<'_, '_, T> as
                        bevy_ecs::system::SystemParam>::init_access(&state.state,
                    system_meta, component_access_set, world);
            }
            fn apply(state: &mut Self::State,
                system_meta: &bevy_ecs::system::SystemMeta,
                world: &mut bevy_ecs::world::World) {
                <__StructFieldsAlias<'_, '_, T> as
                        bevy_ecs::system::SystemParam>::apply(&mut state.state,
                    system_meta, world);
            }
            fn queue(state: &mut Self::State,
                system_meta: &bevy_ecs::system::SystemMeta,
                world: bevy_ecs::world::DeferredWorld) {
                <__StructFieldsAlias<'_, '_, T> as
                        bevy_ecs::system::SystemParam>::queue(&mut state.state,
                    system_meta, world);
            }
            #[inline]
            unsafe fn get_param<'w,
                's>(state: &'s mut Self::State,
                system_meta: &bevy_ecs::system::SystemMeta,
                world:
                    bevy_ecs::world::unsafe_world_cell::UnsafeWorldCell<'w>,
                change_tick: bevy_ecs::change_detection::Tick)
                ->
                    ::core::result::Result<Self::Item<'w, 's>,
                    bevy_ecs::system::SystemParamValidationError> {
                let (fieldcomponent_id, fieldreader, fieldmessage_sets) =
                    &mut state.state;
                let fieldcomponent_id =
                    unsafe {
                                <ComponentIdFor<'s, T> as
                                        bevy_ecs::system::SystemParam>::get_param(fieldcomponent_id,
                                    system_meta, world, change_tick)
                            }.map_err(|err|
                                bevy_ecs::system::SystemParamValidationError::new::<Self>(err.skipped,
                                    err.message, "::component_id"))?;
                let fieldreader =
                    unsafe {
                                <Local<'s, RemovedComponentReader<T>> as
                                        bevy_ecs::system::SystemParam>::get_param(fieldreader,
                                    system_meta, world, change_tick)
                            }.map_err(|err|
                                bevy_ecs::system::SystemParamValidationError::new::<Self>(err.skipped,
                                    err.message, "::reader"))?;
                let fieldmessage_sets =
                    unsafe {
                                <&'w RemovedComponentMessages as
                                        bevy_ecs::system::SystemParam>::get_param(fieldmessage_sets,
                                    system_meta, world, change_tick)
                            }.map_err(|err|
                                bevy_ecs::system::SystemParamValidationError::new::<Self>(err.skipped,
                                    err.message, "::message_sets"))?;
                ::core::result::Result::Ok(RemovedComponents {
                        component_id: fieldcomponent_id,
                        reader: fieldreader,
                        message_sets: fieldmessage_sets,
                    })
            }
        }
        unsafe impl<'w, 's, T: Component>
            bevy_ecs::system::ReadOnlySystemParam for
            RemovedComponents<'w, 's, T> where
            ComponentIdFor<'s, T>: bevy_ecs::system::ReadOnlySystemParam,
            Local<'s,
            RemovedComponentReader<T>>: bevy_ecs::system::ReadOnlySystemParam,
            &'w RemovedComponentMessages: bevy_ecs::system::ReadOnlySystemParam
            {}
    };SystemParam)]
511pub struct RemovedComponents<'w, 's, T: Component> {
512    component_id: ComponentIdFor<'s, T>,
513    reader: Local<'s, RemovedComponentReader<T>>,
514    message_sets: &'w RemovedComponentMessages,
515}
516
517/// Iterator over entities that had a specific component removed.
518///
519/// See [`RemovedComponents`].
520pub type RemovedIter<'a> = iter::Map<
521    iter::Flatten<option::IntoIter<iter::Cloned<MessageIterator<'a, RemovedComponentEntity>>>>,
522    fn(RemovedComponentEntity) -> Entity,
523>;
524
525/// Iterator over entities that had a specific component removed.
526///
527/// See [`RemovedComponents`].
528pub type RemovedIterWithId<'a> = iter::Map<
529    iter::Flatten<option::IntoIter<MessageIteratorWithId<'a, RemovedComponentEntity>>>,
530    fn(
531        (&RemovedComponentEntity, MessageId<RemovedComponentEntity>),
532    ) -> (Entity, MessageId<RemovedComponentEntity>),
533>;
534
535fn map_id_messages(
536    (entity, id): (&RemovedComponentEntity, MessageId<RemovedComponentEntity>),
537) -> (Entity, MessageId<RemovedComponentEntity>) {
538    (entity.clone().into(), id)
539}
540
541// For all practical purposes, the api surface of `RemovedComponents<T>`
542// should be similar to `MessageReader<T>` to reduce confusion.
543impl<'w, 's, T: Component> RemovedComponents<'w, 's, T> {
544    /// Fetch underlying [`MessageCursor`].
545    pub fn reader(&self) -> &MessageCursor<RemovedComponentEntity> {
546        &self.reader
547    }
548
549    /// Fetch underlying [`MessageCursor`] mutably.
550    pub fn reader_mut(&mut self) -> &mut MessageCursor<RemovedComponentEntity> {
551        &mut self.reader
552    }
553
554    /// Fetch underlying [`Messages`].
555    pub fn messages(&self) -> Option<&Messages<RemovedComponentEntity>> {
556        self.message_sets.get(self.component_id.get())
557    }
558
559    /// Destructures to get a mutable reference to the `MessageCursor`
560    /// and a reference to `Messages`.
561    ///
562    /// This is necessary since Rust can't detect destructuring through methods and most
563    /// usecases of the reader uses the `Messages` as well.
564    pub fn reader_mut_with_messages(
565        &mut self,
566    ) -> Option<(
567        &mut RemovedComponentReader<T>,
568        &Messages<RemovedComponentEntity>,
569    )> {
570        self.message_sets
571            .get(self.component_id.get())
572            .map(|messages| (&mut *self.reader, messages))
573    }
574
575    /// Iterates over the messages this [`RemovedComponents`] has not seen yet. This updates the
576    /// [`RemovedComponents`]'s message counter, which means subsequent message reads will not include messages
577    /// that happened before now.
578    pub fn read(&mut self) -> RemovedIter<'_> {
579        self.reader_mut_with_messages()
580            .map(|(reader, messages)| reader.read(messages).cloned())
581            .into_iter()
582            .flatten()
583            .map(RemovedComponentEntity::into)
584    }
585
586    /// Like [`read`](Self::read), except also returning the [`MessageId`] of the messages.
587    pub fn read_with_id(&mut self) -> RemovedIterWithId<'_> {
588        self.reader_mut_with_messages()
589            .map(|(reader, messages)| reader.read_with_id(messages))
590            .into_iter()
591            .flatten()
592            .map(map_id_messages)
593    }
594
595    /// Determines the number of removal messages available to be read from this [`RemovedComponents`] without consuming any.
596    pub fn len(&self) -> usize {
597        self.messages()
598            .map(|messages| self.reader.len(messages))
599            .unwrap_or(0)
600    }
601
602    /// Returns `true` if there are no messages available to read.
603    pub fn is_empty(&self) -> bool {
604        self.messages()
605            .is_none_or(|messages| self.reader.is_empty(messages))
606    }
607
608    /// Consumes all available messages.
609    ///
610    /// This means these messages will not appear in calls to [`RemovedComponents::read()`] or
611    /// [`RemovedComponents::read_with_id()`] and [`RemovedComponents::is_empty()`] will return `true`.
612    pub fn clear(&mut self) {
613        if let Some((reader, messages)) = self.reader_mut_with_messages() {
614            reader.clear(messages);
615        }
616    }
617}
618
619// SAFETY: Only reads World removed component messages
620unsafe impl<'a> ReadOnlySystemParam for &'a RemovedComponentMessages {}
621
622// SAFETY: no component value access.
623unsafe impl<'a> SystemParam for &'a RemovedComponentMessages {
624    type State = ();
625    type Item<'w, 's> = &'w RemovedComponentMessages;
626
627    fn init_state(_world: &mut World) -> Self::State {}
628
629    fn init_access(
630        _state: &Self::State,
631        _system_meta: &mut SystemMeta,
632        _component_access_set: &mut FilteredAccessSet,
633        _world: &mut World,
634    ) {
635    }
636
637    #[inline]
638    unsafe fn get_param<'w, 's>(
639        _state: &'s mut Self::State,
640        _system_meta: &SystemMeta,
641        world: UnsafeWorldCell<'w>,
642        _change_tick: Tick,
643    ) -> Result<Self::Item<'w, 's>, SystemParamValidationError> {
644        Ok(world.removed_components())
645    }
646}