Systems

Systems are a great way to organize code.
A function with views as arguments is all you need.

Here's an example:

fn create_ints(mut entities: EntitiesViewMut, mut vm_vel: ViewMut<Vel>) {
    // -- snip --
}

We have a system, let's run it!

let world = World::new();

world.run(create_ints);

It also works with closures, all previous chapters were using systems.

Workloads

A workload is a group of systems.

fn create_ints(mut entities: EntitiesViewMut, mut vm_vel: ViewMut<Vel>) {
    // -- snip --
}

fn delete_ints(mut vm_vel: ViewMut<Vel>) {
    // -- snip --
}

fn int_cycle() -> Workload {
    (create_ints, delete_ints).into_workload()
}

let world = World::new();

world.add_workload(int_cycle);

world.run_workload(int_cycle).unwrap();

They are stored in the World, ready to be run again and again.

Workloads will run their systems first to last and try to run them in parallel when possible. We call this outer-parallelism, you can learn more about it in this chapter.

Workload Nesting

You can also add a workload to another and build your execution logic brick by brick.

#[derive(Component)]
struct Dead<T: 'static + Send + Sync>(core::marker::PhantomData<T>);

fn increment(mut vm_vel: ViewMut<Vel>) {
    for i in (&mut vm_vel).iter() {
        i.0 += 1.0;
    }
}

fn flag_deleted_vel(v_vel: View<Vel>, mut deads: ViewMut<Dead<Vel>>) {
    for (id, i) in v_vel.iter().with_id() {
        if i.0 > 100.0 {
            deads.add_component_unchecked(id, Dead(core::marker::PhantomData));
        }
    }
}

fn clear_deleted_vel(mut all_storages: AllStoragesViewMut) {
    all_storages.delete_any::<SparseSet<Dead<Vel>>>();
}

fn filter_vel() -> Workload {
    (flag_deleted_vel, clear_deleted_vel).into_workload()
}

fn main_loop() -> Workload {
    (increment, filter_vel).into_workload()
}

let world = World::new();

world.add_workload(main_loop);

world.run_workload(main_loop).unwrap();

Congratulations, you made it to the end of the fundamentals!
The next section will explore less universal topics.