Revert changes related mutual exclusivity + minor docs and release note changes
This commit is contained in:
parent
779e4535d9
commit
1161216938
@ -30,9 +30,8 @@ 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 {
|
||||
type Kind = #bevy_ecs_path::event::BroadcastEventKind;
|
||||
}
|
||||
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 {}
|
||||
})
|
||||
}
|
||||
|
||||
@ -75,8 +74,10 @@ 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 {
|
||||
type Kind = #bevy_ecs_path::event::EntityEventKind<Self, #traversal, #auto_propagate>;
|
||||
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;
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -95,9 +95,6 @@ use core::{
|
||||
note = "consider annotating `{Self}` with `#[derive(BroadcastEvent)]` or `#[derive(EntityEvent)]`"
|
||||
)]
|
||||
pub trait Event: Send + Sync + 'static {
|
||||
#[doc(hidden)]
|
||||
type Kind;
|
||||
|
||||
/// Generates the [`EventKey`] for this event type.
|
||||
///
|
||||
/// If this type has already been registered,
|
||||
@ -133,32 +130,7 @@ pub trait Event: Send + Sync + 'static {
|
||||
}
|
||||
|
||||
/// A global [`Event`] without an entity target.
|
||||
#[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> {}
|
||||
}
|
||||
pub trait BroadcastEvent: Event {}
|
||||
|
||||
/// An [`Event`] that can be targeted at specific entities.
|
||||
///
|
||||
@ -276,7 +248,7 @@ pub(crate) mod sealed_a {
|
||||
label = "invalid `EntityEvent`",
|
||||
note = "consider annotating `{Self}` with `#[derive(EntityEvent)]`"
|
||||
)]
|
||||
pub trait EntityEvent: Event + sealed_b::SealedB {
|
||||
pub trait EntityEvent: Event {
|
||||
/// The component that describes which [`Entity`] to propagate this event to next, when [propagation] is enabled.
|
||||
///
|
||||
/// [`Entity`]: crate::entity::Entity
|
||||
@ -291,37 +263,6 @@ pub trait EntityEvent: Event + sealed_b::SealedB {
|
||||
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,10 +11,7 @@ mod update;
|
||||
mod writer;
|
||||
|
||||
pub(crate) use base::EventInstance;
|
||||
pub use base::{
|
||||
BroadcastEvent, BroadcastEventKind, BufferedEvent, EntityEvent, EntityEventKind, Event,
|
||||
EventId, EventKey,
|
||||
};
|
||||
pub use base::{BroadcastEvent, BufferedEvent, EntityEvent, 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};
|
||||
|
@ -110,15 +110,19 @@ impl<'w, E: EntityEvent, B: Bundle> On<'w, E, B> {
|
||||
///
|
||||
/// Note that if event propagation is enabled, this may not be the same as the original target of the event,
|
||||
/// which can be accessed via [`On::original_target`].
|
||||
///
|
||||
/// If the event is also a [`BroadcastEvent`] sent with [`trigger`](World::trigger), this will return [`Entity::PLACEHOLDER`].
|
||||
pub fn target(&self) -> Entity {
|
||||
self.trigger.current_target.unwrap()
|
||||
self.trigger.current_target.unwrap_or(Entity::PLACEHOLDER)
|
||||
}
|
||||
|
||||
/// Returns the original [`Entity`] that the [`EntityEvent`] was targeted at when it was first triggered.
|
||||
///
|
||||
/// If event propagation is not enabled, this will always return the same value as [`On::target`].
|
||||
///
|
||||
/// If the event is also a [`BroadcastEvent`] sent with [`trigger`](World::trigger), this will return [`Entity::PLACEHOLDER`].
|
||||
pub fn original_target(&self) -> Entity {
|
||||
self.trigger.original_target.unwrap()
|
||||
self.trigger.original_target.unwrap_or(Entity::PLACEHOLDER)
|
||||
}
|
||||
|
||||
/// Enables or disables event propagation, allowing the same event to trigger observers on a chain of different entities.
|
||||
@ -181,11 +185,13 @@ pub struct ObserverTrigger {
|
||||
pub event_key: EventKey,
|
||||
/// The [`ComponentId`]s the trigger targeted.
|
||||
pub components: SmallVec<[ComponentId; 2]>,
|
||||
/// For [`EntityEvent`]s this is the entity that the event targeted. Always `None` for [`BroadcastEvent`].
|
||||
/// For [`EntityEvent`]s used with `trigger_targets` this is the entity that the event targeted.
|
||||
/// Can only be `None` for [`BroadcastEvent`]s used with `trigger`.
|
||||
///
|
||||
/// Note that if event propagation is enabled, this may not be the same as [`ObserverTrigger::original_target`].
|
||||
pub current_target: Option<Entity>,
|
||||
/// For [`EntityEvent`]s this is the entity that the event was originally targeted at. Always `None` for [`BroadcastEvent`].
|
||||
/// For [`EntityEvent`]s used with `trigger_targets` this is the entity that the event was originally targeted at.
|
||||
/// Can only be `None` for [`BroadcastEvent`]s used with `trigger`.
|
||||
///
|
||||
/// If event propagation is enabled, this will be the first entity that the event was targeted at,
|
||||
/// even if the event was propagated to other entities.
|
||||
|
@ -2,7 +2,7 @@ use crate::{DynamicScene, Scene};
|
||||
use bevy_asset::{AssetEvent, AssetId, Assets, Handle};
|
||||
use bevy_ecs::{
|
||||
entity::{Entity, EntityHashMap},
|
||||
event::{EntityEvent, EventCursor, Events},
|
||||
event::{BroadcastEvent, EntityEvent, EventCursor, Events},
|
||||
hierarchy::ChildOf,
|
||||
reflect::AppTypeRegistry,
|
||||
resource::Resource,
|
||||
@ -34,6 +34,8 @@ pub struct SceneInstanceReady {
|
||||
pub instance_id: InstanceId,
|
||||
}
|
||||
|
||||
impl BroadcastEvent for SceneInstanceReady {}
|
||||
|
||||
/// Information about a scene instance.
|
||||
#[derive(Debug)]
|
||||
pub struct InstanceInfo {
|
||||
@ -421,8 +423,7 @@ impl SceneSpawner {
|
||||
.trigger_targets(SceneInstanceReady { instance_id }, parent);
|
||||
} else {
|
||||
// Defer via commands otherwise SceneSpawner is not available in the observer.
|
||||
// TODO: Thinkies
|
||||
// world.commands().trigger(SceneInstanceReady { instance_id });
|
||||
world.commands().trigger(SceneInstanceReady { instance_id });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ 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 return `Entity::PLACEHOLDER` for events sent via `trigger` rather than `trigger_targets`.
|
||||
- `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`.
|
||||
|
||||
**Bevy 0.17** aims to solve this ambiguity by splitting the different kinds of events into multiple traits:
|
||||
|
||||
@ -34,8 +34,6 @@ This has led to a lot of confusion and frustration for users. Common footguns in
|
||||
- `EntityEvent`: An observer event that targets specific entities and can propagate the event from one entity to another across relationships.
|
||||
- `BufferedEvent`: An event used with `EventReader` and `EventWriter` for pull-based event handling.
|
||||
|
||||
Note: To fully prevent the footgun of `On::target` returning `Entity::PLACEHOLDER` the `BroadcastEvent` and `EntityEvent` traits were made mutually exclusive.
|
||||
|
||||
## Using Events
|
||||
|
||||
Events without an entity target can be defined, by deriving the `BroadcastEvent` trait.
|
||||
|
Loading…
Reference in New Issue
Block a user