#[system]
Expand description
Wraps a function in a system, and generates a new function which constructs that system.
There are three types of systems: simple
(default), for_each
and par_for_each
.
By default, the system macro will create a new function named <attributed_fn_name>_system
which can be called to construct the system.
Examples
By default, the wrapped function is called once each time the system runs.
#[system]
fn hello_world() {
println!("hello world");
}
Schedule::builder()
.add_system(hello_world_system())
.build();
The function can request resources with reference parameters marked with
the #[resource]
attribute.
#[system]
fn hello_world(#[resource] person: &Person) {
println!("hello, {}", person.name);
}
Systems can also request a world or command buffer.
#[system]
fn create_entity(cmd: &mut CommandBuffer) {
cmd.push((1usize, false, Person { name: "Jane Doe" }));
}
Systems can declare access to component types with the #[read_component]
and
#[write_component]
attributes.
#[system]
#[read_component(usize)]
#[write_component(bool)]
fn run_query(world: &mut SubWorld) {
let mut query = <(&usize, &mut bool)>::query();
for (a, b) in query.iter_mut(world) {
println!("{} {}", a, b);
}
}
Systems can declare queries. The above can also be written as:
#[system]
fn run_query(world: &mut SubWorld, query: &mut Query<(&usize, &mut bool)>) {
for (a, b) in query.iter_mut(world) {
println!("{} {}", a, b);
}
}
for_each
and par_for_each
system types can be used to implement the query for you.
References will be interpreted as Read<T>
and Write<T>
, while options of references
(e.g. Option<&Position>
) will be interpreted as TryRead<T>
and TryWrite<T>
. You can
request the entity ID via a &Entity
parameter.
#[system(for_each)]
fn update_positions(pos: &mut Position, vel: &Velocity, #[resource] time: &Time) {
pos.x += vel.x * time.seconds;
}
for_each
and par_for_each
systems can request attitional filters for their query via the
#[filter]
attribute.
#[system(for_each)]
#[filter(maybe_changed::<Position>())]
fn update_positions(pos: &mut Position, vel: &Velocity, #[resource] time: &Time) {
pos.x += vel.x * time.seconds;
}
Systems can contain their own state. Add a reference marked with the #[state]
parameter to
your function. This state will be initialized when you construct the system.
#[system]
fn stateful(#[state] counter: &mut usize) {
*counter += 1;
println!("state: {}", counter);
}
Schedule::builder()
// initialize state when you construct the system
.add_system(stateful_system(5_usize))
.build();
Systems can contain generic parameters.
#[system(for_each)]
fn print_component<T: Component + Debug>(component: &T) {
println!("{:?}", component);
}
Schedule::builder()
// supply generic parameters when constructing the system
.add_system(print_component_system::<Position>())
.build();