Type Alias specs::storage::ReadStorage
source · pub type ReadStorage<'a, T> = Storage<'a, T, Fetch<'a, MaskedStorage<T>>>;
Expand description
A storage with read access.
This is just a type alias for a fetched component storage.
The main functionality it provides is listed in the following,
however make sure to also check out the documentation for the
respective methods on Storage
.
Aliasing
It is strictly disallowed to get both a ReadStorage
and a WriteStorage
of the same component.
Because Specs uses interior mutability for its resources, we can’t check
this at compile time. If you try to do this, you will get a panic.
It is explicitly allowed to get multiple ReadStorage
s for the same
component.
Joining storages
&ReadStorage
implements Join
, which allows to do
something like this:
use specs::prelude::*;
struct Pos;
impl Component for Pos {
type Storage = VecStorage<Self>;
}
struct Vel;
impl Component for Vel {
type Storage = VecStorage<Self>;
}
let mut world = World::new();
world.register::<Pos>();
world.register::<Vel>();
let pos_storage = world.read_storage::<Pos>();
let vel_storage = world.read_storage::<Vel>();
for (pos, vel) in (&pos_storage, &vel_storage).join() {}
This joins the position and the velocity storage, which means it only iterates over the components of entities that have both a position and a velocity.
Retrieving single components
If you have an entity (for example because you stored it before
or because you’re joining over Entities
), you can get a single
component by calling Storage::get
:
let entity1 = world.create_entity().with(Pos).build();
let entity2 = world.create_entity().with(Vel).build();
assert_eq!(pos_storage.get(entity1), Some(&Pos));
assert_eq!(pos_storage.get(entity2), None);
assert_eq!(vel_storage.get(entity1), None);
assert_eq!(vel_storage.get(entity2), Some(&Vel));
Usage as SystemData
ReadStorage
implements SystemData
which allows you to
get it inside a system by simply adding it to the tuple:
#[derive(Debug)]
struct Pos {
x: f32,
y: f32,
}
impl Component for Pos {
type Storage = VecStorage<Self>;
}
struct Sys;
impl<'a> System<'a> for Sys {
type SystemData = (Entities<'a>, ReadStorage<'a, Pos>);
fn run(&mut self, (ent, pos): Self::SystemData) {
for (ent, pos) in (&*ent, &pos).join() {
println!("Entitiy with id {} has a position of {:?}", ent.id(), pos);
}
}
}
These operations can’t mutate anything; if you want to do
insertions or modify components, you need to use WriteStorage
.
Note that you can also use LazyUpdate
, which does insertions on
World::maintain
. This allows more concurrency and is designed
to be used for entity initialization.
Aliased Type§
struct ReadStorage<'a, T> { /* private fields */ }
Implementations§
source§impl<'e, T, D> Storage<'e, T, D>where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
impl<'e, T, D> Storage<'e, T, D>where T: Component, D: DerefMut<Target = MaskedStorage<T>>,
sourcepub fn entry<'a>(
&'a mut self,
e: Entity
) -> Result<StorageEntry<'a, 'e, T, D>, WrongGeneration>where
'e: 'a,
pub fn entry<'a>( &'a mut self, e: Entity ) -> Result<StorageEntry<'a, 'e, T, D>, WrongGeneration>where 'e: 'a,
Returns an entry to the component associated to the entity.
Behaves somewhat similarly to std::collections::HashMap
’s entry api.
Example
if let Ok(entry) = storage.entry(entity) {
entry.or_insert(Comp { field: 55 });
}
sourcepub fn entries<'a>(&'a mut self) -> Entries<'a, 'e, T, D>
pub fn entries<'a>(&'a mut self) -> Entries<'a, 'e, T, D>
Returns a LendJoin
-able structure that yields all indices, returning
StorageEntry
for all elements
WARNING: Do not have a join of only Entries
s. Otherwise the join will
iterate over every single index of the bitset. If you want a join with
all Entries
s, add an EntitiesRes
to the join as well to bound the
join to all entities that are alive.
Example
let mut join = (counters.entries(), &marker).lend_join();
while let Some((mut counter, _)) = join.next() {
let counter = counter.or_insert_with(Default::default);
counter.increase();
if counter.reached_limit() {
counter.reset();
// Do something
}
}
sourcepub fn entry_inner<'a>(&'a mut self, id: Index) -> StorageEntry<'a, 'e, T, D>
pub fn entry_inner<'a>(&'a mut self, id: Index) -> StorageEntry<'a, 'e, T, D>
Returns an entry to the component associated with the provided index.
Does not check whether an entity is alive!
source§impl<T, D> Storage<'_, T, D>where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
impl<T, D> Storage<'_, T, D>where T: Component, D: Deref<Target = MaskedStorage<T>>,
sourcepub fn restrict<'rf>(&'rf self) -> RestrictedStorage<'rf, T, &T::Storage>
pub fn restrict<'rf>(&'rf self) -> RestrictedStorage<'rf, T, &T::Storage>
Builds an immutable RestrictedStorage
out of a Storage
. Allows
deferred unchecked access to the entity’s component.
This is returned as a ParallelRestriction
version since you can only
get immutable components with this which is safe for parallel by
default.
source§impl<T, D> Storage<'_, T, D>where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
impl<T, D> Storage<'_, T, D>where T: Component, D: DerefMut<Target = MaskedStorage<T>>,
sourcepub fn restrict_mut<'rf>(
&'rf mut self
) -> RestrictedStorage<'rf, T, &mut T::Storage>
pub fn restrict_mut<'rf>( &'rf mut self ) -> RestrictedStorage<'rf, T, &mut T::Storage>
Builds a mutable RestrictedStorage
out of a Storage
. Allows
restricted access to the inner components without allowing
invalidating the bitset for iteration in Join
.
source§impl<'e, T, D> Storage<'e, T, D>where
T: Component,
T::Storage: Tracked,
D: Deref<Target = MaskedStorage<T>>,
impl<'e, T, D> Storage<'e, T, D>where T: Component, T::Storage: Tracked, D: Deref<Target = MaskedStorage<T>>,
sourcepub fn channel(&self) -> &EventChannel<ComponentEvent>
pub fn channel(&self) -> &EventChannel<ComponentEvent>
Returns the event channel tracking modified components.
sourcepub fn event_emission(&self) -> bool
pub fn event_emission(&self) -> bool
Returns the actual state of the event emission.
source§impl<'e, T, D> Storage<'e, T, D>where
T: Component,
T::Storage: Tracked,
D: DerefMut<Target = MaskedStorage<T>>,
impl<'e, T, D> Storage<'e, T, D>where T: Component, T::Storage: Tracked, D: DerefMut<Target = MaskedStorage<T>>,
sourcepub fn channel_mut(&mut self) -> &mut EventChannel<ComponentEvent>
pub fn channel_mut(&mut self) -> &mut EventChannel<ComponentEvent>
Returns the event channel for insertions/removals/modifications of this storage’s components.
sourcepub fn register_reader(&mut self) -> ReaderId<ComponentEvent>
pub fn register_reader(&mut self) -> ReaderId<ComponentEvent>
Starts tracking component events. Note that this reader id should be used every frame, otherwise events will pile up and memory use by the event channel will grow waiting for this reader.
sourcepub fn flag(&mut self, event: ComponentEvent)
pub fn flag(&mut self, event: ComponentEvent)
Flags an index with a ComponentEvent
.
sourcepub fn set_event_emission(&mut self, emit: bool)
pub fn set_event_emission(&mut self, emit: bool)
Controls the events signal emission. When this is set to false the events modified/inserted/removed are not emitted.
source§impl<'e, T, D> Storage<'e, T, D>
impl<'e, T, D> Storage<'e, T, D>
sourcepub fn new(entities: Fetch<'e, EntitiesRes>, data: D) -> Storage<'e, T, D>
pub fn new(entities: Fetch<'e, EntitiesRes>, data: D) -> Storage<'e, T, D>
Creates a new Storage
from a fetched allocator and a immutable or
mutable MaskedStorage
, named data
.
source§impl<'e, T, D> Storage<'e, T, D>where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
impl<'e, T, D> Storage<'e, T, D>where T: Component, D: Deref<Target = MaskedStorage<T>>,
sourcepub fn unprotected_storage(&self) -> &T::Storage
pub fn unprotected_storage(&self) -> &T::Storage
Gets the wrapped storage.
sourcepub fn fetched_entities(&self) -> &EntitiesRes
pub fn fetched_entities(&self) -> &EntitiesRes
Returns the EntitiesRes
resource fetched by this storage.
This does not have anything to do with the components inside.
You only want to use this when implementing additional methods
for Storage
via an extension trait.
sourcepub fn count(&self) -> usize
pub fn count(&self) -> usize
Computes the number of elements this Storage
contains by counting the
bits in the bit set. This operation will never be performed in
constant time.
sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Checks whether this Storage
is empty. This operation is very cheap.
source§impl<'e, T, D> Storage<'e, T, D>where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
T::Storage: SliceAccess<T>,
impl<'e, T, D> Storage<'e, T, D>where T: Component, D: Deref<Target = MaskedStorage<T>>, T::Storage: SliceAccess<T>,
sourcepub fn as_slice(&self) -> &[<T::Storage as SliceAccess<T>>::Element]
pub fn as_slice(&self) -> &[<T::Storage as SliceAccess<T>>::Element]
Returns the component data as a slice.
The indices of this slice may not correspond to anything in particular. Check the underlying storage documentation for details.
source§impl<'e, T, D> Storage<'e, T, D>where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
T::Storage: SliceAccess<T>,
impl<'e, T, D> Storage<'e, T, D>where T: Component, D: DerefMut<Target = MaskedStorage<T>>, T::Storage: SliceAccess<T>,
sourcepub fn as_mut_slice(&mut self) -> &mut [<T::Storage as SliceAccess<T>>::Element]
pub fn as_mut_slice(&mut self) -> &mut [<T::Storage as SliceAccess<T>>::Element]
Returns the component data as a slice.
The indices of this slice may not correspond to anything in particular. Check the underlying storage documentation for details.
source§impl<'e, T, D> Storage<'e, T, D>where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
impl<'e, T, D> Storage<'e, T, D>where T: Component, D: DerefMut<Target = MaskedStorage<T>>,
sourcepub unsafe fn unprotected_storage_mut(&mut self) -> &mut T::Storage
pub unsafe fn unprotected_storage_mut(&mut self) -> &mut T::Storage
Gets mutable access to the wrapped storage.
Safety
This is unsafe because modifying the wrapped storage without also updating the mask bitset accordingly can result in illegal memory access.
sourcepub fn get_mut(
&mut self,
e: Entity
) -> Option<<<T as Component>::Storage as UnprotectedStorage<T>>::AccessMut<'_>>
pub fn get_mut( &mut self, e: Entity ) -> Option<<<T as Component>::Storage as UnprotectedStorage<T>>::AccessMut<'_>>
Tries to mutate the data associated with an Entity
.
sourcepub fn insert(&mut self, e: Entity, v: T) -> InsertResult<T>
pub fn insert(&mut self, e: Entity, v: T) -> InsertResult<T>
Inserts new data for a given Entity
.
Returns the result of the operation as a InsertResult<T>
If a component already existed for the given Entity
, then it will
be overwritten with the new component. If it did overwrite, then the
result will contain Some(T)
where T
is the previous component.
Trait Implementations§
source§impl<'a: 'b, 'b, T> GenericReadStorage for &'b ReadStorage<'a, T>where
T: Component,
impl<'a: 'b, 'b, T> GenericReadStorage for &'b ReadStorage<'a, T>where T: Component,
source§impl<'a, T> GenericReadStorage for ReadStorage<'a, T>where
T: Component,
impl<'a, T> GenericReadStorage for ReadStorage<'a, T>where T: Component,
source§impl<'a, T> SystemData<'a> for ReadStorage<'a, T>where
T: Component,
impl<'a, T> SystemData<'a> for ReadStorage<'a, T>where T: Component,
source§fn fetch(res: &'a World) -> Self
fn fetch(res: &'a World) -> Self
World
. Note that this is only specified
for one concrete lifetime 'a
, you need to implement the
SystemData
trait for every possible lifetime.