From 15ffea3884e115be31525f082e6a8a96db7108e2 Mon Sep 17 00:00:00 2001 From: Tim Blackbird Date: Thu, 17 Jul 2025 14:56:28 +0200 Subject: [PATCH] docs! --- crates/bevy_ecs/src/event/base.rs | 140 ++++++++----------- crates/bevy_ecs/src/event/mod.rs | 22 ++- crates/bevy_scene/src/scene_spawner.rs | 4 +- release-content/release-notes/event_split.md | 1 + 4 files changed, 83 insertions(+), 84 deletions(-) diff --git a/crates/bevy_ecs/src/event/base.rs b/crates/bevy_ecs/src/event/base.rs index 041b127129..fd1144bc2a 100644 --- a/crates/bevy_ecs/src/event/base.rs +++ b/crates/bevy_ecs/src/event/base.rs @@ -11,84 +11,9 @@ use core::{ marker::PhantomData, }; -// TODO: These docs need to be moved around and adjusted -/// Something that "happens" and can be processed by app logic. -/// -/// Events can be triggered on a [`World`] using a method like [`trigger`](World::trigger), -/// causing any global [`Observer`] watching that event to run. This allows for push-based -/// event handling where observers are immediately notified of events as they happen. -/// -/// Additional event handling behavior can be enabled by implementing the [`EntityEvent`] -/// and [`BufferedEvent`] traits: -/// -/// - [`EntityEvent`]s support targeting specific entities, triggering any observers watching those targets. -/// They are useful for entity-specific event handlers and can even be propagated from one entity to another. -/// - [`BufferedEvent`]s support a pull-based event handling system where events are written using an [`EventWriter`] -/// and read later using an [`EventReader`]. This is an alternative to observers that allows efficient batch processing -/// of events at fixed points in a schedule. +/// Supertrait for the observer based [`BroadcastEvent`] and [`EntityEvent`]. /// /// Events must be thread-safe. -/// -/// # Usage -/// -/// The [`Event`] trait can be derived: -/// -/// ``` -/// # use bevy_ecs::prelude::*; -/// # -/// #[derive(BroadcastEvent)] -/// struct Speak { -/// message: String, -/// } -/// ``` -/// -/// An [`Observer`] can then be added to listen for this event type: -/// -/// ``` -/// # use bevy_ecs::prelude::*; -/// # -/// # #[derive(BroadcastEvent)] -/// # struct Speak { -/// # message: String, -/// # } -/// # -/// # let mut world = World::new(); -/// # -/// world.add_observer(|trigger: On| { -/// println!("{}", trigger.message); -/// }); -/// ``` -/// -/// The event can be triggered on the [`World`] using the [`trigger`](World::trigger) method: -/// -/// ``` -/// # use bevy_ecs::prelude::*; -/// # -/// # #[derive(BroadcastEvent)] -/// # struct Speak { -/// # message: String, -/// # } -/// # -/// # let mut world = World::new(); -/// # -/// # world.add_observer(|trigger: On| { -/// # println!("{}", trigger.message); -/// # }); -/// # -/// # world.flush(); -/// # -/// world.trigger(Speak { -/// message: "Hello!".to_string(), -/// }); -/// ``` -/// -/// For events that additionally need entity targeting or buffering, consider also deriving -/// [`EntityEvent`] or [`BufferedEvent`], respectively. -/// -/// [`World`]: crate::world::World -/// [`Observer`]: crate::observer::Observer -/// [`EventReader`]: super::EventReader -/// [`EventWriter`]: super::EventWriter #[diagnostic::on_unimplemented( message = "`{Self}` is not an `Event`", label = "invalid `Event`", @@ -129,7 +54,62 @@ pub trait Event: Send + Sync + 'static { } } -/// A global [`Event`] without an entity target. +/// An [`Event`] without an entity target. +/// +/// [`BroadcastEvent`]s can be triggered on a [`World`] with the method [`trigger`](World::trigger), +/// causing any [`Observer`] watching the event for those entities to run. +/// +/// # Usage +/// +/// The [`BroadcastEvent`] trait can be derived: +/// +/// ``` +/// # use bevy_ecs::prelude::*; +/// # +/// #[derive(BroadcastEvent)] +/// struct Speak { +/// message: String, +/// } +/// ``` +/// +/// An [`Observer`] can then be added to listen for this event type: +/// +/// ``` +/// # use bevy_ecs::prelude::*; +/// # +/// # #[derive(BroadcastEvent)] +/// # struct Speak { +/// # message: String, +/// # } +/// # +/// # let mut world = World::new(); +/// # +/// world.add_observer(|trigger: On| { +/// println!("{}", trigger.message); +/// }); +/// ``` +/// +/// The event can be triggered on the [`World`] using the [`trigger`](World::trigger) method: +/// +/// ``` +/// # use bevy_ecs::prelude::*; +/// # +/// # #[derive(BroadcastEvent)] +/// # struct Speak { +/// # message: String, +/// # } +/// # +/// # let mut world = World::new(); +/// # +/// world.trigger(Speak { +/// message: "Hello!".to_string(), +/// }); +/// ``` +/// +/// For events that additionally need entity targeting or buffering, consider also deriving +/// [`EntityEvent`] or [`BufferedEvent`], respectively. +/// +/// [`Observer`]: crate::observer::Observer pub trait BroadcastEvent: Event {} /// An [`Event`] that can be targeted at specific entities. @@ -138,7 +118,7 @@ pub trait BroadcastEvent: Event {} /// like [`trigger_targets`](World::trigger_targets), causing any [`Observer`] watching the event /// for those entities to run. /// -/// Unlike basic [`Event`]s, entity events can optionally be propagated from one entity target to another +/// Unlike [`BroadcastEvent`]s, entity events can optionally be propagated from one entity target to another /// based on the [`EntityEvent::Traversal`] type associated with the event. This enables use cases /// such as bubbling events to parent entities for UI purposes. /// @@ -237,12 +217,8 @@ pub trait BroadcastEvent: Event {} /// world.trigger_targets(Damage { amount: 10.0 }, armor_piece); /// ``` /// -/// [`World`]: crate::world::World /// [`TriggerTargets`]: crate::observer::TriggerTargets /// [`Observer`]: crate::observer::Observer -/// [`Events`]: super::Events -/// [`EventReader`]: super::EventReader -/// [`EventWriter`]: super::EventWriter #[diagnostic::on_unimplemented( message = "`{Self}` is not an `EntityEvent`", label = "invalid `EntityEvent`", diff --git a/crates/bevy_ecs/src/event/mod.rs b/crates/bevy_ecs/src/event/mod.rs index 3a5f1de8d6..8cb73523b9 100644 --- a/crates/bevy_ecs/src/event/mod.rs +++ b/crates/bevy_ecs/src/event/mod.rs @@ -1,4 +1,24 @@ -//! Event handling types. +//! Events are that "happens" and can be processed by app logic. +//! +//! [Event]s can be triggered on a [`World`](bevy_ecs::world::World) using a method like [`trigger`], +//! causing any global [`Observer`] watching that event to run. This allows for push-based +//! event handling where observers are immediately notified of events as they happen. +//! +//! Event handling behavior can be enabled by implementing the [`EntityEvent`] +//! and [`BufferedEvent`] traits: +//! +//! - [`Event`]: A supertrait for observer events. +//! - [`BroadcastEvent`]: An observer event without an entity target. +//! - [`EntityEvent`]s support targeting specific entities, triggering any observers watching those targets. +//! They are useful for entity-specific event handlers and can even be propagated from one entity to another. +//! - [`BufferedEvent`]s support a pull-based event handling system where events are written using an [`EventWriter`] +//! and read later using an [`EventReader`]. This is an alternative to observers that allows efficient batch processing +//! of events at fixed points in a schedule. +//! +//! [`World`]: crate::world::World +//! [`trigger`]: crate::world::World::trigger +//! [`Observer`]: crate::observer::Observer + mod base; mod collections; mod event_cursor; diff --git a/crates/bevy_scene/src/scene_spawner.rs b/crates/bevy_scene/src/scene_spawner.rs index 75caff003f..c415e8e1cb 100644 --- a/crates/bevy_scene/src/scene_spawner.rs +++ b/crates/bevy_scene/src/scene_spawner.rs @@ -22,11 +22,13 @@ use bevy_ecs::{ system::{Commands, Query}, }; -/// Triggered on a scene's parent entity when [`crate::SceneInstance`] becomes ready to use. +/// This [`Event`] is triggered when the [`SceneInstance`] becomes ready to use. +/// If the scene has a parent the event will be triggered on that entity, otherwise the event has no target. /// /// See also [`On`], [`SceneSpawner::instance_is_ready`]. /// /// [`On`]: bevy_ecs::observer::On +/// [`Event`]: bevy_ecs::event::Event #[derive(Clone, Copy, Debug, Eq, PartialEq, EntityEvent, Reflect)] #[reflect(Debug, PartialEq, Clone)] pub struct SceneInstanceReady { diff --git a/release-content/release-notes/event_split.md b/release-content/release-notes/event_split.md index d2d906262e..b3bf36ab37 100644 --- a/release-content/release-notes/event_split.md +++ b/release-content/release-notes/event_split.md @@ -24,6 +24,7 @@ All three patterns are fundamentally different in both the interface and usage. APIs are typically built to support only one of them. This has led to a lot of confusion and frustration for users. Common footguns include: + - Using a "buffered event" with an observer, or an observer event with `EventReader`, leaving the user wondering why the event is not being detected. - `On`(formerly `Trigger`) has a `target` getter which would cause confusion for events only mean to be used with `trigger` where it returns `Entity::PLACEHOLDER`.