Split BufferedEvent from Event (#20101)

# Objective

> I think we should axe the shared `Event` trait entirely
It doesn't serve any functional purpose, and I don't think it's useful
pedagogically
@alice-i-cecile on discord

## Solution

- Remove `Event` as a supertrait of `BufferedEvent`
- Remove any `Event` derives that were made unnecessary
- Update release notes

---------

Co-authored-by: SpecificProtagonist <vincentjunge@posteo.net>
This commit is contained in:
Tim 2025-07-14 23:31:48 +02:00 committed by GitHub
parent b47f6e8901
commit 4e9e78c31e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
50 changed files with 131 additions and 138 deletions

View File

@ -1,6 +1,6 @@
use bevy_ecs::prelude::*;
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct BenchEvent<const SIZE: usize>([u8; SIZE]);
pub struct Benchmark<const SIZE: usize>(Events<BenchEvent<SIZE>>);

View File

@ -1,6 +1,6 @@
use bevy_ecs::prelude::*;
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct BenchEvent<const SIZE: usize>([u8; SIZE]);
impl<const SIZE: usize> Default for BenchEvent<SIZE> {

View File

@ -26,10 +26,7 @@ use accesskit::Node;
use bevy_app::Plugin;
use bevy_derive::{Deref, DerefMut};
use bevy_ecs::{
component::Component,
event::{BufferedEvent, Event},
resource::Resource,
schedule::SystemSet,
component::Component, event::BufferedEvent, resource::Resource, schedule::SystemSet,
};
#[cfg(feature = "bevy_reflect")]
@ -45,7 +42,7 @@ use serde::{Deserialize, Serialize};
use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
/// Wrapper struct for [`accesskit::ActionRequest`]. Required to allow it to be used as an `Event`.
#[derive(Event, BufferedEvent, Deref, DerefMut)]
#[derive(BufferedEvent, Deref, DerefMut)]
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
pub struct ActionRequest(pub accesskit::ActionRequest);

View File

@ -355,7 +355,7 @@ impl App {
/// # use bevy_app::prelude::*;
/// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Event, BufferedEvent)]
/// # #[derive(BufferedEvent)]
/// # struct MyEvent;
/// # let mut app = App::new();
/// #
@ -1417,7 +1417,7 @@ fn run_once(mut app: App) -> AppExit {
/// This type is roughly meant to map to a standard definition of a process exit code (0 means success, not 0 means error). Due to portability concerns
/// (see [`ExitCode`](https://doc.rust-lang.org/std/process/struct.ExitCode.html) and [`process::exit`](https://doc.rust-lang.org/std/process/fn.exit.html#))
/// we only allow error codes between 1 and [255](u8::MAX).
#[derive(Event, BufferedEvent, Debug, Clone, Default, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, Default, PartialEq, Eq)]
pub enum AppExit {
/// [`App`] exited without any problems.
#[default]
@ -1485,7 +1485,7 @@ mod tests {
change_detection::{DetectChanges, ResMut},
component::Component,
entity::Entity,
event::{BufferedEvent, Event, EventWriter, Events},
event::{BufferedEvent, EventWriter, Events},
lifecycle::RemovedComponents,
query::With,
resource::Resource,
@ -1851,7 +1851,7 @@ mod tests {
}
#[test]
fn events_should_be_updated_once_per_update() {
#[derive(Event, BufferedEvent, Clone)]
#[derive(BufferedEvent, Clone)]
struct TestEvent;
let mut app = App::new();

View File

@ -1,12 +1,12 @@
use crate::{Asset, AssetId, AssetLoadError, AssetPath, UntypedAssetId};
use bevy_ecs::event::{BufferedEvent, Event};
use bevy_ecs::event::BufferedEvent;
use bevy_reflect::Reflect;
use core::fmt::Debug;
/// A [`BufferedEvent`] emitted when a specific [`Asset`] fails to load.
///
/// For an untyped equivalent, see [`UntypedAssetLoadFailedEvent`].
#[derive(Event, BufferedEvent, Clone, Debug)]
#[derive(BufferedEvent, Clone, Debug)]
pub struct AssetLoadFailedEvent<A: Asset> {
/// The stable identifier of the asset that failed to load.
pub id: AssetId<A>,
@ -24,7 +24,7 @@ impl<A: Asset> AssetLoadFailedEvent<A> {
}
/// An untyped version of [`AssetLoadFailedEvent`].
#[derive(Event, BufferedEvent, Clone, Debug)]
#[derive(BufferedEvent, Clone, Debug)]
pub struct UntypedAssetLoadFailedEvent {
/// The stable identifier of the asset that failed to load.
pub id: UntypedAssetId,
@ -46,7 +46,7 @@ impl<A: Asset> From<&AssetLoadFailedEvent<A>> for UntypedAssetLoadFailedEvent {
/// [`BufferedEvent`]s that occur for a specific loaded [`Asset`], such as "value changed" events and "dependency" events.
#[expect(missing_docs, reason = "Documenting the id fields is unhelpful.")]
#[derive(Event, BufferedEvent, Reflect)]
#[derive(BufferedEvent, Reflect)]
pub enum AssetEvent<A: Asset> {
/// Emitted whenever an [`Asset`] is added.
Added { id: AssetId<A> },

View File

@ -52,7 +52,7 @@ pub enum CiTestingEvent {
}
/// A custom event that can be configured from a configuration file for CI testing.
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
pub struct CiTestingCustomEvent(pub String);
#[cfg(test)]

View File

@ -285,7 +285,7 @@ They can be sent using the `EventWriter` system parameter and received with `Eve
```rust
use bevy_ecs::prelude::*;
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct Message(String);
fn writer(mut writer: EventWriter<Message>) {

View File

@ -37,7 +37,7 @@ fn main() {
}
// This is our event that we will send and receive in systems
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct MyEvent {
pub message: String,
pub random_value: f32,

View File

@ -230,7 +230,7 @@ pub trait DetectChangesMut: DetectChanges {
/// #[derive(Resource, PartialEq, Eq)]
/// pub struct Score(u32);
///
/// #[derive(Event, BufferedEvent, PartialEq, Eq)]
/// #[derive(BufferedEvent, PartialEq, Eq)]
/// pub struct ScoreChanged {
/// current: u32,
/// previous: u32,

View File

@ -259,7 +259,7 @@ pub trait EntityEvent: Event {
const AUTO_PROPAGATE: bool = false;
}
/// A buffered [`Event`] for pull-based event handling.
/// A buffered event for pull-based event handling.
///
/// Buffered events can be written with [`EventWriter`] and read using the [`EventReader`] system parameter.
/// These events are stored in the [`Events<E>`] resource, and require periodically polling the world for new events,
@ -286,7 +286,7 @@ pub trait EntityEvent: Event {
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// #[derive(Event, BufferedEvent)]
/// #[derive(BufferedEvent)]
/// struct Message(String);
/// ```
///
@ -295,7 +295,7 @@ pub trait EntityEvent: Event {
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Event, BufferedEvent)]
/// # #[derive(BufferedEvent)]
/// # struct Message(String);
/// #
/// fn write_hello(mut writer: EventWriter<Message>) {
@ -308,7 +308,7 @@ pub trait EntityEvent: Event {
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Event, BufferedEvent)]
/// # #[derive(BufferedEvent)]
/// # struct Message(String);
/// #
/// fn read_messages(mut reader: EventReader<Message>) {
@ -327,9 +327,9 @@ pub trait EntityEvent: Event {
#[diagnostic::on_unimplemented(
message = "`{Self}` is not an `BufferedEvent`",
label = "invalid `BufferedEvent`",
note = "consider annotating `{Self}` with `#[derive(Event, BufferedEvent)]`"
note = "consider annotating `{Self}` with `#[derive(BufferedEvent)]`"
)]
pub trait BufferedEvent: Event {}
pub trait BufferedEvent: Send + Sync + 'static {}
/// An internal type that implements [`Component`] for a given [`Event`] type.
///

View File

@ -40,9 +40,9 @@ use {
/// # Example
///
/// ```
/// use bevy_ecs::event::{BufferedEvent, Event, Events};
/// use bevy_ecs::event::{BufferedEvent, Events};
///
/// #[derive(Event, BufferedEvent)]
/// #[derive(BufferedEvent)]
/// struct MyEvent {
/// value: usize
/// }
@ -419,11 +419,11 @@ impl<E: BufferedEvent> ExactSizeIterator for WriteBatchIds<E> {
#[cfg(test)]
mod tests {
use crate::event::{BufferedEvent, Event, Events};
use crate::event::{BufferedEvent, Events};
#[test]
fn iter_current_update_events_iterates_over_current_events() {
#[derive(Event, BufferedEvent, Clone)]
#[derive(BufferedEvent, Clone)]
struct TestEvent;
let mut test_events = Events::<TestEvent>::default();

View File

@ -22,7 +22,7 @@ use core::marker::PhantomData;
/// use bevy_ecs::prelude::*;
/// use bevy_ecs::event::{BufferedEvent, Events, EventCursor};
///
/// #[derive(Event, BufferedEvent, Clone, Debug)]
/// #[derive(BufferedEvent, Clone, Debug)]
/// struct MyEvent;
///
/// /// A system that both sends and receives events using a [`Local`] [`EventCursor`].

View File

@ -41,12 +41,12 @@ mod tests {
use bevy_ecs::{event::*, system::assert_is_read_only_system};
use bevy_ecs_macros::BufferedEvent;
#[derive(Event, BufferedEvent, Copy, Clone, PartialEq, Eq, Debug)]
#[derive(BufferedEvent, Copy, Clone, PartialEq, Eq, Debug)]
struct TestEvent {
i: usize,
}
#[derive(Event, BufferedEvent, Clone, PartialEq, Debug, Default)]
#[derive(BufferedEvent, Clone, PartialEq, Debug, Default)]
struct EmptyTestEvent;
fn get_events<E: BufferedEvent + Clone>(

View File

@ -15,7 +15,7 @@ use bevy_ecs::{
/// ```
/// # use bevy_ecs::prelude::*;
///
/// #[derive(Event, BufferedEvent, Debug)]
/// #[derive(BufferedEvent, Debug)]
/// pub struct MyEvent(pub u32); // Custom event type.
/// fn my_system(mut reader: EventMutator<MyEvent>) {
/// for event in reader.read() {
@ -69,7 +69,7 @@ impl<'w, 's, E: BufferedEvent> EventMutator<'w, 's, E> {
/// # use bevy_ecs::prelude::*;
/// # use std::sync::atomic::{AtomicUsize, Ordering};
///
/// #[derive(Event, BufferedEvent)]
/// #[derive(BufferedEvent)]
/// struct MyEvent {
/// value: usize,
/// }
@ -116,7 +116,7 @@ impl<'w, 's, E: BufferedEvent> EventMutator<'w, 's, E> {
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// #[derive(Event, BufferedEvent)]
/// #[derive(BufferedEvent)]
/// struct CollisionEvent;
///
/// fn play_collision_sound(mut events: EventMutator<CollisionEvent>) {

View File

@ -41,7 +41,7 @@ impl<'w, 's, E: BufferedEvent> EventReader<'w, 's, E> {
/// # use bevy_ecs::prelude::*;
/// # use std::sync::atomic::{AtomicUsize, Ordering};
///
/// #[derive(Event, BufferedEvent)]
/// #[derive(BufferedEvent)]
/// struct MyEvent {
/// value: usize,
/// }
@ -88,7 +88,7 @@ impl<'w, 's, E: BufferedEvent> EventReader<'w, 's, E> {
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// #[derive(Event, BufferedEvent)]
/// #[derive(BufferedEvent)]
/// struct CollisionEvent;
///
/// fn play_collision_sound(mut events: EventReader<CollisionEvent>) {

View File

@ -11,7 +11,7 @@ use bevy_ecs::{
/// ```
/// # use bevy_ecs::prelude::*;
///
/// #[derive(Event, BufferedEvent)]
/// #[derive(BufferedEvent)]
/// pub struct MyEvent; // Custom event type.
/// fn my_system(mut writer: EventWriter<MyEvent>) {
/// writer.write(MyEvent);
@ -38,7 +38,7 @@ use bevy_ecs::{
///
/// ```
/// # use bevy_ecs::{prelude::*, event::Events};
/// # #[derive(Event, BufferedEvent)]
/// # #[derive(BufferedEvent)]
/// # pub struct MyEvent;
/// fn write_untyped(mut commands: Commands) {
/// // Write an event of a specific type without having to declare that

View File

@ -60,7 +60,7 @@ pub mod world;
pub use bevy_ptr as ptr;
#[cfg(feature = "hotpatching")]
use event::{BufferedEvent, Event};
use event::BufferedEvent;
/// The ECS prelude.
///
@ -140,7 +140,7 @@ pub mod __macro_exports {
///
/// Systems should refresh their inner pointers.
#[cfg(feature = "hotpatching")]
#[derive(Event, BufferedEvent, Default)]
#[derive(BufferedEvent, Default)]
pub struct HotPatched;
#[cfg(test)]

View File

@ -393,7 +393,7 @@ pub type OnDespawn = Despawn;
/// Wrapper around [`Entity`] for [`RemovedComponents`].
/// Internally, `RemovedComponents` uses these as an `Events<RemovedComponentEntity>`.
#[derive(Event, BufferedEvent, Debug, Clone, Into)]
#[derive(BufferedEvent, Debug, Clone, Into)]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
#[cfg_attr(feature = "bevy_reflect", reflect(Debug, Clone))]
pub struct RemovedComponentEntity(Entity);

View File

@ -864,7 +864,7 @@ pub mod common_conditions {
/// my_system.run_if(on_event::<MyEvent>),
/// );
///
/// #[derive(Event, BufferedEvent)]
/// #[derive(BufferedEvent)]
/// struct MyEvent;
///
/// fn my_system(mut counter: ResMut<Counter>) {
@ -1264,7 +1264,7 @@ where
#[cfg(test)]
mod tests {
use super::{common_conditions::*, SystemCondition};
use crate::event::{BufferedEvent, Event};
use crate::event::BufferedEvent;
use crate::query::With;
use crate::{
change_detection::ResMut,
@ -1384,7 +1384,7 @@ mod tests {
#[derive(Component)]
struct TestComponent;
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct TestEvent;
#[derive(Resource)]

View File

@ -783,7 +783,7 @@ mod tests {
#[derive(Component)]
struct B;
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct E;
#[derive(Resource, Component)]

View File

@ -135,7 +135,7 @@ impl SystemMeta {
/// # use bevy_ecs::system::SystemState;
/// # use bevy_ecs::event::Events;
/// #
/// # #[derive(Event, BufferedEvent)]
/// # #[derive(BufferedEvent)]
/// # struct MyEvent;
/// # #[derive(Resource)]
/// # struct MyResource(u32);
@ -168,7 +168,7 @@ impl SystemMeta {
/// # use bevy_ecs::system::SystemState;
/// # use bevy_ecs::event::Events;
/// #
/// # #[derive(Event, BufferedEvent)]
/// # #[derive(BufferedEvent)]
/// # struct MyEvent;
/// #[derive(Resource)]
/// struct CachedSystemState {

View File

@ -57,7 +57,7 @@ use variadics_please::{all_tuples, all_tuples_enumerated};
/// # use bevy_ecs::prelude::*;
/// # #[derive(Resource)]
/// # struct SomeResource;
/// # #[derive(Event, BufferedEvent)]
/// # #[derive(BufferedEvent)]
/// # struct SomeEvent;
/// # #[derive(Resource)]
/// # struct SomeOtherResource;
@ -601,7 +601,7 @@ unsafe impl<'w, 's, D: ReadOnlyQueryData + 'static, F: QueryFilter + 'static> Re
/// ```
/// # use bevy_ecs::prelude::*;
/// #
/// # #[derive(Event, BufferedEvent)]
/// # #[derive(BufferedEvent)]
/// # struct MyEvent;
/// # impl MyEvent {
/// # pub fn new() -> Self { Self }
@ -2853,7 +2853,7 @@ impl Display for SystemParamValidationError {
#[cfg(test)]
mod tests {
use super::*;
use crate::{event::Event, system::assert_is_system};
use crate::system::assert_is_system;
use core::cell::RefCell;
// Compile test for https://github.com/bevyengine/bevy/pull/2838.
@ -3103,7 +3103,7 @@ mod tests {
fn missing_event_error() {
use crate::prelude::{BufferedEvent, EventReader};
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
pub struct MissingEvent;
let mut schedule = crate::schedule::Schedule::default();

View File

@ -10,7 +10,7 @@ use bevy_ecs::{
change_detection::DetectChangesMut,
component::Component,
entity::Entity,
event::{BufferedEvent, Event, EventReader, EventWriter},
event::{BufferedEvent, EventReader, EventWriter},
name::Name,
system::{Commands, Query},
};
@ -32,7 +32,7 @@ use thiserror::Error;
/// the in-frame relative ordering of events is important.
///
/// This event is produced by `bevy_input`.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, From)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, From)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -59,7 +59,7 @@ pub enum GamepadEvent {
/// the in-frame relative ordering of events is important.
///
/// This event type is used by `bevy_input` to feed its components.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, From)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, From)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -80,7 +80,7 @@ pub enum RawGamepadEvent {
}
/// [`GamepadButton`] changed event unfiltered by [`GamepadSettings`].
#[derive(Event, BufferedEvent, Debug, Copy, Clone, PartialEq)]
#[derive(BufferedEvent, Debug, Copy, Clone, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -112,7 +112,7 @@ impl RawGamepadButtonChangedEvent {
}
/// [`GamepadAxis`] changed event unfiltered by [`GamepadSettings`].
#[derive(Event, BufferedEvent, Debug, Copy, Clone, PartialEq)]
#[derive(BufferedEvent, Debug, Copy, Clone, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -145,7 +145,7 @@ impl RawGamepadAxisChangedEvent {
/// A [`Gamepad`] connection event. Created when a connection to a gamepad
/// is established and when a gamepad is disconnected.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -184,7 +184,7 @@ impl GamepadConnectionEvent {
}
/// [`GamepadButton`] event triggered by a digital state change.
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -216,7 +216,7 @@ impl GamepadButtonStateChangedEvent {
}
/// [`GamepadButton`] event triggered by an analog state change.
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -251,7 +251,7 @@ impl GamepadButtonChangedEvent {
}
/// [`GamepadAxis`] event triggered by an analog state change.
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(
feature = "bevy_reflect",
@ -1774,7 +1774,7 @@ impl GamepadRumbleIntensity {
#[doc(alias = "force feedback")]
#[doc(alias = "vibration")]
#[doc(alias = "vibrate")]
#[derive(Event, BufferedEvent, Clone)]
#[derive(BufferedEvent, Clone)]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Clone))]
pub enum GamepadRumbleRequest {
/// Add a rumble to the given gamepad.

View File

@ -1,6 +1,6 @@
//! Gestures functionality, from touchscreens and touchpads.
use bevy_ecs::event::{BufferedEvent, Event};
use bevy_ecs::event::BufferedEvent;
use bevy_math::Vec2;
#[cfg(feature = "bevy_reflect")]
use bevy_reflect::Reflect;
@ -17,7 +17,7 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
///
/// - Only available on **`macOS`** and **`iOS`**.
/// - On **`iOS`**, must be enabled first
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -39,7 +39,7 @@ pub struct PinchGesture(pub f32);
///
/// - Only available on **`macOS`** and **`iOS`**.
/// - On **`iOS`**, must be enabled first
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -58,7 +58,7 @@ pub struct RotationGesture(pub f32);
///
/// - Only available on **`macOS`** and **`iOS`**.
/// - On **`iOS`**, must be enabled first
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -76,7 +76,7 @@ pub struct DoubleTapGesture;
/// ## Platform-specific
///
/// - On **`iOS`**, must be enabled first
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),

View File

@ -69,7 +69,7 @@ use crate::{ButtonInput, ButtonState};
use bevy_ecs::{
change_detection::DetectChangesMut,
entity::Entity,
event::{BufferedEvent, Event, EventReader},
event::{BufferedEvent, EventReader},
system::ResMut,
};
@ -95,7 +95,7 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
/// The event is consumed inside of the [`keyboard_input_system`] to update the
/// [`ButtonInput<KeyCode>`](ButtonInput<KeyCode>) and
/// [`ButtonInput<Key>`](ButtonInput<Key>) resources.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq, Hash)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq, Hash)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -144,7 +144,7 @@ pub struct KeyboardInput {
/// when, for example, switching between windows with 'Alt-Tab' or using any other
/// OS specific key combination that leads to Bevy window losing focus and not receiving any
/// input events
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "bevy_reflect", derive(Reflect), reflect(Clone, PartialEq))]
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(

View File

@ -4,7 +4,7 @@ use crate::{ButtonInput, ButtonState};
use bevy_ecs::{
change_detection::DetectChangesMut,
entity::Entity,
event::{BufferedEvent, Event, EventReader},
event::{BufferedEvent, EventReader},
resource::Resource,
system::ResMut,
};
@ -26,7 +26,7 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
///
/// The event is read inside of the [`mouse_button_input_system`]
/// to update the [`ButtonInput<MouseButton>`] resource.
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -91,7 +91,7 @@ pub enum MouseButton {
/// However, the event data does not make it possible to distinguish which device it is referring to.
///
/// [`DeviceEvent::MouseMotion`]: https://docs.rs/winit/latest/winit/event/enum.DeviceEvent.html#variant.MouseMotion
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -140,7 +140,7 @@ pub enum MouseScrollUnit {
/// A mouse wheel event.
///
/// This event is the translated version of the `WindowEvent::MouseWheel` from the `winit` crate.
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),

View File

@ -2,7 +2,7 @@
use bevy_ecs::{
entity::Entity,
event::{BufferedEvent, Event, EventReader},
event::{BufferedEvent, EventReader},
resource::Resource,
system::ResMut,
};
@ -37,7 +37,7 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
///
/// This event is the translated version of the `WindowEvent::Touch` from the `winit` crate.
/// It is available to the end user and can be used for game logic.
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),

View File

@ -55,7 +55,7 @@ pub mod prelude {
/// Note that systems reading these events in [`PreUpdate`](bevy_app::PreUpdate) will not report ordering
/// ambiguities with picking backends. Take care to ensure such systems are explicitly ordered
/// against [`PickingSystems::Backend`](crate::PickingSystems::Backend), or better, avoid reading `PointerHits` in `PreUpdate`.
#[derive(Event, BufferedEvent, Debug, Clone, Reflect)]
#[derive(BufferedEvent, Debug, Clone, Reflect)]
#[reflect(Debug, Clone)]
pub struct PointerHits {
/// The pointer associated with this hit test.

View File

@ -48,7 +48,7 @@
//! # use bevy_ecs::prelude::*;
//! # use bevy_transform::prelude::*;
//! # use bevy_picking::prelude::*;
//! # #[derive(Event, BufferedEvent)]
//! # #[derive(BufferedEvent)]
//! # struct Greeting;
//! fn setup(mut commands: Commands) {
//! commands.spawn(Transform::default())

View File

@ -269,7 +269,7 @@ pub enum PointerAction {
}
/// An input event effecting a pointer.
#[derive(Event, BufferedEvent, Debug, Clone, Reflect)]
#[derive(BufferedEvent, Debug, Clone, Reflect)]
#[reflect(Clone)]
pub struct PointerInput {
/// The id of the pointer.

View File

@ -1,7 +1,7 @@
use core::{marker::PhantomData, mem};
use bevy_ecs::{
event::{BufferedEvent, Event, EventReader, EventWriter},
event::{BufferedEvent, EventReader, EventWriter},
schedule::{IntoScheduleConfigs, Schedule, ScheduleLabel, Schedules, SystemSet},
system::{Commands, In, ResMut},
world::World,
@ -61,7 +61,7 @@ pub struct StateTransition;
/// This includes identity transitions, where `exited` and `entered` have the same value.
///
/// If you know exactly what state you want to respond to ahead of time, consider [`OnEnter`], [`OnTransition`], or [`OnExit`]
#[derive(Debug, Copy, Clone, PartialEq, Eq, Event, BufferedEvent)]
#[derive(Debug, Copy, Clone, PartialEq, Eq, BufferedEvent)]
pub struct StateTransitionEvent<S: States> {
/// The state being exited.
pub exited: Option<S>,

View File

@ -187,7 +187,7 @@ impl StateScopedEventsAppExt for SubApp {
mod tests {
use super::*;
use crate::app::StatesPlugin;
use bevy_ecs::event::{BufferedEvent, Event};
use bevy_ecs::event::BufferedEvent;
use bevy_state::prelude::*;
#[derive(States, Default, Clone, Hash, Eq, PartialEq, Debug)]
@ -197,10 +197,10 @@ mod tests {
B,
}
#[derive(Event, BufferedEvent, Debug)]
#[derive(BufferedEvent, Debug)]
struct StandardEvent;
#[derive(Event, BufferedEvent, Debug)]
#[derive(BufferedEvent, Debug)]
struct StateScopedEvent;
#[test]

View File

@ -186,8 +186,7 @@ mod tests {
use bevy_app::{App, FixedUpdate, Startup, Update};
use bevy_ecs::{
event::{
BufferedEvent, Event, EventReader, EventRegistry, EventWriter, Events,
ShouldUpdateEvents,
BufferedEvent, EventReader, EventRegistry, EventWriter, Events, ShouldUpdateEvents,
},
resource::Resource,
system::{Local, Res, ResMut},
@ -196,7 +195,7 @@ mod tests {
use core::time::Duration;
use std::println;
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct TestEvent<T: Default> {
sender: std::sync::mpsc::Sender<T>,
}
@ -209,7 +208,7 @@ mod tests {
}
}
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct DummyEvent;
#[derive(Resource, Default)]

View File

@ -119,7 +119,7 @@ use {
/// # use bevy_ecs::prelude::*;
/// # use bevy_time::prelude::*;
/// #
/// #[derive(Event, BufferedEvent)]
/// #[derive(BufferedEvent)]
/// struct PauseEvent(bool);
///
/// fn pause_system(mut time: ResMut<Time<Virtual>>, mut events: EventReader<PauseEvent>) {

View File

@ -1,8 +1,5 @@
use alloc::string::String;
use bevy_ecs::{
entity::Entity,
event::{BufferedEvent, Event},
};
use bevy_ecs::{entity::Entity, event::BufferedEvent};
use bevy_input::{
gestures::*,
keyboard::{KeyboardFocusLost, KeyboardInput},
@ -26,7 +23,7 @@ use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
use crate::WindowTheme;
/// A window event that is sent whenever a window's logical size has changed.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -48,7 +45,7 @@ pub struct WindowResized {
/// An event that indicates all of the application's windows should be redrawn,
/// even if their control flow is set to `Wait` and there have been no window events.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -64,7 +61,7 @@ pub struct RequestRedraw;
/// An event that is sent whenever a new window is created.
///
/// To create a new window, spawn an entity with a [`crate::Window`] on it.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -90,7 +87,7 @@ pub struct WindowCreated {
///
/// [`WindowPlugin`]: crate::WindowPlugin
/// [`Window`]: crate::Window
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -108,7 +105,7 @@ pub struct WindowCloseRequested {
/// An event that is sent whenever a window is closed. This will be sent when
/// the window entity loses its [`Window`](crate::window::Window) component or is despawned.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -129,7 +126,7 @@ pub struct WindowClosed {
/// An event that is sent whenever a window is closing. This will be sent when
/// after a [`WindowCloseRequested`] event is received and the window is in the process of closing.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -149,7 +146,7 @@ pub struct WindowClosing {
///
/// Note that if your application only has a single window, this event may be your last chance to
/// persist state before the application terminates.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -179,7 +176,7 @@ pub struct WindowDestroyed {
/// you should not use it for non-cursor-like behavior such as 3D camera control. Please see `MouseMotion` instead.
///
/// [`WindowEvent::CursorMoved`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.CursorMoved
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -204,7 +201,7 @@ pub struct CursorMoved {
}
/// An event that is sent whenever the user's cursor enters a window.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -221,7 +218,7 @@ pub struct CursorEntered {
}
/// An event that is sent whenever the user's cursor leaves a window.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -242,7 +239,7 @@ pub struct CursorLeft {
/// This event is the translated version of the `WindowEvent::Ime` from the `winit` crate.
///
/// It is only sent if IME was enabled on the window with [`Window::ime_enabled`](crate::window::Window::ime_enabled).
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -287,7 +284,7 @@ pub enum Ime {
}
/// An event that indicates a window has received or lost focus.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -314,7 +311,7 @@ pub struct WindowFocused {
/// It is the translated version of [`WindowEvent::Occluded`] from the `winit` crate.
///
/// [`WindowEvent::Occluded`]: https://docs.rs/winit/latest/winit/event/enum.WindowEvent.html#variant.Occluded
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -333,7 +330,7 @@ pub struct WindowOccluded {
}
/// An event that indicates a window's scale factor has changed.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -352,7 +349,7 @@ pub struct WindowScaleFactorChanged {
}
/// An event that indicates a window's OS-reported scale factor has changed.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -371,7 +368,7 @@ pub struct WindowBackendScaleFactorChanged {
}
/// Events related to files being dragged and dropped on a window.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -407,7 +404,7 @@ pub enum FileDragAndDrop {
}
/// An event that is sent when a window is repositioned in physical pixels.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -429,7 +426,7 @@ pub struct WindowMoved {
///
/// This event is only sent when the window is relying on the system theme to control its appearance.
/// i.e. It is only sent when [`Window::window_theme`](crate::window::Window::window_theme) is `None` and the system theme changes.
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -448,7 +445,7 @@ pub struct WindowThemeChanged {
}
/// Application lifetime events
#[derive(Event, BufferedEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[derive(BufferedEvent, Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),
@ -491,7 +488,7 @@ impl AppLifecycle {
/// access window events in the order they were received from the
/// operating system. Otherwise, the event types are individually
/// readable with `EventReader<E>` (e.g. `EventReader<KeyboardInput>`).
#[derive(Event, BufferedEvent, Debug, Clone, PartialEq)]
#[derive(BufferedEvent, Debug, Clone, PartialEq)]
#[cfg_attr(
feature = "bevy_reflect",
derive(Reflect),

View File

@ -156,7 +156,7 @@ impl<T: BufferedEvent> Plugin for WinitPlugin<T> {
/// The default event that can be used to wake the window loop
/// Wakes up the loop if in wait state
#[derive(Debug, Default, Clone, Copy, Event, BufferedEvent, Reflect)]
#[derive(Debug, Default, Clone, Copy, BufferedEvent, Reflect)]
#[reflect(Debug, Default, Clone)]
pub struct WakeUp;
@ -167,7 +167,7 @@ pub struct WakeUp;
///
/// When you receive this event it has already been handled by Bevy's main loop.
/// Sending these events will NOT cause them to be processed by Bevy.
#[derive(Debug, Clone, Event, BufferedEvent)]
#[derive(Debug, Clone, BufferedEvent)]
pub struct RawWinitWindowEvent {
/// The window for which the event was fired.
pub window_id: WindowId,

View File

@ -72,7 +72,7 @@ enum LightingMode {
/// An event that's fired whenever the user changes the lighting mode.
///
/// This is also fired when the scene loads for the first time.
#[derive(Clone, Copy, Default, Event, BufferedEvent)]
#[derive(Clone, Copy, Default, BufferedEvent)]
struct LightingModeChanged;
#[derive(Clone, Copy, Component, Debug)]

View File

@ -38,7 +38,7 @@ fn main() {
}
/// A basic message. This is what we will be sending from the [`CaptureLayer`] to [`CapturedLogEvents`] non-send resource.
#[derive(Debug, Event, BufferedEvent)]
#[derive(Debug, BufferedEvent)]
struct LogEvent {
message: String,
level: Level,

View File

@ -20,7 +20,7 @@ fn main() {
#[derive(Resource, Deref)]
struct StreamReceiver(Receiver<u32>);
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct StreamEvent(u32);
fn setup(mut commands: Commands) {

View File

@ -12,7 +12,7 @@ fn main() {
.run();
}
#[derive(Event, BufferedEvent, Default)]
#[derive(BufferedEvent, Default)]
struct PlayPitch;
#[derive(Resource)]

View File

@ -45,7 +45,7 @@ impl Component for MyComponent {
#[derive(Resource, Default, Debug, Deref, DerefMut)]
struct MyComponentIndex(HashMap<KeyCode, Entity>);
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct MyEvent;
fn main() {

View File

@ -6,17 +6,17 @@ use bevy::prelude::*;
// In order to send or receive events first you must define them
// This event should be sent when something attempts to deal damage to another entity.
#[derive(Event, BufferedEvent, Debug)]
#[derive(BufferedEvent, Debug)]
struct DealDamage {
pub amount: i32,
}
// This event should be sent when an entity receives damage.
#[derive(Event, BufferedEvent, Debug, Default)]
#[derive(BufferedEvent, Debug, Default)]
struct DamageReceived;
// This event should be sent when an entity blocks damage with armor.
#[derive(Event, BufferedEvent, Debug, Default)]
#[derive(BufferedEvent, Debug, Default)]
struct ArmorBlockedDamage;
// This resource represents a timer used to determine when to deal damage

View File

@ -46,10 +46,10 @@ fn main() {
app.update();
}
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct A;
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct B;
// This works fine, because the types are different,
@ -62,7 +62,7 @@ fn read_and_write_different_event_types(mut a: EventWriter<A>, mut b: EventReade
}
/// A dummy event type.
#[derive(Debug, Clone, Event, BufferedEvent)]
#[derive(Debug, Clone, BufferedEvent)]
struct DebugEvent {
resend_from_param_set: bool,
resend_from_local_event_reader: bool,

View File

@ -89,7 +89,7 @@ struct Ball;
#[derive(Component, Deref, DerefMut)]
struct Velocity(Vec2);
#[derive(Event, BufferedEvent, Default)]
#[derive(BufferedEvent, Default)]
struct CollisionEvent;
#[derive(Component)]

View File

@ -6,7 +6,7 @@ use bevy::{ecs::system::EntityCommands, prelude::*};
/// An event that's sent whenever the user changes one of the settings by
/// clicking a radio button.
#[derive(Clone, Event, BufferedEvent, Deref, DerefMut)]
#[derive(Clone, BufferedEvent, Deref, DerefMut)]
pub struct WidgetClickEvent<T>(T);
/// A marker component that we place on all widgets that send

View File

@ -35,7 +35,7 @@ enum Constraint {
#[derive(Copy, Clone, Component)]
struct ButtonValue(Val);
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct ButtonActivatedEvent(Entity);
fn setup(mut commands: Commands, asset_server: Res<AssetServer>) {

View File

@ -6,7 +6,7 @@ use bevy::{
};
use std::fmt::Formatter;
#[derive(Default, Debug, Event, BufferedEvent)]
#[derive(Default, Debug, BufferedEvent)]
enum CustomEvent {
#[default]
WakeUp,

View File

@ -13,7 +13,7 @@ As a workaround, you can transform any entity-event into a buffered event that c
an observer than emits events.
```rust
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct TransformedEntityEvent<E: EntityEvent> {
entity: Entity,
event: E,

View File

@ -1,7 +1,7 @@
---
title: Event Split
authors: ["@Jondolf"]
pull_requests: [19647]
pull_requests: [19647, 20101]
---
In past releases, all event types were defined by simply deriving the `Event` trait:
@ -28,9 +28,9 @@ or an observer event with `EventReader`, leaving the user wondering why the even
**Bevy 0.17** aims to solve this ambiguity by splitting the event traits into `Event`, `EntityEvent`, and `BufferedEvent`.
- `Event`: A shared trait for all events.
- `Event`: A shared trait for observer events.
- `EntityEvent`: An `Event` that additionally supports targeting specific entities and propagating the event from one entity to another.
- `BufferedEvent`: An `Event` that additionally supports usage with `EventReader` and `EventWriter` for pull-based event handling.
- `BufferedEvent`: An event that supports usage with `EventReader` and `EventWriter` for pull-based event handling.
## Using Events
@ -92,10 +92,10 @@ let armor_piece = commands
commands.trigger_targets(Damage { amount: 10.0 }, armor_piece);
```
To allow an event to be used with the buffered API, you can also derive `BufferedEvent`:
To allow an event to be used with the buffered API, you can instead derive `BufferedEvent`:
```rust
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct Message(String);
```
@ -117,5 +117,5 @@ fn read_messages(mut reader: EventReader<Message>) {
In summary:
- Need a basic event you can trigger and observe? Derive `Event`!
- Need the event to be targeted at an entity? Derive `EntityEvent`!
- Need the observer event to be targeted at an entity? Derive `EntityEvent`!
- Need the event to be buffered and support the `EventReader`/`EventWriter` API? Derive `BufferedEvent`!

View File

@ -7,7 +7,7 @@ struct Enemy {
score_value: u32,
}
#[derive(Event, BufferedEvent)]
#[derive(BufferedEvent)]
struct EnemyDied(u32);
#[derive(Resource)]