-
-
Notifications
You must be signed in to change notification settings - Fork 4k
Owned callbacks. #20041
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Owned callbacks. #20041
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could this support an API where the component boxes the system (or something like that) and then automatically registers it with an on_insert
hook?
There's been some discussion on this: basically adding a different variant of I think we need both types of callbacks: ones that can be passed around from template to template as parameters, and ones that can be defined at the point of use. |
self.commands() | ||
.spawn((OwnedCallbackSystem(system_id), crate::owner::OwnedBy(owner))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Registered systems are entities themselves, so you might be able to skip having an extra entity by doing something like:
self.commands() | |
.spawn((OwnedCallbackSystem(system_id), crate::owner::OwnedBy(owner))); | |
self.commands() | |
.entity(system_id.entity()) | |
.insert(crate::owner::OwnedBy(owner)); |
I haven't thought through all the consequences of that, but thought it might be worth mentioning!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I much prefer that design.
I'm not convinced this is the right direction. If we're going to use one-shot systems, we should be leaning on the cached, persistent nature of them for deduplication across multiple buttons that do the same or related things. If we're worried about cleanup, the simpler solution is to just store a closure on the widgets. |
A simple closure isn't going to get you dependency injection, and this is critical. One of the pain points I discovered working with Quill is dealing with closure captures: having to constantly clone stuff and make dummy variables to satisfy the borrow checker. Once we introduced one-shot systems, I hit on a different strategy: replacing captured values with dependency-injected values. One substitutes for the other. For example, say we have a widget with a callback, such that the callback wants to know certain things about the widget - like whether it's checked, focused, disabled, and so on. We can do this in a couple of ways:
Using cached systems could work, if we could come up with a solution to the type-erasure problem. That's what #19847 is about - introducing some kind of dyn trait whose impl is able to internally know the concrete type of the callback and which can be shared between multiple call sites. |
Defines a mechanism for registering callbacks which automatically unregisters the system when the parent entity is despawned.