`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