Struct hecs::World[][src]

pub struct World { /* fields omitted */ }
Expand description

An unordered collection of entities, each having any number of distinctly typed components

Similar to HashMap<Entity, Vec<Box<dyn Any>>> where each Vec never contains two of the same type, but far more efficient to traverse.

The components of entities who have the same set of component types are stored in contiguous runs, allowing for extremely fast, cache-friendly iteration.

There is a maximum number of unique entity IDs, which means that there is a maximum number of live entities. When old entities are despawned, their IDs will be reused on a future entity, and old Entity values with that ID will be invalidated.

Collisions

If an entity is despawned and its Entity handle is preserved over the course of billions of following spawns and despawns, that handle may, in rare circumstances, collide with a newly-allocated Entity handle. Very long-lived applications should therefore limit the period over which they may retain handles of despawned entities.

Implementations

Create an empty world

Create an entity with certain components

Returns the ID of the newly created entity.

Arguments can be tuples, structs annotated with #[derive(Bundle)], or the result of calling build on an EntityBuilder, which is useful if the set of components isn’t statically known. To spawn an entity with only one component, use a one-element tuple like (x,).

Any type that satisfies Send + Sync + 'static can be used as a component.

Example

let mut world = World::new();
let a = world.spawn((123, "abc"));
let b = world.spawn((456, true));

Create an entity with certain components and a specific Entity handle.

See spawn.

Despawns any existing entity with the same Entity::id.

Useful for easy handle-preserving deserialization. Be cautious resurrecting old Entity handles in already-populated worlds as it vastly increases the likelihood of collisions.

Example

let mut world = World::new();
let a = world.spawn((123, "abc"));
let b = world.spawn((456, true));
world.despawn(a);
assert!(!world.contains(a));
// all previous Entity values pointing to 'a' will be live again, instead pointing to the new entity.
world.spawn_at(a, (789, "ABC"));
assert!(world.contains(a));

Efficiently spawn a large number of entities with the same statically-typed components

Faster than calling spawn repeatedly with the same components, but requires that component types are known at compile time.

Example

let mut world = World::new();
let entities = world.spawn_batch((0..1_000).map(|i| (i, "abc"))).collect::<Vec<_>>();
for i in 0..1_000 {
    assert_eq!(*world.get::<i32>(entities[i]).unwrap(), i as i32);
}

Super-efficiently spawn the contents of a ColumnBatch

The fastest, but most specialized, way to spawn large numbers of entities. Useful for high performance deserialization. Supports dynamic component types.

Allocate many entities ID concurrently

Unlike spawn, this can be called simultaneously to other operations on the World such as queries, but does not immediately create the entities. Reserved entities are not visible to queries or world iteration, but can be otherwise operated on freely. Operations that uniquely borrow the world, such as insert or despawn, will cause all outstanding reserved entities to become real entities before proceeding. This can also be done explicitly by calling flush.

Useful for reserving an ID that will later have components attached to it with insert.

Allocate an entity ID concurrently

See reserve_entities.

Destroy an entity and all its components

Ensure at least additional entities with exact components T can be spawned without reallocating

Despawn all entities

Preserves allocated storage for reuse.

Whether entity still exists

Efficiently iterate over all entities that have certain components, using dynamic borrow checking

Prefer query_mut when concurrent access to the World is not required.

Calling iter on the returned value yields (Entity, Q) tuples, where Q is some query type. A query type is &T, &mut T, a tuple of query types, or an Option wrapping a query type, where T is any component type. Components queried with &mut must only appear once. Entities which do not have a component type referenced outside of an Option will be skipped.

Entities are yielded in arbitrary order.

The returned QueryBorrow can be further transformed with combinator methods; see its documentation for details.

Iterating a query will panic if it would violate an existing unique reference or construct an invalid unique reference. This occurs when two simultaneously-active queries could expose the same entity. Simultaneous queries can access the same component type if and only if the world contains no entities that have all components required by both queries, assuming no other component borrows are outstanding.

Iterating a query yields references with lifetimes bound to the QueryBorrow returned here. To ensure those are invalidated, the return value of this method must be dropped for its dynamic borrows from the world to be released. Similarly, lifetime rules ensure that references obtained from a query cannot outlive the QueryBorrow.

Example

let mut world = World::new();
let a = world.spawn((123, true, "abc"));
let b = world.spawn((456, false));
let c = world.spawn((42, "def"));
let entities = world.query::<(&i32, &bool)>()
    .iter()
    .map(|(e, (&i, &b))| (e, i, b)) // Copy out of the world
    .collect::<Vec<_>>();
assert_eq!(entities.len(), 2);
assert!(entities.contains(&(a, 123, true)));
assert!(entities.contains(&(b, 456, false)));

