Attribute Macro legion::system [−][src]
#[system]
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();