Add an example demonstrating callbacks with one-shot systems#23197
Add an example demonstrating callbacks with one-shot systems#23197alice-i-cecile wants to merge 2 commits intobevyengine:mainfrom
Conversation
There was a problem hiding this comment.
Great example!
I don't want to bloat it, but any thoughts on including the other ways of doing this?
eg world.run_system(id) giving you more explicit ordering (because you are now in an exclusive system), or commands.run_system_with(id, input) to allow passing arguments.
I get they may be overkill for this kind of example, but perhaps just the _with variation might be nice to have as I've used that pattern in the past for button callbacks etc (eg passing Entity), and I think feathers uses it now?
| //! Sometimes, you want an extremely flexible way to store logic associated with an entity. | ||
| //! This example demonstrates how to store arbitrary systems in components and run them on demand. | ||
| //! | ||
| //! This pattern will be relatively slow, but it can work well for things like cutscenes, scripted events, |
There was a problem hiding this comment.
Nitpicking :D feel free to ignore
This pattern will be relatively slow
Would personally word it more like this??
This pattern trades some performance for flexibility and works well for things like cutscenes, scripted events,
personally if I see something described as "relatively slow" I assume it's like 10x slower, and a light warning by the developers to not use this if you don't have to. I understand it's actually "somewhat slower relative to scheduled systems", but that nuance might not be understood by someone unfamiliar with bevy ecs.
ChristopherBiscardi
left a comment
There was a problem hiding this comment.
We use "callback" in bevy's internals and it always means impl Fn*, so the usage of it to mean "a SystemId" is a bit awkward and feels like we're constructing, naming, and front-loading a new term that doesn't match prior usage. I probably would've went with something more like "systems ids in components" or one_shot_systems_in_components for discoverability reasons.
That said, I think this is a fine step to show the functionality. It's a good set of functionality to show, and I even just used similar in my jam entry. It duplicates the functionality in the one_shot_systems example but the overhead of maintaining this additional example seems very small so approving anyway in the interest of having more than one example showing this functionality.
I added a few rename suggestions because I think it is important to note that the logs refer to the function names specifically, and that they are actually systems.
| fn setup_callbacks(mut commands: Commands) { | ||
| let trivial_callback = Callback { | ||
| system_id: commands.register_system(|| { | ||
| println!("This is a trivial callback."); |
There was a problem hiding this comment.
| println!("This is a trivial callback."); | |
| println!("This is the trivial callback system"); |
| let ordinary_system_callback = Callback { | ||
| system_id: commands.register_system(|query: Query<&Callback>| { | ||
| let n_callbacks = query.iter().len(); | ||
| println!("This is an ordinary callback. There are currently {n_callbacks} callbacks in the world."); |
There was a problem hiding this comment.
| println!("This is an ordinary callback. There are currently {n_callbacks} callbacks in the world."); | |
| println!("This is the ordinary callback system. There are currently {n_callbacks} callbacks in the world."); |
| let exclusive_callback = Callback { | ||
| system_id: commands.register_system(|world: &mut World| { | ||
| let n_entities = world.entities().len(); | ||
| println!("This is an exclusive callback. There are currently {n_entities} entities in the world."); |
There was a problem hiding this comment.
| println!("This is an exclusive callback. There are currently {n_entities} entities in the world."); | |
| println!("This is the exclusive callback system. There are currently {n_entities} entities in the world."); |
Objective
This is a powerful pattern, but figuring out the exact incantation to call can be quite challenging!
Solution
Write a little prototype, turn it into a full example!
Testing
cargo run --example callbacks