Description
What problem does this solve or what need does it fill?
Currently ways of running systems from other systems are very limited. This proposal aims to provide a way to easily run system as a SystemParam
What solution would you like?
Add a SystemParam
- SystemRunner<T: System + FromWorld>
#[derive(Default)]
struct MySystem;
impl System for MySystem {
In = In<i32>;
Out = String;
//...
}
fn running_my_system(mut runner: SystemRunner<MySystem>) {
let output = runner.run(50);
info!("Output of MySystem: {output}");
}
Unergonomic System
implementation
To use this param, user would have to explicitly specify the type of the system they will use. Implementing System
trait on it's own is hard - unsafe code is not something users want to deal with. FunctionSystem
s are the main way people are used to working with the bevy systems, but they don't implement FromWorld
, and even if it did, you would have to either specify the marker or box every system.
So, it would be nice to have a macro that labels a function system with a specified type name.
#[system(MySystem)]
pub fn my_system(query: Query<&mut MyComponent>, resourse: Res<MyRes>) -> i32 {
//...
}
expands to
pub struct MySystem(SystemState<(Query<'static, 'static, &'static mut MyComponent>, Res<'static, MyRes>)>);
impl FromWorld for MySystem {
fn from_world(world: &mut World) -> Self {
MySystem(SystemState::new(world))
}
}
impl System for MySystem {
//... Basically the same as FunctionSystem implementation
}
Needed controversial change
There is a conflict between System::update_archetype_component_access
and SystemParam::new_archetype
. You can't call update_archetype_component_access
from new_archetype
. Without that you wouldn't be able to call update_archetype_component_access
on an inner system and simultaneously have access rights to run the system.
We can add a new_archetype
method to System
trait or update_archetype_component_access
to SystemParam
trait. We can pass UnsafeWorldCell
to the new_archetype
.
The best option in my opinion - add a new_archetype
method to the System
trait. There will be system-specific code for updating access. update_archetype_component_access
will have a default implementation common for all systems. It will be basically the same as the current FunctionSystem
's implementation. Systems would also need a method that exposes system's archetype generation for update_archetype_component_access
to have default implementation. Method that exposes archetype generation should be fallible so that ZST systems can say that they don't need to update archetype access.