-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
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
Fast and correct one-shot systems with a system registry resource #7999
Conversation
No plugin exists for bevy_ecs, so this was the best place.
Only the commands specific to this system are applied, so we should de-emphasize this choice.
This reverts commit ba66966.
@alice-i-cecile I don't like/understand indexing systems by their sets. I like the idea of moving systems out of schedules and into a centralized system registry, but IMO it should only be possible to run them by type. The use-case of running multiple systems on demand seems better handled by schedules than by this "run in linear registration order". I know that system labels and sets have been merged into a single concept. So I'm not sure what could be an alternative to sets but with a 1-1 relationship with systems. |
Agreed here: we should only accept a
Strongly agreed. |
I'd like to unify the following commands: pub struct RunSystemCommand<...> {
_phantom_marker: PhantomData<M>,
system: S,
}
// formerly RunSystemsBySetCommand
pub struct RunCallback {
pub callback: Callback,
}
I personally favor preregistration for explicitness on the fact that this is being stored and cached. |
use bevy_ecs::system::{Callback, SystemRegistryError}; | ||
|
||
impl App { | ||
/// Register a system with any number of [`SystemLabel`]s. |
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.
SystemLabel should be removed from the docs.
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.
Yes, the docs are not up to date, I want to stabilize some things first :)
@alice-i-cecile I have another question. #4090 stablishes as future work:
Does this still make sense? How would this work with multiple instances of a system inside a world? Should they share change detection or each have their own? |
I don't think that proposal makes sense any more :) Like you said, it doesn't play nice with multiple copies of systems, and we already have schedules for that. |
Yes, sadly I started to feel the same way after thinking about some of the details involved. Even if we renounce to this idea of a global system registry where all systems are stored, we may still want a solution for running systems on demand instead of polling. Kind of like schedules but for single systems. To me it makes sense to call this single-system schedule-like things "Commands", that's what my proposal in #7707 was about. I know that you said that these systems usually don't require exclusive access, but the fact that they are not scheduled is what removes the possibility of parallelization (unless we can think of some cool solution). Just like this system registry solution requires using commands or direct access to the world to run the systems, even for non-exclusive systems. The current commands for entity and component management could be renamed to something like exclusive/direct/world commands. That way we'd have exclusive commands (which wouldn't have the overhead of systems) and system commands (which would have the ergonomics of systems). Edit: Conceptually there would be two ways of running systems of demand, each for a different use-case and with different capabilities:
|
We really can't reuse the name Commands: that's already taken for I agree that we should be able to run systems without pre-registration. I'm currently conflicted between:
The first is more explicit, the second is substantially more ergonomic. |
Sorry for not providing more updates. I was diving deep in Bevy internals but I started on a new position shortly after. I'll try to continue contributing in the future, but right now I don't have the time. |
I'm adopting this ~~child~~ PR. # Objective - Working with exclusive world access is not always easy: in many cases, a standard system or three is more ergonomic to write, and more modularly maintainable. - For small, one-off tasks (commonly handled with scripting), running an event-reader system incurs a small but flat overhead cost and muddies the schedule. - Certain forms of logic (e.g. turn-based games) want very fine-grained linear and/or branching control over logic. - SystemState is not automatically cached, and so performance can suffer and change detection breaks. - Fixes #2192. - Partial workaround for #279. ## Solution - Adds a SystemRegistry resource to the World, which stores initialized systems keyed by their SystemSet. - Allows users to call world.run_system(my_system) and commands.run_system(my_system), without re-initializing or losing state (essential for change detection). - Add a Callback type to enable convenient use of dynamic one shot systems and reduce the mental overhead of working with Box<dyn SystemSet>. - Allow users to run systems based on their SystemSet, enabling more complex user-made abstractions. ## Future work - Parameterized one-shot systems would improve reusability and bring them closer to events and commands. The API could be something like run_system_with_input(my_system, my_input) and use the In SystemParam. - We should evaluate the unification of commands and one-shot systems since they are two different ways to run logic on demand over a World. ### Prior attempts - #2234 - #2417 - #4090 - #7999 This PR continues the work done in #7999. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Federico Rinaldi <gisquerin@gmail.com> Co-authored-by: MinerSebas <66798382+MinerSebas@users.noreply.github.com> Co-authored-by: Aevyrie <aevyrie@gmail.com> Co-authored-by: Alejandro Pascual Pozo <alejandro.pascual.pozo@gmail.com> Co-authored-by: Rob Parrett <robparrett@gmail.com> Co-authored-by: François <mockersf@gmail.com> Co-authored-by: Dmytro Banin <banind@cs.washington.edu> Co-authored-by: James Liu <contact@jamessliu.com>
Merged elsewhere! |
I'm adopting this ~~child~~ PR. # Objective - Working with exclusive world access is not always easy: in many cases, a standard system or three is more ergonomic to write, and more modularly maintainable. - For small, one-off tasks (commonly handled with scripting), running an event-reader system incurs a small but flat overhead cost and muddies the schedule. - Certain forms of logic (e.g. turn-based games) want very fine-grained linear and/or branching control over logic. - SystemState is not automatically cached, and so performance can suffer and change detection breaks. - Fixes bevyengine#2192. - Partial workaround for bevyengine#279. ## Solution - Adds a SystemRegistry resource to the World, which stores initialized systems keyed by their SystemSet. - Allows users to call world.run_system(my_system) and commands.run_system(my_system), without re-initializing or losing state (essential for change detection). - Add a Callback type to enable convenient use of dynamic one shot systems and reduce the mental overhead of working with Box<dyn SystemSet>. - Allow users to run systems based on their SystemSet, enabling more complex user-made abstractions. ## Future work - Parameterized one-shot systems would improve reusability and bring them closer to events and commands. The API could be something like run_system_with_input(my_system, my_input) and use the In SystemParam. - We should evaluate the unification of commands and one-shot systems since they are two different ways to run logic on demand over a World. ### Prior attempts - bevyengine#2234 - bevyengine#2417 - bevyengine#4090 - bevyengine#7999 This PR continues the work done in bevyengine#7999. --------- Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com> Co-authored-by: Federico Rinaldi <gisquerin@gmail.com> Co-authored-by: MinerSebas <66798382+MinerSebas@users.noreply.github.com> Co-authored-by: Aevyrie <aevyrie@gmail.com> Co-authored-by: Alejandro Pascual Pozo <alejandro.pascual.pozo@gmail.com> Co-authored-by: Rob Parrett <robparrett@gmail.com> Co-authored-by: François <mockersf@gmail.com> Co-authored-by: Dmytro Banin <banind@cs.washington.edu> Co-authored-by: James Liu <contact@jamessliu.com>
Objective
SystemState
is not automatically cached, and so performance can suffer and change detection breaks.Solution
SystemRegistry
resource to theWorld
, which stores initialized systems keyed by theirSystemSet
.world.run_system(my_system)
andcommands.run_system(my_system)
, without re-initializing or losing state (essential for change detection).Callback
type to enable convenient use of dynamic one shot systems and reduce the mental overhead of working withBox<dyn SystemSet>
.Allow users to run systems based on theirSystemSet
, enabling more complex user-made abstractions.Status
Future work
run_system_with_input(my_system, my_input)
and use theIn
SystemParam
.World
.Prior attempts
&mut World
#2417This PR continues the work done in #4090.