Make BroadcastEvent
and EntityEvent
mutually exclusive
This commit is contained in:
parent
9154556d97
commit
bd812cd9e0
@ -30,8 +30,9 @@ pub fn derive_broadcast_event(input: TokenStream) -> TokenStream {
|
||||
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
|
||||
|
||||
TokenStream::from(quote! {
|
||||
impl #impl_generics #bevy_ecs_path::event::Event for #struct_name #type_generics #where_clause {}
|
||||
impl #impl_generics #bevy_ecs_path::event::BroadcastEvent for #struct_name #type_generics #where_clause {}
|
||||
impl #impl_generics #bevy_ecs_path::event::Event for #struct_name #type_generics #where_clause {
|
||||
type Kind = #bevy_ecs_path::event::BroadcastEventKind;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@ -74,10 +75,8 @@ pub fn derive_entity_event(input: TokenStream) -> TokenStream {
|
||||
let (impl_generics, type_generics, where_clause) = &ast.generics.split_for_impl();
|
||||
|
||||
TokenStream::from(quote! {
|
||||
impl #impl_generics #bevy_ecs_path::event::Event for #struct_name #type_generics #where_clause {}
|
||||
impl #impl_generics #bevy_ecs_path::event::EntityEvent for #struct_name #type_generics #where_clause {
|
||||
type Traversal = #traversal;
|
||||
const AUTO_PROPAGATE: bool = #auto_propagate;
|
||||
impl #impl_generics #bevy_ecs_path::event::Event for #struct_name #type_generics #where_clause {
|
||||
type Kind = #bevy_ecs_path::event::EntityEventKind<Self, #traversal, #auto_propagate>;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use core::{
|
||||
marker::PhantomData,
|
||||
};
|
||||
|
||||
// TODO: Adjust these docs
|
||||
// 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),
|
||||
@ -36,7 +36,7 @@ use core::{
|
||||
/// ```
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// #
|
||||
/// #[derive(Event)]
|
||||
/// #[derive(BroadcastEvent)]
|
||||
/// struct Speak {
|
||||
/// message: String,
|
||||
/// }
|
||||
@ -47,7 +47,7 @@ use core::{
|
||||
/// ```
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// #
|
||||
/// # #[derive(Event)]
|
||||
/// # #[derive(BroadcastEvent)]
|
||||
/// # struct Speak {
|
||||
/// # message: String,
|
||||
/// # }
|
||||
@ -64,7 +64,7 @@ use core::{
|
||||
/// ```
|
||||
/// # use bevy_ecs::prelude::*;
|
||||
/// #
|
||||
/// # #[derive(Event)]
|
||||
/// # #[derive(BroadcastEvent)]
|
||||
/// # struct Speak {
|
||||
/// # message: String,
|
||||
/// # }
|
||||
@ -90,11 +90,14 @@ use core::{
|
||||
/// [`EventReader`]: super::EventReader
|
||||
/// [`EventWriter`]: super::EventWriter
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` is not an `ObserverEvent`",
|
||||
label = "invalid `ObserverEvent`",
|
||||
message = "`{Self}` is not an `Event`",
|
||||
label = "invalid `Event`",
|
||||
note = "consider annotating `{Self}` with `#[derive(BroadcastEvent)]` or `#[derive(EntityEvent)]`"
|
||||
)]
|
||||
pub trait Event: Send + Sync + 'static {
|
||||
///
|
||||
type Kind;
|
||||
|
||||
/// Generates the [`EventKey`] for this event type.
|
||||
///
|
||||
/// If this type has already been registered,
|
||||
@ -130,7 +133,32 @@ pub trait Event: Send + Sync + 'static {
|
||||
}
|
||||
|
||||
/// A global [`Event`] without an entity target.
|
||||
pub trait BroadcastEvent: Event {}
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "`{Self}` is not an `BroadcastEvent`",
|
||||
label = "invalid `BroadcastEvent`",
|
||||
note = "consider annotating `{Self}` with `#[derive(BroadcastEvent)]`"
|
||||
)]
|
||||
pub trait BroadcastEvent: Event + sealed_a::SealedA {}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct BroadcastEventKind;
|
||||
|
||||
#[diagnostic::do_not_recommend]
|
||||
impl<T> BroadcastEvent for T where T: Event<Kind = BroadcastEventKind> {}
|
||||
|
||||
pub(crate) mod sealed_a {
|
||||
use super::*;
|
||||
|
||||
/// Seal for the [`BroadcastEvent`] trait.
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "manual implementations of `BroadcastEvent` are disallowed",
|
||||
note = "consider annotating `{Self}` with `#[derive(BroadcastEvent)]` instead"
|
||||
)]
|
||||
pub trait SealedA {}
|
||||
|
||||
#[diagnostic::do_not_recommend]
|
||||
impl<T> SealedA for T where T: Event<Kind = BroadcastEventKind> {}
|
||||
}
|
||||
|
||||
/// An [`Event`] that can be targeted at specific entities.
|
||||
///
|
||||
@ -248,7 +276,7 @@ pub trait BroadcastEvent: Event {}
|
||||
label = "invalid `EntityEvent`",
|
||||
note = "consider annotating `{Self}` with `#[derive(EntityEvent)]`"
|
||||
)]
|
||||
pub trait EntityEvent: Event {
|
||||
pub trait EntityEvent: Event + sealed_b::SealedB {
|
||||
/// The component that describes which [`Entity`] to propagate this event to next, when [propagation] is enabled.
|
||||
///
|
||||
/// [`Entity`]: crate::entity::Entity
|
||||
@ -263,6 +291,37 @@ pub trait EntityEvent: Event {
|
||||
const AUTO_PROPAGATE: bool = false;
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct EntityEventKind<T: ?Sized, R: Traversal<T>, const A: bool> {
|
||||
_t: PhantomData<T>,
|
||||
_r: PhantomData<R>,
|
||||
}
|
||||
|
||||
// Blanket impl for EntityEvent
|
||||
#[diagnostic::do_not_recommend]
|
||||
impl<T, R: Traversal<T>, const A: bool> EntityEvent for T
|
||||
where
|
||||
T: Event<Kind = EntityEventKind<T, R, A>>,
|
||||
{
|
||||
type Traversal = R;
|
||||
const AUTO_PROPAGATE: bool = A;
|
||||
}
|
||||
|
||||
pub(crate) mod sealed_b {
|
||||
use super::*;
|
||||
|
||||
/// Seal for the [`EntityEvent`] trait.
|
||||
#[diagnostic::on_unimplemented(
|
||||
message = "manual implementations of `EntityEvent` are disallowed",
|
||||
note = "consider annotating `{Self}` with `#[derive(EntityEvent)]` instead"
|
||||
)]
|
||||
pub trait SealedB {}
|
||||
|
||||
#[diagnostic::do_not_recommend]
|
||||
impl<T, R: Traversal<T>, const A: bool> SealedB for T where T: Event<Kind = EntityEventKind<T, R, A>>
|
||||
{}
|
||||
}
|
||||
|
||||
/// A buffered event for pull-based event handling.
|
||||
///
|
||||
/// Buffered events can be written with [`EventWriter`] and read using the [`EventReader`] system parameter.
|
||||
|
@ -11,7 +11,10 @@ mod update;
|
||||
mod writer;
|
||||
|
||||
pub(crate) use base::EventInstance;
|
||||
pub use base::{BroadcastEvent, BufferedEvent, EntityEvent, Event, EventId, EventKey};
|
||||
pub use base::{
|
||||
BroadcastEvent, BroadcastEventKind, BufferedEvent, EntityEvent, EntityEventKind, Event,
|
||||
EventId, EventKey,
|
||||
};
|
||||
pub use bevy_ecs_macros::{BroadcastEvent, BufferedEvent, EntityEvent};
|
||||
#[expect(deprecated, reason = "`SendBatchIds` was renamed to `WriteBatchIds`.")]
|
||||
pub use collections::{Events, SendBatchIds, WriteBatchIds};
|
||||
|
Loading…
Reference in New Issue
Block a user