pub use self::data::{ReadStorage, WriteStorage};
pub use self::flagged::FlaggedStorage;
pub use self::generic::{GenericReadStorage, GenericWriteStorage};
pub use self::restrict::{
ImmutableParallelRestriction, MutableParallelRestriction, RestrictedStorage,
SequentialRestriction,
};
#[cfg(feature = "rudy")]
pub use self::storages::RudyStorage;
pub use self::storages::{BTreeStorage, DenseVecStorage, HashMapStorage, NullStorage, VecStorage};
pub use self::track::{ComponentEvent, Tracked};
pub use self::entry::{Entries, OccupiedEntry, VacantEntry, StorageEntry};
use std;
use std::marker::PhantomData;
use std::ops::{Deref, DerefMut, Not};
use hibitset::{BitSet, BitSetLike, BitSetNot};
use shred::{CastFrom, Fetch};
use self::drain::Drain;
use error::{Error, WrongGeneration};
use join::Join;
#[cfg(feature = "parallel")]
use join::ParJoin;
use world::{Component, EntitiesRes, Entity, Generation, Index};
mod data;
mod drain;
mod flagged;
mod generic;
mod restrict;
mod storages;
#[cfg(test)]
mod tests;
mod track;
mod entry;
pub struct AntiStorage<'a>(&'a BitSet);
impl<'a> Join for AntiStorage<'a> {
type Type = ();
type Value = ();
type Mask = BitSetNot<&'a BitSet>;
unsafe fn open(self) -> (Self::Mask, ()) {
(BitSetNot(self.0), ())
}
unsafe fn get(_: &mut (), _: Index) -> () {
()
}
}
unsafe impl<'a> DistinctStorage for AntiStorage<'a> {}
#[cfg(feature = "parallel")]
unsafe impl<'a> ParJoin for AntiStorage<'a> {}
pub trait AnyStorage {
fn drop(&mut self, entities: &[Entity]);
}
impl<T> CastFrom<T> for AnyStorage
where
T: AnyStorage + 'static,
{
fn cast(t: &T) -> &Self {
t
}
fn cast_mut(t: &mut T) -> &mut Self {
t
}
}
impl<T> AnyStorage for MaskedStorage<T>
where
T: Component,
{
fn drop(&mut self, entities: &[Entity]) {
for entity in entities {
MaskedStorage::drop(self, entity.id());
}
}
}
pub unsafe trait DistinctStorage {}
pub type InsertResult<T> = Result<Option<T>, Error>;
#[derive(Derivative)]
#[derivative(Default(bound = "T::Storage: Default"))]
pub struct MaskedStorage<T: Component> {
mask: BitSet,
inner: T::Storage,
}
impl<T: Component> MaskedStorage<T> {
pub fn new(inner: T::Storage) -> MaskedStorage<T> {
MaskedStorage {
mask: BitSet::new(),
inner,
}
}
fn open_mut(&mut self) -> (&BitSet, &mut T::Storage) {
(&self.mask, &mut self.inner)
}
pub fn clear(&mut self) {
unsafe {
self.inner.clean(&self.mask);
}
self.mask.clear();
}
pub fn remove(&mut self, id: Index) -> Option<T> {
if self.mask.remove(id) {
Some(unsafe { self.inner.remove(id) })
} else {
None
}
}
pub fn drop(&mut self, id: Index) {
if self.mask.remove(id) {
unsafe {
self.inner.drop(id);
}
}
}
}
impl<T: Component> Drop for MaskedStorage<T> {
fn drop(&mut self) {
self.clear();
}
}
pub struct Storage<'e, T, D> {
data: D,
entities: Fetch<'e, EntitiesRes>,
phantom: PhantomData<T>,
}
impl<'e, T, D> Storage<'e, T, D> {
pub fn new(entities: Fetch<'e, EntitiesRes>, data: D) -> Storage<'e, T, D> {
Storage {
data,
entities,
phantom: PhantomData,
}
}
}
impl<'e, T, D> Storage<'e, T, D>
where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
{
pub fn unprotected_storage(&self) -> &T::Storage {
&self.data.inner
}
pub fn fetched_entities(&self) -> &EntitiesRes {
&self.entities
}
pub fn get(&self, e: Entity) -> Option<&T> {
if self.data.mask.contains(e.id()) && self.entities.is_alive(e) {
Some(unsafe { self.data.inner.get(e.id()) })
} else {
None
}
}
pub fn count(&self) -> usize {
self.mask().iter().count()
}
pub fn is_empty(&self) -> bool {
self.mask().is_empty()
}
pub fn contains(&self, e: Entity) -> bool {
self.data.mask.contains(e.id()) && self.entities.is_alive(e)
}
pub fn mask(&self) -> &BitSet {
&self.data.mask
}
}
impl<'e, T, D> Storage<'e, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
{
pub unsafe fn unprotected_storage_mut(&mut self) -> &mut T::Storage {
&mut self.data.inner
}
pub fn get_mut(&mut self, e: Entity) -> Option<&mut T> {
if self.data.mask.contains(e.id()) && self.entities.is_alive(e) {
Some(unsafe { self.data.inner.get_mut(e.id()) })
} else {
None
}
}
pub fn insert(&mut self, e: Entity, mut v: T) -> InsertResult<T> {
if self.entities.is_alive(e) {
let id = e.id();
if self.data.mask.contains(id) {
std::mem::swap(&mut v, unsafe { self.data.inner.get_mut(id) });
Ok(Some(v))
} else {
self.data.mask.add(id);
unsafe { self.data.inner.insert(id, v) };
Ok(None)
}
} else {
Err(Error::WrongGeneration(WrongGeneration {
action: "insert component for entity",
actual_gen: self.entities.entity(e.id()).gen(),
entity: e,
}))
}
}
pub fn remove(&mut self, e: Entity) -> Option<T> {
if self.entities.is_alive(e) {
self.data.remove(e.id())
} else {
None
}
}
pub fn clear(&mut self) {
self.data.clear();
}
pub fn drain(&mut self) -> Drain<T> {
Drain {
data: &mut self.data,
}
}
}
unsafe impl<'a, T: Component, D> DistinctStorage for Storage<'a, T, D> where
T::Storage: DistinctStorage
{}
impl<'a, 'e, T, D> Join for &'a Storage<'e, T, D>
where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
{
type Type = &'a T;
type Value = &'a T::Storage;
type Mask = &'a BitSet;
unsafe fn open(self) -> (Self::Mask, Self::Value) {
(&self.data.mask, &self.data.inner)
}
unsafe fn get(v: &mut Self::Value, i: Index) -> &'a T {
v.get(i)
}
}
impl<'a, 'e, T, D> Not for &'a Storage<'e, T, D>
where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
{
type Output = AntiStorage<'a>;
fn not(self) -> Self::Output {
AntiStorage(&self.data.mask)
}
}
#[cfg(feature = "parallel")]
unsafe impl<'a, 'e, T, D> ParJoin for &'a Storage<'e, T, D>
where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
T::Storage: Sync,
{}
impl<'a, 'e, T, D> Join for &'a mut Storage<'e, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
{
type Type = &'a mut T;
type Value = &'a mut T::Storage;
type Mask = &'a BitSet;
unsafe fn open(self) -> (Self::Mask, Self::Value) {
self.data.open_mut()
}
unsafe fn get(v: &mut Self::Value, i: Index) -> &'a mut T {
let value: *mut Self::Value = v as *mut Self::Value;
(*value).get_mut(i)
}
}
#[cfg(feature = "parallel")]
unsafe impl<'a, 'e, T, D> ParJoin for &'a mut Storage<'e, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
T::Storage: Sync + DistinctStorage,
{}
pub trait TryDefault: Sized {
fn try_default() -> Result<Self, String>;
fn unwrap_default() -> Self {
match Self::try_default() {
Ok(x) => x,
Err(e) => panic!("Failed to create a default value for storage ({:?})", e),
}
}
}
impl<T> TryDefault for T
where
T: Default,
{
fn try_default() -> Result<Self, String> {
Ok(T::default())
}
}
pub trait UnprotectedStorage<T>: TryDefault {
unsafe fn clean<B>(&mut self, has: B)
where
B: BitSetLike;
unsafe fn get(&self, id: Index) -> &T;
unsafe fn get_mut(&mut self, id: Index) -> &mut T;
unsafe fn insert(&mut self, id: Index, value: T);
unsafe fn remove(&mut self, id: Index) -> T;
unsafe fn drop(&mut self, id: Index) {
self.remove(id);
}
}
#[cfg(test)]
mod tests_inline {
use rayon::iter::ParallelIterator;
use {Builder, Component, DenseVecStorage, Entities, ParJoin, ReadStorage, World};
struct Pos;
impl Component for Pos {
type Storage = DenseVecStorage<Self>;
}
#[test]
fn test_anti_par_join() {
let mut world = World::new();
world.create_entity().build();
world.exec(|(entities, pos): (Entities, ReadStorage<Pos>)| {
(&entities, !&pos).par_join().for_each(|(ent, ())| {
println!("Processing entity: {:?}", ent);
});
});
}
}