SIGN IN SIGN UP
bevyengine / bevy UNCLAIMED

A refreshingly simple data-driven game engine built in Rust

0 0 59 Rust

`SystemId` scene templating (#24087)

# Objective

- Simplified alternative to #24072

I have a bunch of `Bundle`-style code that I want to replace with the
new `bsn!` Scene-style macro:

```rust
pub fn rest_ui(/* system params */) {
    // my ui system...
}

// From
pub fn rest(mut commands: Commands) -> impl Bundle {
    (
        Rest,
        Name::new("Rest"),
        Activity {
            render: commands.register_system(rest_ui),
        },
    )
}

// To (ideally)
pub fn rest() -> impl Scene {
    bsn! {
        Rest
        Name("Rest")
        Activity {
            render: rest_ui
        }
    }
}
```

## Solution

This solution is more inspired by how `HandleTemplate` works.

1. Added `SystemIdTemplate`; it stores either a `SystemId` or a
`Arc<Mutex<Either<SystemId, Box<dyn System>>>>`
2. Added a `system_value` function for wrapping system functions (see
Future Work for potentially removing the need)

## Testing

- Added a unit test for `SystemIdTemplate`.
- Added to the `callbacks` example demonstrating how to spawn
`SystemId`s via BSN scenes.

## Future work

- I believe we can remove the need for wrapping with `system_value` by
introducing [`SuperFrom`/`SuperInto` traits a la
Dioxus](https://docs.rs/dioxus-core/0.7.6/dioxus_core/trait.SuperFrom.html)
and using it in the `bsn!` macros in-place of the implicit `.into()`s.

---

## Showcase

You can now spawn components containing `SystemId`s via `bsn!` macros:

```rust
#[derive(Component, FromTemplate)]
struct Callback {
    system_id: SystemId<(), ()>,
}

fn my_scene() -> impl Scene {
    bsn! {
        Callback {
            system_id: system_value(|| {
                println!("This is a callback spawned via a scene.");
            })
        }
    }
}
```
C
Christian Hughes committed
f4f9aab0118fe375a4317044843d5948616fff3f
Parent: 8bb980e
Committed by GitHub <noreply@github.com> on 5/31/2026, 9:57:40 PM