Components

A component represents data which is attached to an entity.

Note: Compared to other Rust ECS implementations, a component is not the same as the underlying type. This allows different components of the same datatype to coexist without having to use newtypes and forward all traits, and implement Into and From implementations.

#![allow(unused)]

fn main() {
    component! {
        /// Represents the position in the world
        position: (f32, f32),
    }

}

This in turn exposes a function that will return the component id, as component ids are lazily allocated due to lack of compile time unique ids.

The component can be added, accessed and removed from entities using World::set, World::get, and World::remove.

#![allow(unused)]
fn main() {
    let id = world.spawn();

    // Add a component to `id`
    world.set(id, position(), (1.0, 4.0))?;

    {
        let val = world.get(id, position())?;

        println!("The entity is at: {val:?}");
    }

    // This will overwrite the previous value
    world.set(id, position(), (1.0, 4.5))?;

    {
        // Mutate the component
        let mut pos = world.get_mut(id, position())?;
        pos.1 += 1.0;
    }

    println!("The entity is now at: {:?}", world.get(id, position())?);

}

Accessing a component mutably does not require a mutable access to the world, as it uses an AtomicRefCell.

Multiple different components can be accessed simultaneously, even on the same entity.

Default components

Flax provides some opinionated default components to ease the communication between different libraries and users.

  • name: Provides a name for entities and components.
  • child_of: Default dataless hierarchy relation. See: Relations