1//! Information about observers that is stored on the entities themselves.
2//!
3//! This allows for easier cleanup, better inspection, and more flexible querying.
4//!
5//! Each observer is associated with an entity, defined by the [`Observer`] component.
6//! The [`Observer`] component contains the system that will be run when the observer is triggered,
7//! and the [`ObserverDescriptor`] which contains information about what the observer is observing.
8//!
9//! When we watch entities, we add the [`ObservedBy`] component to those entities,
10//! which links back to the observer entity.
1112use core::any::Any;
1314use core::marker::PhantomData;
1516use crate::{
17 component::{ComponentCloneBehavior, ComponentId, Mutable, StorageType},
18 error::{ErrorContext, ErrorHandler},
19 event::{EventKey, EventPattern},
20 lifecycle::{ComponentHook, HookContext},
21 observer::{
22 condition::{ObserverCondition, ObserverWithCondition, ObserverWithConditionMarker},
23observer_system_runner, ObserverRunner,
24 },
25prelude::*,
26 system::{IntoObserverSystem, ObserverSystem},
27world::DeferredWorld,
28};
29use alloc::boxed::Box;
30use alloc::vec::Vec;
31use bevy_utils::prelude::DebugName;
3233#[cfg(feature = "bevy_reflect")]
34use crate::prelude::ReflectComponent;
3536/// An [`Observer`] system. Add this [`Component`] to an [`Entity`] to turn it into an "observer".
37///
38/// Observers watch for a "trigger" of a specific [`Event`]. An event can be triggered on the [`World`]
39/// by calling [`World::trigger`]. It can also be queued up as a [`Command`] using [`Commands::trigger`].
40///
41/// When a [`World`] triggers an [`Event`], it will immediately run every [`Observer`] that watches for that [`Event`].
42///
43/// # Usage
44///
45/// The simplest usage of the observer pattern looks like this:
46///
47/// ```
48/// # use bevy_ecs::prelude::*;
49/// # let mut world = World::default();
50/// #[derive(Event)]
51/// struct Speak {
52/// message: String,
53/// }
54///
55/// world.add_observer(|event: On<Speak>| {
56/// println!("{}", event.message);
57/// });
58///
59/// world.trigger(Speak {
60/// message: "Hello!".into(),
61/// });
62/// ```
63///
64/// Notice that we used [`World::add_observer`]. This is just a shorthand for spawning an [`Entity`] with an [`Observer`] manually:
65///
66/// ```
67/// # use bevy_ecs::prelude::*;
68/// # let mut world = World::default();
69/// # #[derive(Event)]
70/// # struct Speak;
71/// // These are functionally the same:
72/// world.add_observer(|event: On<Speak>| {});
73/// world.spawn(Observer::new(|event: On<Speak>| {}));
74/// ```
75///
76/// Observers are a specialized [`System`] called an [`ObserverSystem`]. The first parameter must be [`On`], which provides access
77/// to the [`Event`], the [`Trigger`], and some additional execution context.
78///
79/// Because they are systems, they can access arbitrary [`World`] data by adding [`SystemParam`]s:
80///
81/// ```
82/// # use bevy_ecs::prelude::*;
83/// # let mut world = World::default();
84/// # #[derive(Event)]
85/// # struct PrintNames;
86/// # #[derive(Component, Debug)]
87/// # struct Name;
88/// world.add_observer(|event: On<PrintNames>, names: Query<&Name>| {
89/// for name in &names {
90/// println!("{name:?}");
91/// }
92/// });
93/// ```
94///
95/// You can also add [`Commands`], which means you can spawn new entities, insert new components, etc:
96///
97/// ```
98/// # use bevy_ecs::prelude::*;
99/// # let mut world = World::default();
100/// # #[derive(Event)]
101/// # struct SpawnThing;
102/// # #[derive(Component, Debug)]
103/// # struct Thing;
104/// world.add_observer(|event: On<SpawnThing>, mut commands: Commands| {
105/// commands.spawn(Thing);
106/// });
107/// ```
108///
109/// Observers can also trigger new events:
110///
111/// ```
112/// # use bevy_ecs::prelude::*;
113/// # let mut world = World::default();
114/// # #[derive(Event)]
115/// # struct A;
116/// # #[derive(Event)]
117/// # struct B;
118/// world.add_observer(|event: On<A>, mut commands: Commands| {
119/// commands.trigger(B);
120/// });
121/// ```
122///
123/// When the commands are flushed (including these "nested triggers") they will be
124/// recursively evaluated until there are no commands left, meaning nested triggers all
125/// evaluate at the same time!
126///
127/// ## Event [`Trigger`] behavior
128///
129/// Each [`Event`] defines a [`Trigger`] behavior, which determines _which_ observers will run for the given [`Event`] and _how_ they will be run.
130///
131/// [`Event`] by default (when derived) uses [`GlobalTrigger`](crate::event::GlobalTrigger). When it is triggered any [`Observer`] watching for it will be run.
132///
133/// ## Event sub-types
134///
135/// There are some built-in specialized [`Event`] types with custom [`Trigger`] logic:
136///
137/// - [`EntityEvent`] / [`EntityTrigger`](crate::event::EntityTrigger): An [`Event`] that targets a _specific_ entity. This also has opt-in support for
138/// "event bubbling" behavior. See [`EntityEvent`] for details.
139/// - [`EntityComponentsTrigger`](crate::event::EntityComponentsTrigger): An [`Event`] that targets an entity _and_ one or more components on that entity.
140/// This is used for [component lifecycle events](crate::lifecycle).
141///
142/// You can also define your own!
143///
144/// ## Observer execution timing
145///
146/// Observers triggered via [`World::trigger`] are evaluated immediately, as are all commands they queue up.
147///
148/// Observers triggered via [`Commands::trigger`] are evaluated at the next sync point in the ECS schedule, just like any other [`Command`].
149///
150/// To control the relative ordering of observer trigger commands sent from different systems,
151/// order the systems in the schedule relative to each other.
152///
153/// Currently, Bevy does not provide [a way to specify the relative ordering of observers](https://github.com/bevyengine/bevy/issues/14890)
154/// watching for the same event. Their ordering is considered to be arbitrary. It is recommended to make no
155/// assumptions about their execution order.
156///
157/// Commands sent by observers are [currently not immediately applied](https://github.com/bevyengine/bevy/issues/19569).
158/// Instead, all queued observers will run, and then all of the commands from those observers will be applied.
159///
160/// ## [`ObservedBy`]
161///
162/// When entities are observed, they will receive an [`ObservedBy`] component,
163/// which will be updated to track the observers that are currently observing them.
164///
165/// ## Manual [`Observer`] target configuration
166///
167/// You can manually control the targets that an observer is watching by calling builder methods like [`Observer::with_entity`]
168/// _before_ inserting the [`Observer`] component.
169///
170/// In general, it is better to use the [`EntityWorldMut::observe`] or [`EntityCommands::observe`] methods,
171/// which spawns a new observer, and configures it to watch the entity it is called on.
172///
173/// ## Cleaning up observers
174///
175/// If an [`EntityEvent`] [`Observer`] targets specific entities, and all of those entities are despawned, the [`Observer`] entity will also be despawned.
176/// This protects against observer "garbage" building up over time.
177///
178/// ## Component lifecycle events: Observers vs Hooks
179///
180/// It is important to note that observers, just like [hooks](crate::lifecycle::ComponentHooks),
181/// can watch for and respond to [lifecycle](crate::lifecycle) events.
182/// Unlike hooks, observers are not treated as an "innate" part of component behavior:
183/// they can be added or removed at runtime, and multiple observers
184/// can be registered for the same lifecycle event for the same component.
185///
186/// The ordering of hooks versus observers differs based on the lifecycle event in question:
187///
188/// - when adding components, hooks are evaluated first, then observers
189/// - when removing components, observers are evaluated first, then hooks
190///
191/// This allows hooks to act as constructors and destructors for components,
192/// as they always have the first and final say in the component's lifecycle.
193///
194/// ## Observer re-targeting
195///
196/// Currently, [observers cannot be retargeted after spawning](https://github.com/bevyengine/bevy/issues/19587):
197/// despawn and respawn an observer as a workaround.
198///
199/// ## Internal observer cache
200///
201/// For more efficient observer triggering, Observers make use of the internal [`CachedObservers`](crate::observer::CachedObservers) storage.
202/// In general, this is an implementation detail developers don't need to worry about, but it can be used when implementing custom [`Trigger`](crate::event::Trigger)
203/// types, or to add "dynamic" observers for cases like scripting / modding.
204///
205/// [`SystemParam`]: crate::system::SystemParam
206/// [`Trigger`]: crate::event::Trigger
207pub struct Observer {
208 hook_on_add: ComponentHook,
209pub(crate) error_handler: Option<ErrorHandler>,
210pub(crate) system: Option<Box<dyn AnyNamedSystem>>,
211pub(crate) descriptor: ObserverDescriptor,
212pub(crate) last_trigger_id: u32,
213pub(crate) despawned_watched_entities: u32,
214pub(crate) runner: ObserverRunner,
215pub(crate) conditions: Vec<ObserverCondition>,
216}
217218impl Observer {
219/// Creates a new [`Observer`], which defaults to a "global" observer. This means it will run _whenever_ an event of type `E` is triggered.
220 ///
221 /// # Panics
222 ///
223 /// Panics if the given system is an exclusive system.
224pub fn new<E: EventPattern, M, I: IntoObserverSystem<E, M>>(system: I) -> Self {
225let system = Box::new(IntoObserverSystem::into_system(system));
226Self {
227 system: Some(system),
228 descriptor: Default::default(),
229 hook_on_add: hook_on_add::<E, I::System>,
230 error_handler: None,
231 runner: observer_system_runner::<E, I::System>,
232 despawned_watched_entities: 0,
233 last_trigger_id: 0,
234 conditions: Vec::new(),
235 }
236 }
237238/// Creates a new [`Observer`] with custom runner, this is mostly used for dynamic event observers
239pub fn with_dynamic_runner(runner: ObserverRunner) -> Self {
240Self {
241 system: Some(Box::new(IntoSystem::into_system(|| {}))),
242 descriptor: Default::default(),
243 hook_on_add: |mut world, hook_context| {
244let default_error_handler = world.fallback_error_handler();
245world.commands().queue(move |world: &mut World| {
246let entity = hook_context.entity;
247let mut conditions = {
248let Some(mut observe) = world.get_mut::<Observer>(entity) else {
249return;
250 };
251if observe.descriptor.event_keys.is_empty() {
252return;
253 }
254if observe.error_handler.is_none() {
255observe.error_handler = Some(default_error_handler);
256 }
257 core::mem::take(&mut observe.conditions)
258 };
259for condition in &mut conditions {
260 condition.initialize(world);
261 }
262if let Some(mut observe) = world.get_mut::<Observer>(entity) {
263observe.conditions = conditions;
264 }
265world.register_observer(entity);
266 });
267 },
268 error_handler: None,
269runner,
270 despawned_watched_entities: 0,
271 last_trigger_id: 0,
272 conditions: Vec::new(),
273 }
274 }
275276/// Observes the given `entity` (in addition to any entity already being observed).
277 /// This will cause the [`Observer`] to run whenever an [`EntityEvent::event_target`] is the given `entity`.
278 /// Note that if this is called _after_ an [`Observer`] is spawned, it will produce no effects.
279pub fn with_entity(mut self, entity: Entity) -> Self {
280self.watch_entity(entity);
281self282 }
283284/// Observes the given `entities` (in addition to any entity already being observed).
285 /// This will cause the [`Observer`] to run whenever an [`EntityEvent::event_target`] is any of the `entities`.
286 /// Note that if this is called _after_ an [`Observer`] is spawned, it will produce no effects.
287pub fn with_entities<I: IntoIterator<Item = Entity>>(mut self, entities: I) -> Self {
288self.watch_entities(entities);
289self290 }
291292/// Observes the given `entity` (in addition to any entity already being observed).
293 /// This will cause the [`Observer`] to run whenever an [`EntityEvent::event_target`] is the given `entity`.
294 /// Note that if this is called _after_ an [`Observer`] is spawned, it will produce no effects.
295pub fn watch_entity(&mut self, entity: Entity) {
296self.descriptor.entities.push(entity);
297 }
298299/// Observes the given `entity` (in addition to any entity already being observed).
300 /// This will cause the [`Observer`] to run whenever an [`EntityEvent::event_target`] is any of the `entities`.
301 /// Note that if this is called _after_ an [`Observer`] is spawned, it will produce no effects.
302pub fn watch_entities<I: IntoIterator<Item = Entity>>(&mut self, entities: I) {
303self.descriptor.entities.extend(entities);
304 }
305306/// Observes the given `component`. This will cause the [`Observer`] to run whenever the [`Event`] has
307 /// an [`EntityComponentsTrigger`](crate::event::EntityComponentsTrigger) that targets the given `component`.
308pub fn with_component(mut self, component: ComponentId) -> Self {
309self.descriptor.components.push(component);
310self311 }
312313/// Observes the given `components`. This will cause the [`Observer`] to run whenever the [`Event`] has
314 /// an [`EntityComponentsTrigger`](crate::event::EntityComponentsTrigger) that targets any of the `components`.
315pub fn with_components<I: IntoIterator<Item = ComponentId>>(mut self, components: I) -> Self {
316self.descriptor.components.extend(components);
317self318 }
319320/// Observes the given `event_key`. This will cause the [`Observer`] to run whenever an event with the given [`EventKey`]
321 /// is triggered.
322 /// # Safety
323 /// The type of the `event_key` [`EventKey`] _must_ match the actual value
324 /// of the event passed into the observer system.
325pub unsafe fn with_event_key(mut self, event_key: EventKey) -> Self {
326self.descriptor.event_keys.push(event_key);
327self328 }
329330/// Sets the error handler to use for this observer.
331 ///
332 /// See the [`error` module-level documentation](crate::error) for more information.
333pub fn with_error_handler(mut self, error_handler: fn(BevyError, ErrorContext)) -> Self {
334self.error_handler = Some(error_handler);
335self336 }
337338/// Adds a run condition to this observer.
339 ///
340 /// The observer will only run if all conditions return `true` (AND semantics).
341 /// Multiple conditions can be added by chaining `run_if` calls.
342pub fn run_if<M>(mut self, condition: impl SystemCondition<M>) -> Self {
343self.conditions.push(ObserverCondition::new(condition));
344self345 }
346347/// Returns the [`ObserverDescriptor`] for this [`Observer`].
348pub fn descriptor(&self) -> &ObserverDescriptor {
349&self.descriptor
350 }
351352/// Returns the name of the [`Observer`]'s system .
353pub fn system_name(&self) -> DebugName {
354self.system.as_deref().map_or(
355DebugName::borrowed("<system is initializing>"),
356 AnyNamedSystem::system_name,
357 )
358 }
359}
360361impl Componentfor Observer {
362const STORAGE_TYPE: StorageType = StorageType::SparseSet;
363type Mutability = Mutable;
364fn on_add() -> Option<ComponentHook> {
365Some(|world, context| {
366let Some(observe) = world.get::<Self>(context.entity) else {
367return;
368 };
369let hook = observe.hook_on_add;
370hook(world, context);
371 })
372 }
373fn on_remove() -> Option<ComponentHook> {
374Some(|mut world, HookContext { entity, .. }| {
375let descriptor = core::mem::take(
376&mut world377 .entity_mut(entity)
378 .get_mut::<Self>()
379 .unwrap()
380 .as_mut()
381 .descriptor,
382 );
383world.commands().queue(move |world: &mut World| {
384world.unregister_observer(entity, descriptor);
385 });
386 })
387 }
388}
389390/// Store information about what an [`Observer`] observes.
391///
392/// This information is stored inside of the [`Observer`] component,
393#[derive(#[automatically_derived]impl ::core::default::Default for ObserverDescriptor {
#[inline]
fn default() -> Self {
ObserverDescriptor {
event_keys: ::core::default::Default::default(),
components: ::core::default::Default::default(),
entities: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]impl ::core::clone::Clone for ObserverDescriptor {
#[inline]
fn clone(&self) -> Self {
ObserverDescriptor {
event_keys: ::core::clone::Clone::clone(&self.event_keys),
components: ::core::clone::Clone::clone(&self.components),
entities: ::core::clone::Clone::clone(&self.entities),
}
}
}Clone)]
394pub struct ObserverDescriptor {
395/// The event keys the observer is watching.
396pub(super) event_keys: Vec<EventKey>,
397398/// The components the observer is watching.
399pub(super) components: Vec<ComponentId>,
400401/// The entities the observer is watching.
402pub(super) entities: Vec<Entity>,
403}
404405impl ObserverDescriptor {
406/// Add the given `event_keys` to the descriptor.
407 /// # Safety
408 /// The type of each [`EventKey`] in `event_keys` _must_ match the actual value
409 /// of the event passed into the observer.
410pub unsafe fn with_event_keys(mut self, event_keys: Vec<EventKey>) -> Self {
411self.event_keys = event_keys;
412self413 }
414415/// Add the given `components` to the descriptor.
416pub fn with_components(mut self, components: Vec<ComponentId>) -> Self {
417self.components = components;
418self419 }
420421/// Add the given `entities` to the descriptor.
422pub fn with_entities(mut self, entities: Vec<Entity>) -> Self {
423self.entities = entities;
424self425 }
426427/// Returns the `event_keys` that the observer is watching.
428pub fn event_keys(&self) -> &[EventKey] {
429&self.event_keys
430 }
431432/// Returns the `components` that the observer is watching.
433pub fn components(&self) -> &[ComponentId] {
434&self.components
435 }
436437/// Returns the `entities` that the observer is watching.
438pub fn entities(&self) -> &[Entity] {
439&self.entities
440 }
441}
442443/// A [`ComponentHook`] used by [`Observer`] to handle its [`on-add`](`crate::lifecycle::ComponentHooks::on_add`).
444///
445/// This function exists separate from [`Observer`] to allow [`Observer`] to have its type parameters
446/// erased.
447///
448/// The type parameters of this function _must_ match those used to create the [`Observer`].
449/// As such, it is recommended to only use this function within the [`Observer::new`] method to
450/// ensure type parameters match.
451fn hook_on_add<E: EventPattern, S: ObserverSystem<E>>(
452mut world: DeferredWorld<'_>,
453HookContext { entity, .. }: HookContext,
454) {
455world.commands().queue(move |world: &mut World| {
456let event_key = world.register_event_key::<E::Event>();
457let components = E::Components::component_ids(&mut world.components_registrator());
458459let Some(mut observer) = world.get_mut::<Observer>(entity) else {
460return;
461 };
462observer.descriptor.event_keys.push(event_key);
463observer.descriptor.components.extend(components);
464465let mut boxed_system = core::mem::take(&mut observer.system).unwrap();
466let mut conditions = core::mem::take(&mut observer.conditions);
467468let system: &mut dyn Any = boxed_system.as_mut();
469let system = system.downcast_mut::<S>().unwrap();
470let access = system.initialize(world);
471if !!access.is_exclusive() {
{
::core::panicking::panic_fmt(format_args!("Exclusive system `{0}` may not be used as observer.\nInstead of `&mut World`, use either `DeferredWorld` if you do not need structural changes, or `Commands` if you do.",
system.name()));
}
};assert!(
472 !access.is_exclusive(),
473concat!(
474"Exclusive system `{}` may not be used as observer.\n",
475"Instead of `&mut World`, use either `DeferredWorld` if you do not need structural changes, or `Commands` if you do."
476),
477 system.name(),
478 );
479480for condition in &mut conditions {
481 condition.initialize(world);
482 }
483484// If the observer was despawned during `initialize`, don't register it.
485let Some(mut observer) = world.get_mut::<Observer>(entity) else {
486return;
487 };
488489observer.system = Some(boxed_system);
490observer.conditions = conditions;
491492world.register_observer(entity);
493 });
494}
495496/// Tracks a list of entity observers for the [`Entity`] [`ObservedBy`] is added to.
497#[derive(#[automatically_derived]impl ::core::default::Default for ObservedBy {
#[inline]
fn default() -> Self { ObservedBy(::core::default::Default::default()) }
}Default, #[automatically_derived]impl ::core::fmt::Debug for ObservedBy {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_tuple_field1_finish(f, "ObservedBy",
&&self.0)
}
}Debug)]
498#[cfg_attr(feature = "bevy_reflect", derive(const _: () =
{
impl bevy_reflect::GetTypeRegistration for ObservedBy where {
fn get_type_registration() -> bevy_reflect::TypeRegistration {
let mut registration =
bevy_reflect::TypeRegistration::of::<Self>();
registration.insert(<bevy_reflect::ReflectFromPtr as
bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
registration.insert(<bevy_reflect::ReflectFromReflect as
bevy_reflect::CreateTypeData<Self>>::create_type_data(()));
registration.register_type_data_with::<ReflectComponent, Self,
_>(());
registration
}
#[inline(never)]
fn register_type_dependencies(registry:
&mut bevy_reflect::TypeRegistry) {
<Vec<Entity> as
bevy_reflect::__macro_exports::RegisterForReflection>::__register(registry);
}
}
impl bevy_reflect::Typed for ObservedBy where {
#[inline(never)]
fn type_info() -> &'static bevy_reflect::TypeInfo {
static CELL: bevy_reflect::utility::NonGenericTypeInfoCell =
bevy_reflect::utility::NonGenericTypeInfoCell::new();
CELL.get_or_set(#[inline(never)] ||
{
bevy_reflect::TypeInfo::TupleStruct(bevy_reflect::tuple_struct::TupleStructInfo::new::<Self>(&[bevy_reflect::UnnamedField::new::<Vec<Entity>>(0usize)]))
})
}
}
#[allow(deprecated, reason =
"derives on a deprecated type shouldn't be considered a usage")]
impl bevy_reflect::TypePath for ObservedBy where {
fn type_path() -> &'static str {
"bevy_ecs::observer::distributed_storage::ObservedBy"
}
fn short_type_path() -> &'static str { "ObservedBy" }
fn type_ident() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("ObservedBy")
}
fn crate_name() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_ecs::observer::distributed_storage".split(':').next().unwrap())
}
fn module_path() -> ::core::option::Option<&'static str> {
::core::option::Option::Some("bevy_ecs::observer::distributed_storage")
}
}
impl bevy_reflect::Reflect for ObservedBy 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 ObservedBy where {
fn ownership() -> bevy_reflect::func::args::Ownership {
bevy_reflect::func::args::Ownership::Owned
}
}
impl bevy_reflect::func::args::FromArg for ObservedBy where {
type This<'from_arg> = ObservedBy;
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 ObservedBy 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 ObservedBy 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)
->
::core::result::Result<bevy_reflect::tuple_struct::DynamicTupleStruct,
bevy_reflect::ReflectCloneError> {
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)?);
::core::result::Result::Ok(dynamic)
}
}
impl bevy_reflect::PartialReflect for ObservedBy 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]
#[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 {
0: <Vec<Entity> as
bevy_reflect::PartialReflect>::reflect_clone_and_take(&self.0)?,
}))
}
}
impl bevy_reflect::FromReflect for ObservedBy 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: <Vec<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 }
}
}
};bevy_reflect::Reflect))]
499#[cfg_attr(feature = "bevy_reflect", reflect(Component, Debug))]
500pub struct ObservedBy(pub(crate) Vec<Entity>);
501502impl ObservedBy {
503/// Provides a read-only reference to the list of entities observing this entity.
504pub fn get(&self) -> &[Entity] {
505&self.0
506}
507}
508509impl Componentfor ObservedBy {
510const STORAGE_TYPE: StorageType = StorageType::SparseSet;
511type Mutability = Mutable;
512513fn on_remove() -> Option<ComponentHook> {
514Some(|mut world, HookContext { entity, .. }| {
515let observed_by = {
516let mut component = world.get_mut::<ObservedBy>(entity).unwrap();
517 core::mem::take(&mut component.0)
518 };
519for e in observed_by {
520let (total_entities, despawned_watched_entities) = {
521let Ok(mut entity_mut) = world.get_entity_mut(e) else {
522continue;
523 };
524let Some(mut state) = entity_mut.get_mut::<Observer>() else {
525continue;
526 };
527 state.despawned_watched_entities += 1;
528 (
529 state.descriptor.entities.len(),
530 state.despawned_watched_entities as usize,
531 )
532 };
533534// Despawn Observer if it has no more active sources.
535if total_entities == despawned_watched_entities {
536 world.commands().entity(e).try_despawn();
537 }
538 }
539 })
540 }
541542fn clone_behavior() -> ComponentCloneBehavior {
543 ComponentCloneBehavior::Ignore544 }
545}
546547pub(crate) trait AnyNamedSystem: Any + Send + Sync + 'static {
548fn system_name(&self) -> DebugName;
549}
550551impl<T: Any + System> AnyNamedSystemfor T {
552fn system_name(&self) -> DebugName {
553self.name()
554 }
555}
556557/// Trait for types that can be converted into an [`Observer`].
558pub trait IntoObserver<Marker>: Send + 'static {
559/// Converts this type into an [`Observer`].
560fn into_observer(self) -> Observer;
561}
562563impl IntoObserver<()> for Observer {
564fn into_observer(self) -> Observer {
565self566 }
567}
568569impl<E: EventPattern, M, T: IntoObserverSystem<E, M>> IntoObserver<(E, M)> for T {
570fn into_observer(self) -> Observer {
571Observer::new(self)
572 }
573}
574575impl<E: EventPattern, M: 'static, S: IntoObserverSystem<E, M>>
576IntoObserver<ObserverWithConditionMarker> for ObserverWithCondition<E, M, S>
577{
578fn into_observer(self) -> Observer {
579let (system, conditions) = self.take_conditions();
580let mut observer = Observer::new(system);
581observer.conditions = conditions;
582observer583 }
584}
585586/// Trait for types that can be converted into an entity-targeting [`Observer`].
587///
588/// This trait enforces that the event type implements [`EntityEvent`].
589#[diagnostic::on_unimplemented(
590 message = "`{Self}` cannot be used as an entity observer",
591 note = "entity observers require the event type to implement `EntityEvent`"
592)]
593pub trait IntoEntityObserver<Marker>: Send + 'static {
594/// Converts this type into an [`Observer`] that watches the given entity.
595fn into_observer_for_entity(self, entity: Entity) -> Observer;
596}
597598impl<E: EventPattern<Event: EntityEvent>, M, T: IntoObserverSystem<E, M>> IntoEntityObserver<(E, M)>
599for T
600{
601fn into_observer_for_entity(self, entity: Entity) -> Observer {
602Observer::new(self).with_entity(entity)
603 }
604}
605606impl<E: EventPattern<Event: EntityEvent>, M: 'static, S: IntoObserverSystem<E, M>>
607IntoEntityObserver<ObserverWithConditionMarker> for ObserverWithCondition<E, M, S>
608{
609fn into_observer_for_entity(self, entity: Entity) -> Observer {
610let (system, conditions) = self.take_conditions();
611let mut observer = Observer::new(system);
612observer.conditions = conditions;
613observer.with_entity(entity)
614 }
615}
616617/// Extension trait for adding run conditions to observer systems.
618pub trait ObserverSystemExt<E: EventPattern, M>: IntoObserverSystem<E, M> + Sized {
619/// Adds a run condition to this observer system.
620 ///
621 /// The observer will only run if the condition returns `true`.
622 /// Multiple conditions can be chained (AND semantics).
623fn run_if<C, CM>(self, condition: C) -> ObserverWithCondition<E, M, Self>
624where
625C: SystemCondition<CM>,
626 {
627ObserverWithCondition {
628 system: self,
629 conditions: ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
[Box::new(IntoSystem::into_system(condition))]))alloc::vec![Box::new(IntoSystem::into_system(condition))],
630 _marker: PhantomData,
631 }
632 }
633}
634635impl<E: EventPattern, M, T: IntoObserverSystem<E, M>> ObserverSystemExt<E, M> for T {}