Query a uniquely borrowed world

Like query, but faster because dynamic borrow checks can be skipped. Note that, unlike query, this returns an IntoIterator which can be passed directly to a for loop.

Prepare a query against a single entity, using dynamic borrow checking

Prefer query_one_mut when concurrent access to the World is not required.

Call get on the resulting QueryOne to actually execute the query. The QueryOne value is responsible for releasing the dynamically-checked borrow made by get, so it can’t be dropped while references returned by get are live.

Handy for accessing multiple components simultaneously.

Example

let mut world = World::new();
let a = world.spawn((123, true, "abc"));
// The returned query must outlive the borrow made by `get`
let mut query = world.query_one::<(&mut i32, &bool)>(a).unwrap();
let (number, flag) = query.get().unwrap();
if *flag { *number *= 2; }
assert_eq!(*number, 246);

Query a single entity in a uniquely borrow world

Like query_one, but faster because dynamic borrow checks can be skipped. Note that, unlike query_one, on success this returns the query’s results directly.

Borrow the T component of entity

Panics if the component is already uniquely borrowed from another entity with the same components.

Uniquely borrow the T component of entity

Panics if the component is already borrowed from another entity with the same components.

Access an entity regardless of its component types

Does not immediately borrow any component.

Given an id obtained from Entity::id, reconstruct the still-live Entity.

Safety

id must correspond to a currently live Entity. A despawned or never-allocated id will produce undefined behavior.

Iterate over all entities in the world

Entities are yielded in arbitrary order. Prefer query for better performance when components will be accessed in predictable patterns.

Example

let mut world = World::new();
let a = world.spawn(());
let b = world.spawn(());
let ids = world.iter().map(|entity_ref| entity_ref.entity()).collect::<Vec<_>>();
assert_eq!(ids.len(), 2);
assert!(ids.contains(&a));
assert!(ids.contains(&b));

Add components to entity

Computational cost is proportional to the number of components entity has. If an entity already has a component of a certain type, it is dropped and replaced.

When inserting a single component, see insert_one for convenience.

Example

let mut world = World::new();
let e = world.spawn((123, "abc"));
world.insert(e, (456, true));
assert_eq!(*world.get::<i32>(e).unwrap(), 456);
assert_eq!(*world.get::<bool>(e).unwrap(), true);

Add component to entity

See insert.

Remove components from entity

Computational cost is proportional to the number of components entity has. The entity itself is not removed, even if no components remain; use despawn for that. If any component in T is not present in entity, no components are removed and an error is returned.

When removing a single component, see remove_one for convenience.

Example

let mut world = World::new();
let e = world.spawn((123, "abc", true));
assert_eq!(world.remove::<(i32, &str)>(e), Ok((123, "abc")));
assert!(world.get::<i32>(e).is_err());
assert!(world.get::<&str>(e).is_err());
assert_eq!(*world.get::<bool>(e).unwrap(), true);

Remove the T component from entity

See remove.

Borrow the T component of entity without safety checks

Should only be used as a building block for safe abstractions.

Safety

entity must have been previously obtained from this World, and no unique borrow of the same component of entity may be live simultaneous to the returned reference.

Uniquely borrow the T component of entity without safety checks

Should only be used as a building block for safe abstractions.

Safety

entity must have been previously obtained from this World, and no borrow of the same component of entity may be live simultaneous to the returned reference.

Convert all reserved entities into empty entities that can be iterated and accessed

Invoked implicitly by spawn, despawn, insert, and remove.

Inspect the archetypes that entities are organized into

Useful for dynamically scheduling concurrent queries by checking borrows in advance, and for efficient serialization.

Returns a distinct value after archetypes is changed

Store the current value after deriving information from archetypes, then check whether the value returned by this function differs before attempting an operation that relies on its correctness. Useful for determining whether e.g. a concurrent query execution plan is still correct.

The generation may be, but is not necessarily, changed as a result of adding or removing any entity or component.

Example

let mut world = World::new();
let initial_gen = world.archetypes_generation();
world.spawn((123, "abc"));
assert_ne!(initial_gen, world.archetypes_generation());

Number of currently live entities

Whether no entities are live

Trait Implementations

Returns the “default value” for a type. Read more

Extends a collection with the contents of an iterator. Read more

🔬 This is a nightly-only experimental API. (extend_one)

Extends a collection with exactly one element.

🔬 This is a nightly-only experimental API. (extend_one)

Reserves capacity in a collection for the given number of additional elements. Read more

Creates a value from an iterator. Read more

Which kind of iterator are we turning this into?

The type of the elements being iterated over.

Creates an iterator from a value. 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

Performs the conversion.

Performs the conversion.

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.