Struct specs::world::World

source ·
pub struct World {
    pub res: Resources,
}
Expand description

The World struct contains the component storages and other resources.

Many methods take &self which works because everything is stored with interior mutability. In case you violate the borrowing rules of Rust (multiple reads xor one write), you will get a panic.

Examples

use specs::prelude::*;

let mut world = World::new();
world.register::<Pos>();
world.register::<Vel>();

world.add_resource(DeltaTime(0.02));

world
    .create_entity()
    .with(Pos { x: 1.0, y: 2.0 })
    .with(Vel { x: -1.0, y: 0.0 })
    .build();

let b = world
    .create_entity()
    .with(Pos { x: 3.0, y: 5.0 })
    .with(Vel { x: 1.0, y: 0.0 })
    .build();

let c = world
    .create_entity()
    .with(Pos { x: 0.0, y: 1.0 })
    .with(Vel { x: 0.0, y: 1.0 })
    .build();

{
    // `World::read_storage` returns a component storage.
    let pos_storage = world.read_storage::<Pos>();
    let vel_storage = world.read_storage::<Vel>();

    // `Storage::get` allows to get a component from it:
    assert_eq!(pos_storage.get(b), Some(&Pos { x: 3.0, y: 5.0 }));
    assert_eq!(vel_storage.get(c), Some(&Vel { x: 0.0, y: 1.0 }));
}

let empty = world.create_entity().build();

{
    // This time, we write to the `Pos` storage:
    let mut pos_storage = world.write_storage::<Pos>();
    let vel_storage = world.read_storage::<Vel>();

    assert!(pos_storage.get(empty).is_none());

    // You can also insert components after creating the entity:
    pos_storage.insert(empty, Pos { x: 3.1, y: 4.15 });

    assert!(pos_storage.get(empty).is_some());
}

Fields

res: Resources

The resources used for this world.

Implementations

Creates a new empty World.

Registers a new component, adding the component storage.

Calls register_with_storage with Default::default().

Does nothing if the component was already registered.

Examples
use specs::prelude::*;

struct Pos {
    x: f32,
    y: f32,
}

impl Component for Pos {
    type Storage = DenseVecStorage<Self>;
}

let mut world = World::new();
world.register::<Pos>();
// Register all other components like this

Registers a new component with a given storage.

Does nothing if the component was already registered.

Gets SystemData T from the World.

Examples

let mut world = World::new();
world.register::<Pos>();
world.register::<Vel>();
let storages: (WriteStorage<Pos>, ReadStorage<Vel>) = world.system_data();
Panics
  • Panics if T is already borrowed in an incompatible way.

Sets up system data T for fetching afterwards.

Executes f once, right now with the specified system data.

This sets up the system data f expects, fetches it and then executes f. You can see this like a system that only runs once.

This is especially useful if you either need a lot of system data or you want to build an entity and for that you need to access resources first

  • just fetching the resources and building the entity would cause a double borrow.

Calling this method is equivalent to:

{ // note the extra scope
    world.setup::<MySystemData>();
    let my_data: MySystemData = world.system_data();
    my_data.do_something();
}
Examples
let mut world = World::new();

struct MyComp;

impl Component for MyComp {
    type Storage = DenseVecStorage<Self>;
}

#[derive(Default)]
struct MyRes {
    field: i32,
}

world.exec(|(mut my_res,): (Write<MyRes>,)| {
    assert_eq!(my_res.field, 0);
    my_res.field = 5;
});

assert_eq!(world.read_resource::<MyRes>().field, 5);

Adds a resource to the world.

If the resource already exists it will be overwritten.

Difference between resources and components

While components exist per entity, resources are like globals in the World. Components are stored in component storages, which are resources themselves.

Everything that is Any + Send + Sync can be a resource.

Built-in resources

There are two built-in resources:

  • LazyUpdate and
  • EntitiesRes

Both of them should only be fetched immutably, which is why the latter one has a type def for convenience: Entities which is just Fetch<EntitiesRes>. Both resources are special and need to execute code at the end of the frame, which is done in World::maintain.

Examples
use specs::prelude::*;

let mut world = World::new();
world.add_resource(timer);
world.add_resource(server_con);

Fetches a component’s storage for reading.

Panics

Panics if it is already borrowed mutably. Panics if the component has not been registered.

Fetches a component’s storage for writing.

Panics

Panics if it is already borrowed (either immutably or mutably). Panics if the component has not been registered.

Fetches a resource for reading.

Panics

Panics if it is already borrowed mutably. Panics if the resource has not been added.

Fetches a resource for writing.

Panics

Panics if it is already borrowed. Panics if the resource has not been added.

Convenience method for fetching entities.

Creation and deletion of entities with the Entities struct are atomically, so the actual changes will be applied with the next call to maintain().

Allows building an entity with its components.

This takes a mutable reference to the World, since no component storage this builder accesses may be borrowed. If it’s necessary that you borrow a resource from the World while this builder is alive, you can use create_entity_unchecked.

Allows building an entity with its components.

You have to make sure that no component storage is borrowed during the building!

This variant is only recommended if you need to borrow a resource during the entity building. If possible, try to use create_entity.

Returns an iterator for entity creation. This makes it easy to create a whole collection of them.

Examples
use specs::prelude::*;

let mut world = World::new();
let five_entities: Vec<_> = world.create_iter().take(5).collect();

Deletes an entity and its components.

Deletes the specified entities and their components.

Deletes all entities and their components.

Checks if an entity is alive. Please note that atomically created or deleted entities (the ones created / deleted with the Entities struct) are not handled by this method. Therefore, you should have called maintain() before using this method.

If you want to get this functionality before a maintain(), you are most likely in a system; from there, just access the Entities resource and call the is_alive method.

Panics

Panics if generation is dead.

Merges in the appendix, recording all the dynamically created and deleted entities into the persistent generations vector. Also removes all the abandoned components.

Additionally, LazyUpdate will be merged.

Trait Implementations

Immutably borrows from an owned value. Read more
Associated storage type for this component.
Returns the “default value” for a type. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

The alignment of pointer.
The type for initializers.
Initializes a with the given initializer. Read more
Dereferences the given pointer. Read more
Mutably dereferences the given pointer. Read more
Drops the object pointed to by the given pointer. Read more
Tries to create the default.
Calls try_default and panics on an error case.
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.