Skip to content
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

Closed
wants to merge 12 commits into from

Conversation

JoJoJet
Copy link
Member

@JoJoJet JoJoJet commented Aug 23, 2022

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.

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

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.

@alice-i-cecile alice-i-cecile added A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use labels Aug 23, 2022
@alice-i-cecile
Copy link
Member

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.

@JoJoJet
Copy link
Member Author

JoJoJet commented Aug 23, 2022

It would be helpful if chained systems had a way of accessing the name of the outer ChainSystem, for debug purposes. I'm planning on opening an issue about that.

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,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
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 ChainSystems?

Copy link
Member Author

@JoJoJet JoJoJet Aug 23, 2022

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.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Make sense

crates/bevy_ecs/src/system/system_chaining.rs Outdated Show resolved Hide resolved
crates/bevy_ecs/src/system/system_chaining.rs Outdated Show resolved Hide resolved
/// println!("{x:?}");
/// }
/// ```
pub fn new<T, U>(mut f: impl FnMut(T) -> U) -> impl FnMut(In<T>) -> U {
Copy link
Contributor

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.

Copy link
Member Author

@JoJoJet JoJoJet Aug 26, 2022

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.

Copy link
Contributor

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.

Copy link
Member

@cart cart left a 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.

@cart
Copy link
Member

cart commented Aug 30, 2022

bors r+

bors bot pushed a commit that referenced this pull request Aug 30, 2022
# 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.
@bors bors bot changed the title Add a module for common system chain/pipe adapters [Merged by Bors] - Add a module for common system chain/pipe adapters Aug 30, 2022
@bors bors bot closed this Aug 30, 2022
@JoJoJet JoJoJet deleted the adapters branch August 30, 2022 02:06
james7132 pushed a commit to james7132/bevy that referenced this pull request Oct 28, 2022
# 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.
bors bot pushed a commit that referenced this pull request Dec 11, 2022
# 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``.
alradish pushed a commit to alradish/bevy that referenced this pull request Jan 22, 2023
…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``.
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
# 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.
ItsDoot pushed a commit to ItsDoot/bevy that referenced this pull request Feb 1, 2023
…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``.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-ECS Entities, components, systems, and events C-Usability A targeted quality-of-life change that makes Bevy easier to use
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants