-
-
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
[Merged by Bors] - Add a module for common system chain
/pipe
adapters
#5776
Conversation
I'd love to see info / debug / warn / error adaptors for Result return types too :) Doesn't have to be in this PR, but it seems like a nice fit. |
It would be helpful if chained systems had a way of accessing the name of the outer |
Commands, In, IntoChainSystem, IntoExclusiveSystem, IntoSystem, Local, NonSend, | ||
NonSendMut, ParallelCommands, ParamSet, Query, RemovedComponents, Res, ResMut, | ||
Resource, System, SystemParamFunction, | ||
adapter as system_adapter, Commands, In, IntoChainSystem, IntoExclusiveSystem, |
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.
adapter as system_adapter, Commands, In, IntoChainSystem, IntoExclusiveSystem, | |
adapter as chain_adapter, Commands, In, IntoChainSystem, IntoExclusiveSystem, |
Wouldn't it be better to use chain_adapter
as those adapters can only be used on ChainSystem
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.
The current plan is to rename .chain()
to .pipe()
, so I'd rather not give it a name that we'd have to change later.
Also, system_adapter
feels more consistent to me. The two ways of accessing this module are bevy::ecs::system::adapter
and bevy::prelude::system_adapter
. Like how bevy_ecs
and bevy::ecs
mean the same thing.
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.
Make sense
Co-authored-by: Afonso Lage <lage.afonso@gmail.com>
/// println!("{x:?}"); | ||
/// } | ||
/// ``` | ||
pub fn new<T, U>(mut f: impl FnMut(T) -> U) -> impl FnMut(In<T>) -> U { |
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.
IMHO new
may be confusing. In rust new
is generally used to create an object.
Since this is a mapping operation, I think map
would fit better.
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 respectfully disagree. The meaning behind the name system_adapter::new
is "create a new system adapter from some fn", which should be clear enough IMO. And the resulting system adapter is an object, of course.
I don't think it makes sense to call it map
, since the mapping is semantically being done by the .chain()
call.
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 didn't take into consideration the mod name. It makes sense.
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'm happy with where this is at. Definitely worth following up with tracing adapters, but those can wait.
bors r+ |
# Objective Right now, users have to implement basic system adapters such as `Option` <-> `Result` conversions by themselves. This is slightly annoying and discourages the use of system chaining. ## Solution Add the module `system_adapter` to the prelude, which contains a collection of common adapters. This is very ergonomic in practice. ## Examples Convenient early returning. ```rust use bevy::prelude::*; App::new() // If the system fails, just try again next frame. .add_system(pet_dog.chain(system_adapter::ignore)) .run(); #[derive(Component)] struct Dog; fn pet_dog(dogs: Query<(&Name, Option<&Parent>), With<Dog>>) -> Option<()> { let (dog, dad) = dogs.iter().next()?; println!("You pet {dog}. He/she/they are a good boy/girl/pupper."); let (dad, _) = dogs.get(dad?.get()).ok()?; println!("Their dad's name is {dad}"); Some(()) } ``` Converting the output of a system ```rust use bevy::prelude::*; App::new() .add_system( find_name .chain(system_adapter::new(String::from)) .chain(spawn_with_name), ) .run(); fn find_name() -> &'static str { /* ... */ } fn spawn_with_name(In(name): In<String>, mut commands: Commands) { commands.spawn().insert(Name::new(name)); } ``` --- ## Changelog * Added the module `bevy_ecs::prelude::system_adapter`, which contains a collection of common system chaining adapters. * `new` - Converts a regular fn to a system adapter. * `unwrap` - Similar to `Result::unwrap` * `ignore` - Discards the output of the previous system.
Pull request successfully merged into main. Build succeeded: |
chain
/pipe
adapterschain
/pipe
adapters
# Objective Right now, users have to implement basic system adapters such as `Option` <-> `Result` conversions by themselves. This is slightly annoying and discourages the use of system chaining. ## Solution Add the module `system_adapter` to the prelude, which contains a collection of common adapters. This is very ergonomic in practice. ## Examples Convenient early returning. ```rust use bevy::prelude::*; App::new() // If the system fails, just try again next frame. .add_system(pet_dog.chain(system_adapter::ignore)) .run(); #[derive(Component)] struct Dog; fn pet_dog(dogs: Query<(&Name, Option<&Parent>), With<Dog>>) -> Option<()> { let (dog, dad) = dogs.iter().next()?; println!("You pet {dog}. He/she/they are a good boy/girl/pupper."); let (dad, _) = dogs.get(dad?.get()).ok()?; println!("Their dad's name is {dad}"); Some(()) } ``` Converting the output of a system ```rust use bevy::prelude::*; App::new() .add_system( find_name .chain(system_adapter::new(String::from)) .chain(spawn_with_name), ) .run(); fn find_name() -> &'static str { /* ... */ } fn spawn_with_name(In(name): In<String>, mut commands: Commands) { commands.spawn().insert(Name::new(name)); } ``` --- ## Changelog * Added the module `bevy_ecs::prelude::system_adapter`, which contains a collection of common system chaining adapters. * `new` - Converts a regular fn to a system adapter. * `unwrap` - Similar to `Result::unwrap` * `ignore` - Discards the output of the previous system.
# Objective Fixes #6224, add ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to expand #5776, which call the corresponding re-exported [bevy_log macros](https://docs.rs/bevy/latest/bevy/log/macro.info.html) when the result is an error. ## Solution * Added ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to ``system_piping.rs``. * Modified and added tests for these under examples in ``system_piping.rs``.
…gine#6751) # Objective Fixes bevyengine#6224, add ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to expand bevyengine#5776, which call the corresponding re-exported [bevy_log macros](https://docs.rs/bevy/latest/bevy/log/macro.info.html) when the result is an error. ## Solution * Added ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to ``system_piping.rs``. * Modified and added tests for these under examples in ``system_piping.rs``.
# Objective Right now, users have to implement basic system adapters such as `Option` <-> `Result` conversions by themselves. This is slightly annoying and discourages the use of system chaining. ## Solution Add the module `system_adapter` to the prelude, which contains a collection of common adapters. This is very ergonomic in practice. ## Examples Convenient early returning. ```rust use bevy::prelude::*; App::new() // If the system fails, just try again next frame. .add_system(pet_dog.chain(system_adapter::ignore)) .run(); #[derive(Component)] struct Dog; fn pet_dog(dogs: Query<(&Name, Option<&Parent>), With<Dog>>) -> Option<()> { let (dog, dad) = dogs.iter().next()?; println!("You pet {dog}. He/she/they are a good boy/girl/pupper."); let (dad, _) = dogs.get(dad?.get()).ok()?; println!("Their dad's name is {dad}"); Some(()) } ``` Converting the output of a system ```rust use bevy::prelude::*; App::new() .add_system( find_name .chain(system_adapter::new(String::from)) .chain(spawn_with_name), ) .run(); fn find_name() -> &'static str { /* ... */ } fn spawn_with_name(In(name): In<String>, mut commands: Commands) { commands.spawn().insert(Name::new(name)); } ``` --- ## Changelog * Added the module `bevy_ecs::prelude::system_adapter`, which contains a collection of common system chaining adapters. * `new` - Converts a regular fn to a system adapter. * `unwrap` - Similar to `Result::unwrap` * `ignore` - Discards the output of the previous system.
…gine#6751) # Objective Fixes bevyengine#6224, add ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to expand bevyengine#5776, which call the corresponding re-exported [bevy_log macros](https://docs.rs/bevy/latest/bevy/log/macro.info.html) when the result is an error. ## Solution * Added ``dbg``, ``info``, ``warn`` and ``error`` system piping adapter variants to ``system_piping.rs``. * Modified and added tests for these under examples in ``system_piping.rs``.
Objective
Right now, users have to implement basic system adapters such as
Option
<->Result
conversions by themselves. This is slightly annoying and discourages the use of system chaining.Solution
Add the module
system_adapter
to the prelude, which contains a collection of common adapters. This is very ergonomic in practice.Examples
Convenient early returning.
Converting the output of a system
Changelog
bevy_ecs::prelude::system_adapter
, which contains a collection of common system chaining adapters.new
- Converts a regular fn to a system adapter.unwrap
- Similar toResult::unwrap
ignore
- Discards the output of the previous system.