pub use self::deref_flagged::{DerefFlaggedStorage, FlaggedAccessMut};
pub use self::{
data::{ReadStorage, WriteStorage},
entry::{Entries, OccupiedEntry, StorageEntry, VacantEntry},
flagged::FlaggedStorage,
generic::{GenericReadStorage, GenericWriteStorage},
restrict::{
PairedStorageRead, PairedStorageWriteExclusive, PairedStorageWriteShared,
RestrictedStorage, SharedGetOnly,
},
storages::{
BTreeStorage, DefaultVecStorage, DenseVecStorage, HashMapStorage, NullStorage, SliceAccess,
VecStorage,
},
track::{ComponentEvent, Tracked},
};
use std::{
self,
marker::PhantomData,
ops::{Deref, DerefMut, Not},
};
use hibitset::{BitSet, BitSetLike, BitSetNot};
use shred::{CastFrom, Fetch};
#[nougat::gat(Type)]
use crate::join::LendJoin;
#[cfg(feature = "parallel")]
use crate::join::ParJoin;
use crate::{
error::{Error, WrongGeneration},
join::{Join, RepeatableLendGet},
world::{Component, EntitiesRes, Entity, Index},
};
use self::drain::Drain;
use self::sync_unsafe_cell::SyncUnsafeCell;
mod data;
mod deref_flagged;
mod drain;
mod entry;
mod flagged;
mod generic;
mod restrict;
mod storages;
mod sync_unsafe_cell;
#[cfg(test)]
mod tests;
mod track;
type AccessMutReturn<'a, T> = <<T as Component>::Storage as UnprotectedStorage<T>>::AccessMut<'a>;
pub struct AntiStorage<'a>(pub &'a BitSet);
#[nougat::gat]
unsafe impl<'a> LendJoin for AntiStorage<'a> {
type Mask = BitSetNot<&'a BitSet>;
type Type<'next> = ();
type Value = ();
unsafe fn open(self) -> (Self::Mask, ()) {
(BitSetNot(self.0), ())
}
unsafe fn get<'next>(_: &'next mut (), _: Index) {}
}
unsafe impl RepeatableLendGet for AntiStorage<'_> {}
unsafe 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) {}
}
#[cfg(feature = "parallel")]
unsafe impl<'a> ParJoin for AntiStorage<'a> {
type Mask = BitSetNot<&'a BitSet>;
type Type = ();
type Value = ();
unsafe fn open(self) -> (Self::Mask, ()) {
(BitSetNot(self.0), ())
}
unsafe fn get(_: &(), _: Index) {}
}
pub trait AnyStorage {
fn drop(&mut self, entities: &[Entity]);
}
unsafe impl<T> CastFrom<T> for dyn AnyStorage
where
T: AnyStorage + 'static,
{
fn cast(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) {
let mut mask_temp = core::mem::take(&mut self.mask);
unsafe { self.inner.clean(&mask_temp) };
mask_temp.clear();
self.mask = mask_temp;
}
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<AccessMutReturn<'_, 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) }.access_mut());
Ok(Some(v))
} else {
unsafe { self.not_present_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,
}))
}
}
#[inline(always)]
unsafe fn not_present_insert(&mut self, id: Index, value: T) {
unsafe { self.data.inner.insert(id, value) };
if cfg!(panic = "abort") {
self.data.mask.add(id);
} else {
struct RemoveOnDrop<'a, T: Component>(&'a mut MaskedStorage<T>, Index);
impl<'a, T: Component> Drop for RemoveOnDrop<'a, T> {
fn drop(&mut self) {
unsafe {
self.0.inner.remove(self.1);
}
}
}
let guard = RemoveOnDrop(&mut self.data, id);
guard.0.mask.add(id);
core::mem::forget(guard);
}
}
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())
}
}
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)
}
}
#[nougat::gat]
unsafe impl<'a, 'e, T, D> LendJoin for &'a Storage<'e, T, D>
where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
{
type Mask = &'a BitSet;
type Type<'next> = &'a T;
type Value = &'a T::Storage;
unsafe fn open(self) -> (Self::Mask, Self::Value) {
(&self.data.mask, &self.data.inner)
}
unsafe fn get<'next>(v: &'next mut Self::Value, i: Index) -> &'a T {
unsafe { v.get(i) }
}
}
unsafe impl<'a, 'e, T, D> RepeatableLendGet for &'a Storage<'e, T, D>
where
T: Component,
D: Deref<Target = MaskedStorage<T>>,
{
}
unsafe 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 {
unsafe { v.get(i) }
}
}
#[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,
{
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: &Self::Value, i: Index) -> &'a T {
unsafe { v.get(i) }
}
}
#[nougat::gat]
unsafe impl<'a, 'e, T, D> LendJoin for &'a mut Storage<'e, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
{
type Mask = &'a BitSet;
type Type<'next> = AccessMutReturn<'next, T>;
type Value = &'a mut T::Storage;
unsafe fn open(self) -> (Self::Mask, Self::Value) {
self.data.open_mut()
}
unsafe fn get<'next>(value: &'next mut Self::Value, id: Index) -> Self::Type<'next> {
unsafe { value.get_mut(id) }
}
}
unsafe impl<'a, 'e, T, D> RepeatableLendGet for &'a mut Storage<'e, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
{
}
mod shared_get_mut_only {
use super::{Index, SharedGetMutStorage, UnprotectedStorage};
use core::marker::PhantomData;
pub struct SharedGetMutOnly<'a, T, S>(&'a S, PhantomData<T>);
impl<'a, T, S> SharedGetMutOnly<'a, T, S> {
pub(crate) fn new(storage: &'a mut S) -> Self {
Self(storage, PhantomData)
}
pub(crate) unsafe fn get_mut(
this: &Self,
id: Index,
) -> <S as UnprotectedStorage<T>>::AccessMut<'a>
where
S: SharedGetMutStorage<T>,
{
unsafe { this.0.shared_get_mut(id) }
}
}
}
pub use shared_get_mut_only::SharedGetMutOnly;
unsafe impl<'a, 'e, T, D> Join for &'a mut Storage<'e, T, D>
where
T: Component,
D: DerefMut<Target = MaskedStorage<T>>,
T::Storage: SharedGetMutStorage<T>,
{
type Mask = &'a BitSet;
type Type = AccessMutReturn<'a, T>;
type Value = SharedGetMutOnly<'a, T, T::Storage>;
unsafe fn open(self) -> (Self::Mask, Self::Value) {
let (mask, value) = self.data.open_mut();
let value = SharedGetMutOnly::new(value);
(mask, value)
}
unsafe fn get(value: &mut Self::Value, id: Index) -> Self::Type {
unsafe { SharedGetMutOnly::get_mut(value, id) }
}
}
#[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 + SharedGetMutStorage<T> + DistinctStorage,
{
type Mask = &'a BitSet;
type Type = AccessMutReturn<'a, T>;
type Value = SharedGetMutOnly<'a, T, T::Storage>;
unsafe fn open(self) -> (Self::Mask, Self::Value) {
let (mask, value) = self.data.open_mut();
let value = SharedGetMutOnly::new(value);
(mask, value)
}
unsafe fn get(value: &Self::Value, id: Index) -> Self::Type {
unsafe { SharedGetMutOnly::get_mut(value, id) }
}
}
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 AccessMut: core::ops::Deref {
fn access_mut(&mut self) -> &mut Self::Target;
}
impl<T: ?Sized> AccessMut for T
where
T: core::ops::DerefMut,
{
fn access_mut(&mut self) -> &mut Self::Target {
&mut *self
}
}
pub trait UnprotectedStorage<T>: TryDefault {
type AccessMut<'a>: AccessMut<Target = T>
where
Self: 'a;
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) -> Self::AccessMut<'_>;
unsafe fn insert(&mut self, id: Index, value: T);
unsafe fn remove(&mut self, id: Index) -> T;
unsafe fn drop(&mut self, id: Index) {
unsafe { self.remove(id) };
}
}
pub trait SharedGetMutStorage<T>: UnprotectedStorage<T> {
unsafe fn shared_get_mut(&self, id: Index) -> <Self as UnprotectedStorage<T>>::AccessMut<'_>;
}
#[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);
});
});
}
}