pub use self::{
data::{ReadStorage, WriteStorage},
entry::{Entries, OccupiedEntry, StorageEntry, VacantEntry},
flagged::FlaggedStorage,
generic::{GenericReadStorage, GenericWriteStorage},
restrict::{
ImmutableParallelRestriction, MutableParallelRestriction, RestrictedStorage,
SequentialRestriction,
},
storages::{
BTreeStorage, DefaultVecStorage, DenseVecStorage, HashMapStorage, NullStorage, VecStorage,
},
track::{ComponentEvent, Tracked},
};
use self::storages::SliceAccess;
use std::{
self,
marker::PhantomData,
ops::{Deref, DerefMut, Not},
};
use hibitset::{BitSet, BitSetLike, BitSetNot};
use shred::{CastFrom, Fetch};
#[cfg(feature = "parallel")]
use crate::join::ParJoin;
use crate::{
error::{Error, WrongGeneration},
join::Join,
world::{Component, EntitiesRes, Entity, Generation, Index},
};
use self::drain::Drain;
mod data;
mod drain;
mod entry;
mod flagged;
mod generic;
mod restrict;
mod storages;
#[cfg(test)]
mod tests;
mod track;
pub struct AntiStorage<'a>(pub &'a BitSet);
impl<'a> Join for AntiStorage<'a> {
type Mask = BitSetNot<&'a BitSet>;
type Type = ();
type Value = ();
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]);
}
unsafe impl<T> CastFrom<T> for dyn 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>;
pub struct MaskedStorage<T: Component> {
mask: BitSet,
inner: T::Storage,
}
impl<T: Component> Default for MaskedStorage<T>
where
T::Storage: Default,
{
fn default() -> Self {
Self {
mask: Default::default(),
inner: Default::default(),
}
}
}
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: Deref<Target = MaskedStorage<T>>,
T::Storage: SliceAccess<T>,
{
pub fn as_slice(&self) -> &[<T::Storage as SliceAccess<T>>::Element] {
self.data.inner.as_slice()
}
}
impl<'e, T, D> Storage<'e, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
T::Storage: SliceAccess<T>,
{
pub fn as_mut_slice(&mut self) -> &mut [<T::Storage as SliceAccess<T>>::Element] {
self.data.inner.as_mut_slice()
}
}
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,
}
}
}
impl<'a, T, D: Clone> Clone for Storage<'a, T, D> {
fn clone(&self) -> Self {
Storage::new(self.entities.clone(), self.data.clone())
}
}
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 Mask = &'a BitSet;
type Type = &'a T;
type Value = &'a T::Storage;
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 Mask = &'a BitSet;
type Type = &'a mut T;
type Value = &'a mut T::Storage;
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)]
#[cfg(feature = "parallel")]
mod tests_inline {
use crate::{
Builder, Component, DenseVecStorage, Entities, ParJoin, ReadStorage, World, WorldExt,
};
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);
});
});
}
}