use crate::change_detection::MaybeLocation;1use crate::component::ComponentId;2use crate::world::World;3use crate::{component::Component, traversal::Traversal};4#[cfg(feature = "bevy_reflect")]5use bevy_reflect::Reflect;6use core::{7cmp::Ordering,8fmt,9hash::{Hash, Hasher},10marker::PhantomData,11};1213/// Something that "happens" and can be processed by app logic.14///15/// Events can be triggered on a [`World`] using a method like [`trigger`](World::trigger),16/// causing any global [`Observer`] watching that event to run. This allows for push-based17/// event handling where observers are immediately notified of events as they happen.18///19/// Additional event handling behavior can be enabled by implementing the [`EntityEvent`]20/// and [`BufferedEvent`] traits:21///22/// - [`EntityEvent`]s support targeting specific entities, triggering any observers watching those targets.23/// They are useful for entity-specific event handlers and can even be propagated from one entity to another.24/// - [`BufferedEvent`]s support a pull-based event handling system where events are written using an [`EventWriter`]25/// and read later using an [`EventReader`]. This is an alternative to observers that allows efficient batch processing26/// of events at fixed points in a schedule.27///28/// Events must be thread-safe.29///30/// # Usage31///32/// The [`Event`] trait can be derived:33///34/// ```35/// # use bevy_ecs::prelude::*;36/// #37/// #[derive(Event)]38/// struct Speak {39/// message: String,40/// }41/// ```42///43/// An [`Observer`] can then be added to listen for this event type:44///45/// ```46/// # use bevy_ecs::prelude::*;47/// #48/// # #[derive(Event)]49/// # struct Speak {50/// # message: String,51/// # }52/// #53/// # let mut world = World::new();54/// #55/// world.add_observer(|event: On<Speak>| {56/// println!("{}", event.message);57/// });58/// ```59///60/// The event can be triggered on the [`World`] using the [`trigger`](World::trigger) method:61///62/// ```63/// # use bevy_ecs::prelude::*;64/// #65/// # #[derive(Event)]66/// # struct Speak {67/// # message: String,68/// # }69/// #70/// # let mut world = World::new();71/// #72/// # world.add_observer(|event: On<Speak>| {73/// # println!("{}", event.message);74/// # });75/// #76/// # world.flush();77/// #78/// world.trigger(Speak {79/// message: "Hello!".to_string(),80/// });81/// ```82///83/// For events that additionally need entity targeting or buffering, consider also deriving84/// [`EntityEvent`] or [`BufferedEvent`], respectively.85///86/// [`World`]: crate::world::World87/// [`Observer`]: crate::observer::Observer88/// [`EventReader`]: super::EventReader89/// [`EventWriter`]: super::EventWriter90#[diagnostic::on_unimplemented(91message = "`{Self}` is not an `Event`",92label = "invalid `Event`",93note = "consider annotating `{Self}` with `#[derive(Event)]`"94)]95pub trait Event: Send + Sync + 'static {96/// Generates the [`EventKey`] for this event type.97///98/// If this type has already been registered,99/// this will return the existing [`EventKey`].100///101/// This is used by various dynamically typed observer APIs,102/// such as [`World::trigger_targets_dynamic`].103///104/// # Warning105///106/// This method should not be overridden by implementers,107/// and should always correspond to the implementation of [`event_key`](Event::event_key).108fn register_event_key(world: &mut World) -> EventKey {109EventKey(world.register_component::<EventWrapperComponent<Self>>())110}111112/// Fetches the [`EventKey`] for this event type,113/// if it has already been generated.114///115/// This is used by various dynamically typed observer APIs,116/// such as [`World::trigger_targets_dynamic`].117///118/// # Warning119///120/// This method should not be overridden by implementers,121/// and should always correspond to the implementation of122/// [`register_event_key`](Event::register_event_key).123fn event_key(world: &World) -> Option<EventKey> {124world125.component_id::<EventWrapperComponent<Self>>()126.map(EventKey)127}128}129130/// An [`Event`] that can be targeted at specific entities.131///132/// Entity events can be triggered on a [`World`] with specific entity targets using a method133/// like [`trigger_targets`](World::trigger_targets), causing any [`Observer`] watching the event134/// for those entities to run.135///136/// Unlike basic [`Event`]s, entity events can optionally be propagated from one entity target to another137/// based on the [`EntityEvent::Traversal`] type associated with the event. This enables use cases138/// such as bubbling events to parent entities for UI purposes.139///140/// Entity events must be thread-safe.141///142/// # Usage143///144/// The [`EntityEvent`] trait can be derived. The `event` attribute can be used to further configure145/// the propagation behavior: adding `auto_propagate` sets [`EntityEvent::AUTO_PROPAGATE`] to `true`,146/// while adding `traversal = X` sets [`EntityEvent::Traversal`] to be of type `X`.147///148/// ```149/// # use bevy_ecs::prelude::*;150/// #151/// // When the `Damage` event is triggered on an entity, bubble the event up to ancestors.152/// #[derive(EntityEvent)]153/// #[entity_event(traversal = &'static ChildOf, auto_propagate)]154/// struct Damage {155/// amount: f32,156/// }157/// ```158///159/// An [`Observer`] can then be added to listen for this event type for the desired entity:160///161/// ```162/// # use bevy_ecs::prelude::*;163/// #164/// # #[derive(EntityEvent)]165/// # #[entity_event(traversal = &'static ChildOf, auto_propagate)]166/// # struct Damage {167/// # amount: f32,168/// # }169/// #170/// # #[derive(Component)]171/// # struct Health(f32);172/// #173/// # #[derive(Component)]174/// # struct Enemy;175/// #176/// # #[derive(Component)]177/// # struct ArmorPiece;178/// #179/// # let mut world = World::new();180/// #181/// // Spawn an enemy entity.182/// let enemy = world.spawn((Enemy, Health(100.0))).id();183///184/// // Spawn some armor as a child of the enemy entity.185/// // When the armor takes damage, it will bubble the event up to the enemy,186/// // which can then handle the event with its own observer.187/// let armor_piece = world188/// .spawn((ArmorPiece, Health(25.0), ChildOf(enemy)))189/// .observe(|event: On<Damage>, mut query: Query<&mut Health>| {190/// // Note: `On::entity` only exists because this is an `EntityEvent`.191/// let mut health = query.get_mut(event.entity()).unwrap();192/// health.0 -= event.amount;193/// })194/// .id();195/// ```196///197/// The event can be triggered on the [`World`] using the [`trigger_targets`](World::trigger_targets) method,198/// providing the desired entity target(s):199///200/// ```201/// # use bevy_ecs::prelude::*;202/// #203/// # #[derive(EntityEvent)]204/// # #[entity_event(traversal = &'static ChildOf, auto_propagate)]205/// # struct Damage {206/// # amount: f32,207/// # }208/// #209/// # #[derive(Component)]210/// # struct Health(f32);211/// #212/// # #[derive(Component)]213/// # struct Enemy;214/// #215/// # #[derive(Component)]216/// # struct ArmorPiece;217/// #218/// # let mut world = World::new();219/// #220/// # let enemy = world.spawn((Enemy, Health(100.0))).id();221/// # let armor_piece = world222/// # .spawn((ArmorPiece, Health(25.0), ChildOf(enemy)))223/// # .observe(|event: On<Damage>, mut query: Query<&mut Health>| {224/// # // Note: `On::entity` only exists because this is an `EntityEvent`.225/// # let mut health = query.get_mut(event.entity()).unwrap();226/// # health.0 -= event.amount;227/// # })228/// # .id();229/// #230/// # world.flush();231/// #232/// world.trigger_targets(Damage { amount: 10.0 }, armor_piece);233/// ```234///235/// [`World`]: crate::world::World236/// [`TriggerTargets`]: crate::observer::TriggerTargets237/// [`Observer`]: crate::observer::Observer238/// [`Events<E>`]: super::Events239/// [`EventReader`]: super::EventReader240/// [`EventWriter`]: super::EventWriter241#[diagnostic::on_unimplemented(242message = "`{Self}` is not an `EntityEvent`",243label = "invalid `EntityEvent`",244note = "consider annotating `{Self}` with `#[derive(EntityEvent)]`"245)]246pub trait EntityEvent: Event {247/// The component that describes which [`Entity`] to propagate this event to next, when [propagation] is enabled.248///249/// [`Entity`]: crate::entity::Entity250/// [propagation]: crate::observer::On::propagate251type Traversal: Traversal<Self>;252253/// When true, this event will always attempt to propagate when [triggered], without requiring a call254/// to [`On::propagate`].255///256/// [triggered]: crate::system::Commands::trigger_targets257/// [`On::propagate`]: crate::observer::On::propagate258const AUTO_PROPAGATE: bool = false;259}260261/// A buffered event for pull-based event handling.262///263/// Buffered events can be written with [`EventWriter`] and read using the [`EventReader`] system parameter.264/// These events are stored in the [`Events<E>`] resource, and require periodically polling the world for new events,265/// typically in a system that runs as part of a schedule.266///267/// While the polling imposes a small overhead, buffered events are useful for efficiently batch processing268/// a large number of events at once. This can make them more efficient than [`Event`]s used by [`Observer`]s269/// for events that happen at a high frequency or in large quantities.270///271/// Unlike [`Event`]s triggered for observers, buffered events are evaluated at fixed points in the schedule272/// rather than immediately when they are sent. This allows for more predictable scheduling and deferring273/// event processing to a later point in time.274///275/// Buffered events do *not* trigger observers automatically when they are written via an [`EventWriter`].276/// However, they can still also be triggered on a [`World`] in case you want both buffered and immediate277/// event handling for the same event.278///279/// Buffered events must be thread-safe.280///281/// # Usage282///283/// The [`BufferedEvent`] trait can be derived:284///285/// ```286/// # use bevy_ecs::prelude::*;287/// #288/// #[derive(BufferedEvent)]289/// struct Message(String);290/// ```291///292/// The event can then be written to the event buffer using an [`EventWriter`]:293///294/// ```295/// # use bevy_ecs::prelude::*;296/// #297/// # #[derive(BufferedEvent)]298/// # struct Message(String);299/// #300/// fn write_hello(mut writer: EventWriter<Message>) {301/// writer.write(Message("Hello!".to_string()));302/// }303/// ```304///305/// Buffered events can be efficiently read using an [`EventReader`]:306///307/// ```308/// # use bevy_ecs::prelude::*;309/// #310/// # #[derive(BufferedEvent)]311/// # struct Message(String);312/// #313/// fn read_messages(mut reader: EventReader<Message>) {314/// // Process all buffered events of type `Message`.315/// for Message(message) in reader.read() {316/// println!("{message}");317/// }318/// }319/// ```320///321/// [`World`]: crate::world::World322/// [`Observer`]: crate::observer::Observer323/// [`Events<E>`]: super::Events324/// [`EventReader`]: super::EventReader325/// [`EventWriter`]: super::EventWriter326#[diagnostic::on_unimplemented(327message = "`{Self}` is not an `BufferedEvent`",328label = "invalid `BufferedEvent`",329note = "consider annotating `{Self}` with `#[derive(BufferedEvent)]`"330)]331pub trait BufferedEvent: Send + Sync + 'static {}332333/// An internal type that implements [`Component`] for a given [`Event`] type.334///335/// This exists so we can easily get access to a unique [`ComponentId`] for each [`Event`] type,336/// without requiring that [`Event`] types implement [`Component`] directly.337/// [`ComponentId`] is used internally as a unique identifier for events because they are:338///339/// - Unique to each event type.340/// - Can be quickly generated and looked up.341/// - Are compatible with dynamic event types, which aren't backed by a Rust type.342///343/// This type is an implementation detail and should never be made public.344// TODO: refactor events to store their metadata on distinct entities, rather than using `ComponentId`345#[derive(Component)]346struct EventWrapperComponent<E: Event + ?Sized>(PhantomData<E>);347348/// An `EventId` uniquely identifies an event stored in a specific [`World`].349///350/// An `EventId` can among other things be used to trace the flow of an event from the point it was351/// sent to the point it was processed. `EventId`s increase monotonically by send order.352///353/// [`World`]: crate::world::World354#[cfg_attr(355feature = "bevy_reflect",356derive(Reflect),357reflect(Clone, Debug, PartialEq, Hash)358)]359pub struct EventId<E: BufferedEvent> {360/// Uniquely identifies the event associated with this ID.361// This value corresponds to the order in which each event was added to the world.362pub id: usize,363/// The source code location that triggered this event.364pub caller: MaybeLocation,365#[cfg_attr(feature = "bevy_reflect", reflect(ignore, clone))]366pub(super) _marker: PhantomData<E>,367}368369impl<E: BufferedEvent> Copy for EventId<E> {}370371impl<E: BufferedEvent> Clone for EventId<E> {372fn clone(&self) -> Self {373*self374}375}376377impl<E: BufferedEvent> fmt::Display for EventId<E> {378fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {379<Self as fmt::Debug>::fmt(self, f)380}381}382383impl<E: BufferedEvent> fmt::Debug for EventId<E> {384fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {385write!(386f,387"event<{}>#{}",388core::any::type_name::<E>().split("::").last().unwrap(),389self.id,390)391}392}393394impl<E: BufferedEvent> PartialEq for EventId<E> {395fn eq(&self, other: &Self) -> bool {396self.id == other.id397}398}399400impl<E: BufferedEvent> Eq for EventId<E> {}401402impl<E: BufferedEvent> PartialOrd for EventId<E> {403fn partial_cmp(&self, other: &Self) -> Option<Ordering> {404Some(self.cmp(other))405}406}407408impl<E: BufferedEvent> Ord for EventId<E> {409fn cmp(&self, other: &Self) -> Ordering {410self.id.cmp(&other.id)411}412}413414impl<E: BufferedEvent> Hash for EventId<E> {415fn hash<H: Hasher>(&self, state: &mut H) {416Hash::hash(&self.id, state);417}418}419420#[derive(Debug)]421#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]422pub(crate) struct EventInstance<E: BufferedEvent> {423pub event_id: EventId<E>,424pub event: E,425}426427/// A unique identifier for an [`Event`], used by [observers].428///429/// You can look up the key for your event by calling the [`Event::event_key`] method.430///431/// [observers]: crate::observer432#[derive(Debug, Copy, Clone, Hash, Ord, PartialOrd, Eq, PartialEq)]433pub struct EventKey(pub(crate) ComponentId);434435impl EventKey {436/// Returns the internal [`ComponentId`].437#[inline]438pub(crate) fn component_id(&self) -> ComponentId {439self.0440}441}442443444