Make events no longer components#17317
Make events no longer components#17317SpecificProtagonist wants to merge 2 commits intobevyengine:mainfrom
Conversation
This will break observers for dynamic components. I don't like |
Sorry for the misunderstanding: I meant observers use of (I assume the Contentious is because of this, I'll re-add it otherwise) |
alice-i-cecile
left a comment
There was a problem hiding this comment.
Ah, I see. This may cause us pain if we try to introduce dynamic events in the future, but the clarity gains are worth it to me.
|
I don't like this because of the affect it has on dynamic event types. In my opinion all data types in the ECS should be referred to by component IDs (and in future entity IDs) to maximize flexibility and code re-use. How would someone define an event type in a script and register an observer for it? That being said if short-term conceptual clarity is the priority this change is fine, it's just a step back in my mind. |
|
I don't think any part of this was ever confusing to begin with. This just breaks a nice dogfood. |
As a new user, you go and look up the I don't mind using I would prefer to rename |
No that's correct? They only reason they're "special" is because of |
|
This is part of the problem of lumping |
|
Would it help to have a wrapper component like #[derive(Component)]
#[repr(transparent)]
struct EventComponent<T: Event>(T);? Then you could easily get a |
|
That would be better. I'm still not For this PR though, I think we should: a) remove To do that, we should merge |
…Component (#17380) # Objective As raised in #17317, the `Event: Component` trait bound is confusing to users. In general, a type `E` (like `AppExit`) which implements `Event` should not: - be stored as a component on an entity - be a valid option for `Query<&AppExit>` - require the storage type and other component metadata to be specified Events are not components (even if they one day use some of the same internal mechanisms), and this trait bound is confusing to users. We're also automatically generating `Component` impls with our derive macro, which should be avoided when possible to improve explicitness and avoid conflicts with user impls. Closes #17317, closes #17333 ## Solution - We only care that each unique event type gets a unique `ComponentId` - dynamic events need their own tools for getting identifiers anyways - This avoids complicating the internals of `ComponentId` generation. - Clearly document why this cludge-y solution exists. In the medium term, I think that either a) properly generalizing `ComponentId` (and moving it into `bevy_reflect?) or b) using a new-typed `Entity` as the key for events is more correct. This change is stupid simple though, and removes the offending trait bound in a way that doesn't introduce complex tech debt and does not risk changes to the internals. This change does not: - restrict our ability to implement dynamic buffered events (the main improvement over #17317) - there's still a fair bit of work to do, but this is a step in the right direction - limit our ability to store event metadata on entities in the future - make it harder for users to work with types that are both events and components (just add the derive / trait bound) ## Migration Guide The `Event` trait no longer requires the `Component` trait. If you were relying on this behavior, change your trait bounds from `Event` to `Event + Component`. If you also want your `Event` type to implement `Component`, add a derive. --------- Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
…Component (bevyengine#17380) # Objective As raised in bevyengine#17317, the `Event: Component` trait bound is confusing to users. In general, a type `E` (like `AppExit`) which implements `Event` should not: - be stored as a component on an entity - be a valid option for `Query<&AppExit>` - require the storage type and other component metadata to be specified Events are not components (even if they one day use some of the same internal mechanisms), and this trait bound is confusing to users. We're also automatically generating `Component` impls with our derive macro, which should be avoided when possible to improve explicitness and avoid conflicts with user impls. Closes bevyengine#17317, closes bevyengine#17333 ## Solution - We only care that each unique event type gets a unique `ComponentId` - dynamic events need their own tools for getting identifiers anyways - This avoids complicating the internals of `ComponentId` generation. - Clearly document why this cludge-y solution exists. In the medium term, I think that either a) properly generalizing `ComponentId` (and moving it into `bevy_reflect?) or b) using a new-typed `Entity` as the key for events is more correct. This change is stupid simple though, and removes the offending trait bound in a way that doesn't introduce complex tech debt and does not risk changes to the internals. This change does not: - restrict our ability to implement dynamic buffered events (the main improvement over bevyengine#17317) - there's still a fair bit of work to do, but this is a step in the right direction - limit our ability to store event metadata on entities in the future - make it harder for users to work with types that are both events and components (just add the derive / trait bound) ## Migration Guide The `Event` trait no longer requires the `Component` trait. If you were relying on this behavior, change your trait bounds from `Event` to `Event + Component`. If you also want your `Event` type to implement `Component`, add a derive. --------- Co-authored-by: Chris Russell <8494645+chescock@users.noreply.github.com>
Objective
Events are components, but are not intended to be used as components. Fix this.
Solution
Make events no longer components. Use
TypeIdinstead ofComponentIdfor identifying event types in observers.Is there a reason (such as planned changes) that
ComponentIds were used (in which case this PR can be closed / reworked)?Benchmarks
Alternatives
Add a
HasComponentIdtraitMigration Guide
The
Eventtrait no longer requires theComponenttrait. If you were relying on this behavior, change your trait bounds fromEventtoEvent + Component. If you also want yourEventtype to implementComponent, add a derive.