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};
pub use self::storages::{BTreeStorage, DenseVecStorage, HashMapStorage, NullStorage, VecStorage};
#[cfg(feature = "rudy")]
pub use self::storages::RudyStorage;
pub use self::track::{InsertedFlag, ModifiedFlag, RemovedFlag, TrackChannels, Tracked};
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, 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;
pub struct AntiStorage<'a>(&'a BitSet);
impl<'a> Join for AntiStorage<'a> {
type Type = ();
type Value = ();
type Mask = BitSetNot<&'a BitSet>;
fn open(self) -> (Self::Mask, ()) {
(BitSetNot(self.0), ())
}
unsafe fn get(_: &mut (), _: Index) -> () {
()
}
}
unsafe impl<'a> DistinctStorage for AntiStorage<'a> {}
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 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 contains(&self, e: Entity) -> bool {
self.data.mask.contains(e.id()) && self.entities.is_alive(e)
}
pub fn mask(&self) -> &BitSet {
&self.data.mask
}
}
pub struct OccupiedEntry<'a, 'b: 'a, T: 'a, D: 'a> {
entity: Entity,
storage: &'a mut Storage<'b, T, D>,
}
impl<'a, 'b, T, D> OccupiedEntry<'a, 'b, T, D>
where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
{
pub fn get(&self) -> &T {
unsafe { self.storage.data.inner.get(self.entity.id()) }
}
}
impl<'a, 'b, T, D> OccupiedEntry<'a, 'b, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
{
pub fn get_mut(&mut self) -> &mut T {
unsafe { self.storage.data.inner.get_mut(self.entity.id()) }
}
pub fn into_mut(self) -> &'a mut T {
unsafe { self.storage.data.inner.get_mut(self.entity.id()) }
}
pub fn insert(&mut self, mut component: T) -> T {
std::mem::swap(&mut component, self.get_mut());
component
}
pub fn remove(self) -> T {
self.storage.data.remove(self.entity.id()).unwrap()
}
}
pub struct VacantEntry<'a, 'b: 'a, T: 'a, D: 'a> {
entity: Entity,
storage: &'a mut Storage<'b, T, D>,
}
impl<'a, 'b, T, D> VacantEntry<'a, 'b, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
{
pub fn insert(self, component: T) -> &'a mut T {
let id = self.entity.id();
self.storage.data.mask.add(id);
unsafe {
self.storage.data.inner.insert(id, component);
self.storage.data.inner.get_mut(id)
}
}
}
pub enum StorageEntry<'a, 'b: 'a, T: 'a, D: 'a> {
Occupied(OccupiedEntry<'a, 'b, T, D>),
Vacant(VacantEntry<'a, 'b, T, D>),
}
impl<'a, 'b, T, D> StorageEntry<'a, 'b, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
{
pub fn or_insert(self, component: T) -> &'a mut T {
self.or_insert_with(|| component)
}
pub fn or_insert_with<F>(self, default: F) -> &'a mut T
where
F: FnOnce() -> T,
{
match self {
StorageEntry::Occupied(occupied) => occupied.into_mut(),
StorageEntry::Vacant(vacant) => vacant.insert(default()),
}
}
}
impl<'e, T, D> Storage<'e, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
{
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 entry<'a>(&'a mut self, e: Entity) -> Result<StorageEntry<'a, 'e, T, D>, WrongGeneration>
where
'e: 'a,
{
if self.entities.is_alive(e) {
if self.data.mask.contains(e.id()) {
Ok(StorageEntry::Occupied(OccupiedEntry {
entity: e,
storage: self,
}))
} else {
Ok(StorageEntry::Vacant(VacantEntry {
entity: e,
storage: self,
}))
}
} else {
let gen = self.entities
.alloc
.generations
.get(e.id() as usize)
.cloned()
.unwrap_or(Generation(1));
Err(WrongGeneration {
action: "attempting to get an entry to a storage",
actual_gen: gen,
entity: e,
})
}
}
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;
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)
}
}
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;
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)
}
}
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 {Component, DenseVecStorage, Entities, ParJoin, ReadStorage, World};
use rayon::iter::ParallelIterator;
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);
});
});
}
}