pub struct World {
entities: RefCell<Entities>,
archetypes: Archetypes,
ctors: TypeIdHashMap<fn() -> Box<dyn AnyColumn>>,
names: TypeIdHashMap<&'static str>,
commands: RefCell<VecDeque<Box<dyn Command>>>,
tree: ScopeTree,
borrow: RefCell<BorrowLedger>,
root: Entity,
shared: Entity,
scaffolding: u32,
}Expand description
Entities and their components.
Fields§
§entities: RefCell<Entities>Where each handle lives, and the allocator behind it.
Still a cell: World::reserve_entity hands out a handle through
&World so that Commands::spawn can answer one
before the queue is applied, and a reservation is a real allocation, not
a queued intent. Everything else that touches this table runs under
&mut World, so the two never overlap.
archetypes: Archetypes§ctors: TypeIdHashMap<fn() -> Box<dyn AnyColumn>>Column constructors, one per component type that ever entered the world.
names: TypeIdHashMap<&'static str>The name of every component type that ever entered the world.
commands: RefCell<VecDeque<Box<dyn Command>>>Structural changes waiting for the next World::apply.
A cell for the same reason: a command is queued from a callback that
only holds &World.
tree: ScopeTreeWhere every live entity lives.
Not a cell: every write to it happens under &mut World, and a reader
borrowing it from &World keeps that shared borrow alive, which is what
excludes one. The visibility walk reads it on every row, so the absence of
a runtime flag there is the point.
borrow: RefCell<BorrowLedger>Who holds which component values.
A cell because a claim is registered by a query constructed from &World
and dropped by its holder’s Drop, neither of which has the world
mutably.
root: EntityThe entity that owns the world, whose scope sees everything.
The entity whose subtree every scope sees.
scaffolding: u32The archetype holding the two scaffolding entities.
They are the only entities that exist without being content, so a scope
that counts rows has to know where they are. They take the first
World::SCAFFOLDING_ROWS rows of it.
Implementations§
Source§impl World
impl World
Sourceconst SCAFFOLDING_ROWS: usize = 2
const SCAFFOLDING_ROWS: usize = 2
How many rows the two scaffolding entities take.
World::new pushes both before any caller can spawn, and a removal only
ever moves the last row of an archetype into the hole it leaves, so the
pair stays at the front for the world’s whole life.
Sourcepub fn new() -> Self
pub fn new() -> Self
A world holding its root and shared scope, and nothing else.
Both are ordinary entities: they are addressable, carry components and
can be opened as scopes, and they are what a shared resource hangs from.
Neither is counted, queried, despawned or linked; see Scope::len,
which reports the entities a scope sees with the pair left out.
The entity whose subtree every scope sees.
Whether entity is in the shared subtree, itself included.
Sourcepub fn is_scaffolding(&self, entity: Entity) -> bool
pub fn is_scaffolding(&self, entity: Entity) -> bool
Whether entity is one of the tree’s two scaffolding entities.
This is narrower than World::is_shared, which covers the whole
shared subtree: the entities a caller spawns there are content, and a
scope counts and queries them like any other.
Sourcepub fn is_descendant(&self, ancestor: Entity, entity: Entity) -> bool
pub fn is_descendant(&self, ancestor: Entity, entity: Entity) -> bool
Whether entity is strictly below ancestor in the tree.
Sourcepub fn visible(&self, caller: Entity, candidate: Entity) -> bool
pub fn visible(&self, caller: Entity, candidate: Entity) -> bool
Whether a scope of caller sees candidate.
The shared subtree reaches every scope, the root sees everything, and a scope sees itself and everything below it. A handle that is not alive is visible from nowhere, the root included: seeing a place is not the same as there being something in it.
Sourcepub fn owns(&self, caller: Entity, entity: Entity) -> bool
pub fn owns(&self, caller: Entity, entity: Entity) -> bool
Whether a scope of caller may despawn or relink entity.
Ownership is stricter than visibility: the shared subtree is readable from everywhere but only the root may move or remove it.
Sourcefn check_owns(
&self,
caller: Entity,
entity: Entity,
) -> Result<(), EntityAccessError>
fn check_owns( &self, caller: Entity, entity: Entity, ) -> Result<(), EntityAccessError>
Why a scope of caller may not despawn or relink entity.
The same rule as World::owns, answered with the reason instead of
one bit: an entity outside the subtree is another scope’s to change, and
one in the shared subtree is the root’s alone.
Sourcepub fn parent_scope(&self, entity: Entity) -> Result<Entity, EntityAccessError>
pub fn parent_scope(&self, entity: Entity) -> Result<Entity, EntityAccessError>
The parent of a live entity.
Sourcepub fn children(&self, entity: Entity) -> Result<Vec<Entity>, EntityAccessError>
pub fn children(&self, entity: Entity) -> Result<Vec<Entity>, EntityAccessError>
The direct children of entity.
Answers EntityAccessError::NotAlive for a handle that names no live
entity, which an empty list would otherwise hide.
Sourcepub(crate) fn content_start(&self, archetype: u32) -> usize
pub(crate) fn content_start(&self, archetype: u32) -> usize
The first row of archetype that holds content rather than scaffolding.
This is where a query starts scanning an archetype, and what a count leaves out. It is a row boundary rather than a per-row test so that walking a row costs no identity check: the two roots share their archetype with every entity spawned bare, which would otherwise need one comparison per row.
Sourcepub fn root_scope(&self) -> Scope<'_>
pub fn root_scope(&self) -> Scope<'_>
The scope of the root: everything in the world.
Sourcepub fn root_scope_mut(&mut self) -> ScopeMut<'_>
pub fn root_scope_mut(&mut self) -> ScopeMut<'_>
The mutable scope of the root: everything in the world.
Sourcepub fn scope_mut(
&mut self,
scope: Entity,
) -> Result<ScopeMut<'_>, EntityAccessError>
pub fn scope_mut( &mut self, scope: Entity, ) -> Result<ScopeMut<'_>, EntityAccessError>
The mutable scope of scope.
Sourcepub fn reserve_entity(&self, name: &'static str) -> Entity
pub fn reserve_entity(&self, name: &'static str) -> Entity
A handle to an entity that does not exist yet, named name.
The handle becomes live when a bundle is put on it, either with a
scope’s spawn or by applying a queued crate::Commands::spawn.
Reserving is where the caller says what the entity is, so the bundle
put on it later does not rename it.
Sourcepub fn release_entity(&mut self, entity: Entity) -> bool
pub fn release_entity(&mut self, entity: Entity) -> bool
Release a handle from World::reserve_entity that will never be
spawned.
A reserved handle that is dropped without ever being spawned keeps its
index out of the pool; releasing it puts the index back, so a later
spawn reuses it. Returns whether entity was such a handle.
Sourcepub(crate) fn spawn_in<B: Bundle>(&mut self, scope: Entity, bundle: B) -> Entity
pub(crate) fn spawn_in<B: Bundle>(&mut self, scope: Entity, bundle: B) -> Entity
Spawn bundle in scope.
The entity is named after the bundle: a type of the caller’s own names it
after itself, and a bundle! names it after the source position that
wrote the bundle. A dynamic bundle made by hand carries no name, so an
entity spawned from one has none.
Sourcepub(crate) fn spawn_named_in<B: Bundle>(
&mut self,
scope: Entity,
name: &'static str,
bundle: B,
) -> Entity
pub(crate) fn spawn_named_in<B: Bundle>( &mut self, scope: Entity, name: &'static str, bundle: B, ) -> Entity
Spawn a bundle under name, whatever name the bundle carries.
fn spawn_bundle_in( &mut self, scope: Entity, name: &'static str, bundle: DynamicBundle, ) -> Entity
Sourcepub(crate) fn spawn_at_in<B: Bundle>(
&mut self,
entity: Entity,
scope: Entity,
bundle: B,
) -> Result<(), EntityAccessError>
pub(crate) fn spawn_at_in<B: Bundle>( &mut self, entity: Entity, scope: Entity, bundle: B, ) -> Result<(), EntityAccessError>
Spawn bundle on entity, a handle from World::reserve_entity, in
scope.
Answers EntityAccessError::NotReserved when the handle is not a live
reservation from World::reserve_entity: spawning on a stale or
never-reserved handle would leave a row nobody can reach or free.
Sourcepub(crate) fn despawn_in(
&mut self,
entity: Entity,
caller: Entity,
) -> Result<usize, EntityAccessError>
pub(crate) fn despawn_in( &mut self, entity: Entity, caller: Entity, ) -> Result<usize, EntityAccessError>
Despawn entity and its whole subtree, on behalf of caller.
Children are removed before the parent they lived in, so a child’s despawn callback still sees living ancestors. The answer is how many entities the despawn took with it: the subtree is the scope’s to know about, and a caller that counts what it removed can say so.
Sourcepub(crate) fn link_in(
&mut self,
child: Entity,
parent: Entity,
caller: Entity,
) -> Result<(), EntityAccessError>
pub(crate) fn link_in( &mut self, child: Entity, parent: Entity, caller: Entity, ) -> Result<(), EntityAccessError>
Make child a child of parent on behalf of caller.
Neither end may be a root or the shared scope itself, both must be
alive, and parent may not be inside child’s subtree: moving a scope
into its own descendant would cut the tree in two. The shared subtree is
readable from everywhere but it is the root’s to rearrange, so only a
root caller may move an entity into or out of it.
Sourcepub(crate) fn unlink_in(
&mut self,
child: Entity,
scope: Entity,
caller: Entity,
) -> Result<(), EntityAccessError>
pub(crate) fn unlink_in( &mut self, child: Entity, scope: Entity, caller: Entity, ) -> Result<(), EntityAccessError>
Detach child from its parent and put it in scope, on behalf of
caller.
child may not be the scope itself: that would make it its own parent,
which is how the tree says “this is a root”. Scaffolding does not move,
and only a root caller may take an entity out of the shared subtree.
Sourcefn write_scope(&mut self, entity: Entity, scope: Entity)
fn write_scope(&mut self, entity: Entity, scope: Entity)
Move a live entity into scope and reindex it.
Sourcefn insert_row<B: Bundle>(&mut self, entity: Entity, scope: Entity, bundle: B)
fn insert_row<B: Bundle>(&mut self, entity: Entity, scope: Entity, bundle: B)
Insert a row for entity in scope, made of the components bundle
carries.
Sourcefn remove_entity(&mut self, entity: Entity)
fn remove_entity(&mut self, entity: Entity)
Run the despawn callbacks of entity and drop its row and handle.
Sourcepub(crate) fn finish_spawn(&mut self, entity: Entity)
pub(crate) fn finish_spawn(&mut self, entity: Entity)
Run the spawn callbacks of an entity whose row is already in place.
Sourcefn run_lifecycle<C: 'static + Lifecycle>(&mut self, entity: Entity)
fn run_lifecycle<C: 'static + Lifecycle>(&mut self, entity: Entity)
Run the callback of the lifecycle component C the entity carries.
The scope handed to it is the one the entity lives in, that of its parent: a callback that wants the entity’s own subtree descends into the entity itself.
Sourcefn take_lifecycle<C: 'static + Lifecycle>(
&mut self,
entity: Entity,
) -> Option<LifecycleCallback>
fn take_lifecycle<C: 'static + Lifecycle>( &mut self, entity: Entity, ) -> Option<LifecycleCallback>
Move the callback of the lifecycle component C out of the entity’s row.
Sourcefn restore_lifecycle<C: 'static + Lifecycle>(
&mut self,
entity: Entity,
callback: LifecycleCallback,
)
fn restore_lifecycle<C: 'static + Lifecycle>( &mut self, entity: Entity, callback: LifecycleCallback, )
Put back a callback moved out by the world’s own run of it.
Sourcepub fn type_name(&self, type_id: TypeId) -> Option<&'static str>
pub fn type_name(&self, type_id: TypeId) -> Option<&'static str>
The name of a component type that has entered the world, as
core::any::type_name reported it, or None when no entity has ever
carried it.
Sourcepub fn apply(&mut self) -> Result<(), EntityAccessError>
pub fn apply(&mut self) -> Result<(), EntityAccessError>
Apply every queued command, in order.
Commands queued while applying are applied as well, after the ones already in the queue. A command that fails does not stop the ones after it: the queue is drained either way, and the caller is answered with the first error.
pub(crate) fn entities_read(&self) -> Ref<'_, Entities>
pub(crate) fn entities_write(&self) -> RefMut<'_, Entities>
fn tree_mut(&mut self) -> &mut ScopeTree
pub(crate) fn commands_write(&self) -> RefMut<'_, VecDeque<Box<dyn Command>>>
Sourcepub(crate) fn push_command(&self, command: Box<dyn Command>)
pub(crate) fn push_command(&self, command: Box<dyn Command>)
Append a command to the deferred queue.
Sourcepub(crate) fn claim(
&self,
group: u64,
type_id: TypeId,
name: &'static str,
mode: Mode,
rows: Rows,
origin: &'static Location<'static>,
)
pub(crate) fn claim( &self, group: u64, type_id: TypeId, name: &'static str, mode: Mode, rows: Rows, origin: &'static Location<'static>, )
Register a claim on one component type for one holder.
Panics when a claim already held for the same type clashes with it. See
crate::borrow for what clashes.
Sourcepub(crate) fn next_group(&self) -> u64
pub(crate) fn next_group(&self) -> u64
The id the next holder files its claims under.
fn borrow_write(&self) -> RefMut<'_, BorrowLedger>
Sourcefn archetype_for_components(&mut self, components: &[BundleComponent]) -> u32
fn archetype_for_components(&mut self, components: &[BundleComponent]) -> u32
The archetype with exactly the types of components, creating it when
it is new. Every type must have a registered column constructor.
A hit allocates nothing: the types are hashed as the components are walked and compared in place, so the type sequence is only materialised when a new archetype has to be registered.
Sourcepub(crate) fn location(
&self,
entity: Entity,
) -> Result<Location, EntityAccessError>
pub(crate) fn location( &self, entity: Entity, ) -> Result<Location, EntityAccessError>
Where a live entity’s components live.
Sourcepub fn entity_name(
&self,
entity: Entity,
) -> Result<&'static str, EntityAccessError>
pub fn entity_name( &self, entity: Entity, ) -> Result<&'static str, EntityAccessError>
What a live entity is called, read from the row that stores it.
This is the only durable copy of the label: the allocator keeps no name, and a handle rebuilt from bare bits carries none.
Sourcepub fn archetypes(&self) -> &Archetypes
pub fn archetypes(&self) -> &Archetypes
The archetypes, including the empty one.
This is the storage itself, not a view of one scope: it holds every row
of every scope. Reading it through a Scope is what filters by
visibility.
Sourcepub(crate) fn remove_row(&mut self, location: Location)
pub(crate) fn remove_row(&mut self, location: Location)
Drop the row at location, keeping every other location correct.
pub(crate) fn free_entity(&mut self, entity: Entity) -> bool
Trait Implementations§
Source§impl Debug for World
impl Debug for World
Source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
Reports the tree’s roots and the archetype pool, not the entities.
The entity table, the borrow ledger and the command queue live in cells, and a debug print is most likely to run while one of them is already borrowed. Borrowing them here would panic inside the panic message that is being built, so they are left out rather than read on a best effort.