#[cfg(all(feature="parallel_systems", not(feature="lockfree")))]
use parking_lot::*;
use std::cell::{UnsafeCell};
use std::ops::Range;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::fmt::{self, Debug};
use std::any::TypeId;
#[cfg(not(feature="parallel_systems"))]
use std::cell::RefCell;
#[cfg(all(feature="parallel_systems", any(feature="lockfree", feature="debug_locks")))]
use crate::mutcell::{self, MutCell};
use std::cell;
use crate::{idtree, storage::{FastIndexExt}};
use crate::component::Component;
#[cfg(feature="parallel_systems")]
use crate::component;
use crate::entity::{Entity};
use crate::storage::{HiddenFastIndex, HierarchicalStorage, Storage, SubStorages};
use crate::bitmask::{Bitmask, MaskType};
use crate::utils::delete_lifetime;
#[cfg(not(feature="parallel_systems"))]
use crate::utils::delete_lifetime_mut;
#[cfg(feature="parallel_systems")]
use crossbeam_skiplist::SkipMap;
#[cfg(components_64)]
use num_traits::Zero;
#[cfg(not(feature="parallel_systems"))]
type SkipMap<K,V> = hashbrown::HashMap<K,V>;
#[cfg(feature="parallel_systems")]
#[derive(Clone)]
pub struct IndexGuard<'a>{
index: crossbeam_skiplist::map::Entry<'a, (Bitmask, TypeId), Vec<HiddenFastIndex>>,
}
#[cfg(feature="parallel_systems")]
impl<'a> IndexGuard<'a>{
pub(crate) fn new(index: crossbeam_skiplist::map::Entry<'a, (Bitmask, TypeId), Vec<HiddenFastIndex>>) -> IndexGuard<'a>{
IndexGuard{index}
}
}
#[cfg(feature="parallel_systems")]
impl<'a> Deref for IndexGuard<'a>{
type Target = [HiddenFastIndex];
fn deref(&self) -> &[HiddenFastIndex]{
self.index.value()
}
}
#[cfg(feature="parallel_systems")]
#[derive(Clone)]
pub struct OrderedIndexGuard<'a>{
index: crossbeam_skiplist::map::Entry<'a, (component::Id, Bitmask), Vec<HiddenFastIndex>>,
}
#[cfg(feature="parallel_systems")]
impl<'a> OrderedIndexGuard<'a>{
pub(crate) fn new(index: crossbeam_skiplist::map::Entry<'a, (component::Id, Bitmask), Vec<HiddenFastIndex>>) -> OrderedIndexGuard<'a>{
OrderedIndexGuard{index}
}
}
#[cfg(feature="parallel_systems")]
impl<'a> Deref for OrderedIndexGuard<'a>{
type Target = [HiddenFastIndex];
fn deref(&self) -> &[HiddenFastIndex]{
&self.index.value()
}
}
#[cfg(not(feature="parallel_systems"))]
#[derive(Clone)]
pub struct IndexGuard<'a>{
index: &'a [HiddenFastIndex],
}
#[cfg(not(feature="parallel_systems"))]
impl<'a> IndexGuard<'a>{
pub(crate) fn new(index: &'a [HiddenFastIndex]) -> IndexGuard<'a>{
IndexGuard{index}
}
}
#[cfg(not(feature="parallel_systems"))]
impl<'a> Deref for IndexGuard<'a>{
type Target = [HiddenFastIndex];
fn deref(&self) -> &[HiddenFastIndex]{
self.index
}
}
#[cfg(not(feature="parallel_systems"))]
pub type OrderedIndexGuard<'a> = IndexGuard<'a>;
pub struct LazyIndexGuard<'a>{
pub(crate) index_guard: UnsafeCell<Option<IndexGuard<'a>>>,
pub(crate) storages: SubStorages<'a>,
pub(crate) query_mask: Bitmask,
}
pub trait Indices {
fn index<S: FastIndexExt>(&self, storage: &S) -> &[HiddenFastIndex];
fn as_ptr_range<S: FastIndexExt>(&self, storage: &S) -> Range<*const HiddenFastIndex>;
}
impl<'a> Indices for LazyIndexGuard<'a> {
fn index<S: FastIndexExt>(&self, storage: &S) -> &[HiddenFastIndex] {
if let Some(guard) = unsafe{ (*self.index_guard.get()).as_ref() } {
&guard
}else{
let index_guard = self.storages.entities_for_mask(
self.query_mask.clone(),
storage
);
unsafe{
*self.index_guard.get() = Some(index_guard);
(*self.index_guard.get()).as_ref().unwrap()
}
}
}
fn as_ptr_range<S: FastIndexExt>(&self, storage: &S) -> Range<*const HiddenFastIndex> {
self.index(storage).as_ptr_range()
}
}
impl<'a> Indices for &'a [HiddenFastIndex] {
fn index<S: FastIndexExt>(&self, _: &S) -> &[HiddenFastIndex] {
self
}
fn as_ptr_range<S: FastIndexExt>(&self, _: &S) -> Range<*const HiddenFastIndex> {
(*self).as_ptr_range()
}
}
#[cfg(not(feature="parallel_systems"))]
pub struct Lock<T>(RefCell<T>);
#[cfg(all(feature="parallel_systems", any(feature="lockfree", feature="debug_locks")))]
pub struct Lock<T>(MutCell<T>);
#[cfg(all(feature="parallel_systems", not(feature="lockfree"), not(feature="debug_locks")))]
pub struct Lock<T>(RwLock<T>);
#[cfg(any(not(feature="parallel_systems"), feature="debug_locks"))]
impl<T> Lock<T>{
#[cfg(not(feature="debug_locks"))]
pub fn new(t: T) -> Lock<T>{
Lock(RefCell::new(t))
}
#[cfg(feature="debug_locks")]
pub fn new(t: T) -> Lock<T>{
Lock(MutCell::new(t))
}
pub fn read(&self) -> ReadGuard<T>{
ReadGuard::ThreadLocal(self.0.borrow())
}
pub fn write(&self) -> WriteGuard<T>{
WriteGuard::ThreadLocal(self.0.borrow_mut())
}
pub fn get_mut(&mut self) -> &mut T{
self.0.get_mut()
}
pub fn into_inner(self) -> T{
self.0.into_inner()
}
}
#[cfg(all(feature="parallel_systems", feature="lockfree"))]
impl<T> Lock<T>{
pub fn new(t: T) -> Lock<T>{
Lock(MutCell::new(t))
}
pub fn read(&self) -> ReadGuard<T>{
ReadGuard::Sync(self.0.borrow())
}
pub fn write(&self) -> WriteGuard<T>{
WriteGuard::Sync(self.0.borrow_mut())
}
pub fn get_mut(&mut self) -> &mut T{
self.0.get_mut()
}
pub fn into_inner(self) -> T{
self.0.into_inner()
}
}
#[cfg(all(feature="parallel_systems", not(feature="lockfree"), not(feature="debug_locks")))]
impl<T> Lock<T>{
pub fn new(t: T) -> Lock<T>{
Lock(RwLock::new(t))
}
pub fn read(&self) -> ReadGuard<T>{
ReadGuard::Sync(self.0.read())
}
pub fn write(&self) -> WriteGuard<T>{
WriteGuard::Sync(self.0.write())
}
pub fn get_mut(&mut self) -> &mut T{
self.0.get_mut()
}
pub fn into_inner(self) -> T{
self.0.into_inner()
}
}
pub enum ReadGuard<'a, S: 'a + ?Sized>{
#[cfg(not(feature="debug_locks"))]
ThreadLocal(cell::Ref<'a,S>),
#[cfg(feature="debug_locks")]
ThreadLocal(mutcell::Ref<'a,S>),
#[cfg(all(feature="parallel_systems", feature="lockfree"))]
Sync(mutcell::Ref<'a,S>),
#[cfg(all(feature="parallel_systems", not(feature="lockfree"), not(feature="debug_locks")))]
Sync(RwLockReadGuard<'a,S>),
#[cfg(all(feature="parallel_systems", not(feature="lockfree"), not(feature="debug_locks")))]
MappedSync(MappedRwLockReadGuard<'a,S>),
Reference(&'a S),
}
pub enum WriteGuard<'a, S: 'a + ?Sized>{
#[cfg(not(feature="debug_locks"))]
ThreadLocal(cell::RefMut<'a,S>),
#[cfg(feature="debug_locks")]
ThreadLocal(mutcell::RefMut<'a,S>),
#[cfg(all(feature="parallel_systems", feature="lockfree"))]
Sync(mutcell::RefMut<'a,S>),
#[cfg(all(feature="parallel_systems", not(feature="lockfree"), not(feature="debug_locks")))]
Sync(RwLockWriteGuard<'a,S>),
#[cfg(all(feature="parallel_systems", not(feature="lockfree"), not(feature="debug_locks")))]
MappedSync(MappedRwLockWriteGuard<'a,S>),
Reference(&'a mut S),
}
impl<'a,S: ?Sized> ReadGuard<'a,S>{
pub fn map<F,SS: ?Sized>(guard: Self, mapf: F) -> ReadGuard<'a,SS>
where F: FnOnce(&S) -> &SS{
match guard {
#[cfg(not(feature="debug_locks"))]
ReadGuard::ThreadLocal(s) => ReadGuard::ThreadLocal(cell::Ref::map(s, mapf)),
#[cfg(feature="debug_locks")]
ReadGuard::ThreadLocal(s) => ReadGuard::ThreadLocal(mutcell::Ref::map(s, mapf)),
#[cfg(all(feature="parallel_systems", feature="lockfree"))]
ReadGuard::Sync(s) => ReadGuard::Sync(mutcell::Ref::map(s, mapf)),
#[cfg(all(feature="parallel_systems", not(feature="lockfree"), not(feature="debug_locks")))]
ReadGuard::Sync(s) => ReadGuard::MappedSync(RwLockReadGuard::map(s, mapf)),
#[cfg(all(feature="parallel_systems", not(any(feature="lockfree", feature="debug_locks"))))]
ReadGuard::MappedSync(s) => ReadGuard::MappedSync(MappedRwLockReadGuard::map(s, mapf)),
ReadGuard::Reference(s) => ReadGuard::Reference(mapf(s)),
}
}
}
impl<'a,S: ?Sized> WriteGuard<'a,S>{
pub fn map<F,SS: ?Sized>(guard: Self, mapf: F) -> WriteGuard<'a,SS>
where F: FnOnce(&mut S) -> &mut SS{
match guard {
#[cfg(not(feature="debug_locks"))]
WriteGuard::ThreadLocal(s) => WriteGuard::ThreadLocal(cell::RefMut::map(s, mapf)),
#[cfg(feature="debug_locks")]
WriteGuard::ThreadLocal(s) => WriteGuard::ThreadLocal(mutcell::RefMut::map(s, mapf)),
#[cfg(all(feature="parallel_systems", feature="lockfree"))]
WriteGuard::Sync(s) => WriteGuard::Sync(mutcell::RefMut::map(s, mapf)),
#[cfg(all(feature="parallel_systems", not(feature="lockfree"), not(feature="debug_locks")))]
WriteGuard::Sync(s) => WriteGuard::MappedSync(RwLockWriteGuard::map(s, mapf)),
#[cfg(all(feature="parallel_systems", not(feature="lockfree"), not(feature="debug_locks")))]
WriteGuard::MappedSync(s) => WriteGuard::MappedSync(MappedRwLockWriteGuard::map(s, mapf)),
WriteGuard::Reference(s) => WriteGuard::Reference(mapf(s)),
}
}
}
impl<'a, S: 'a> Deref for ReadGuard<'a, S>{
type Target = S;
#[inline]
fn deref(&self) -> &S{
match self{
ReadGuard::ThreadLocal(s) => s.deref(),
#[cfg(all(feature="parallel_systems", not(feature="debug_locks")))]
ReadGuard::Sync(s) => s.deref(),
#[cfg(all(feature="parallel_systems", not(any(feature="lockfree", feature="debug_locks"))))]
ReadGuard::MappedSync(s) => s.deref(),
ReadGuard::Reference(s) => s
}
}
}
pub struct ReadGuardRef<'a, S: 'a + ?Sized>{
_guard: ReadGuard<'a, S>,
reference: &'a S,
}
impl<'a, S: 'a> ReadGuardRef<'a, S>{
pub fn new(guard: ReadGuard<'a, S>) -> ReadGuardRef<'a, S>{
ReadGuardRef{
reference: unsafe{ mem::transmute::<&S, &S>(guard.deref()) },
_guard: guard,
}
}
}
impl<'a, S: 'a + ?Sized> ReadGuardRef<'a, S>{
pub fn map<F, SS: ?Sized>(guard: Self, mapf: F) -> ReadGuardRef<'a, SS>
where F: Fn(&S) -> &SS{
ReadGuardRef{
reference: mapf(guard.reference),
_guard: ReadGuard::map(guard._guard, mapf),
}
}
}
impl<'a, S: 'a + ?Sized> Deref for ReadGuardRef<'a, S>{
type Target = S;
#[inline]
fn deref(&self) -> &S{
self.reference
}
}
impl<'a, S: 'a> Deref for WriteGuard<'a, S>{
type Target = S;
fn deref(&self) -> &S{
match self{
WriteGuard::ThreadLocal(s) => s.deref(),
#[cfg(all(feature="parallel_systems", not(feature="debug_locks")))]
WriteGuard::Sync(s) => s.deref(),
#[cfg(all(feature="parallel_systems", not(any(feature="lockfree", feature="debug_locks"))))]
WriteGuard::MappedSync(s) => s.deref(),
WriteGuard::Reference(s) => s,
}
}
}
impl<'a, S: 'a> DerefMut for WriteGuard<'a, S>{
fn deref_mut(&mut self) -> &mut S{
match self{
WriteGuard::ThreadLocal(s) => s.deref_mut(),
#[cfg(all(feature="parallel_systems", not(feature="debug_locks")))]
WriteGuard::Sync(s) => s.deref_mut(),
#[cfg(all(feature="parallel_systems", not(any(feature="lockfree", feature="debug_locks"))))]
WriteGuard::MappedSync(s) => s.deref_mut(),
WriteGuard::Reference(s) => s,
}
}
}
pub struct CacheGuard {
#[cfg(feature="parallel_systems")]
entities_index_per_mask: &'static SkipMap<(Bitmask, TypeId), Vec<HiddenFastIndex>>,
#[cfg(not(feature="parallel_systems"))]
entities_index_per_mask: &'static mut SkipMap<(Bitmask, TypeId), Vec<HiddenFastIndex>>,
component_mask: &'static MaskType
}
#[cfg(feature="parallel_systems")]
impl<'a> Drop for CacheGuard {
fn drop(&mut self) {
if let Some(mut entry) = self.entities_index_per_mask.front(){
loop {
let (mask, _storage_id) = entry.key();
if mask.components() & self.component_mask != MaskType::zero() {
entry.remove();
}
if !entry.move_next(){
break;
}
}
}
}
}
#[cfg(not(feature="parallel_systems"))]
impl<'a> Drop for CacheGuard {
fn drop(&mut self) {
if *self.component_mask == MaskType::zero(){
return
}
let components_mask = self.component_mask;
self.entities_index_per_mask.retain(|(mask,_ ), _|{
mask.components() & components_mask == MaskType::zero()
})
}
}
#[cfg(feature="parallel_systems")]
pub trait CacheConstructor {
fn new(
entities_index_per_mask: &SkipMap<(Bitmask, TypeId), Vec<HiddenFastIndex>>,
component_mask: &MaskType) -> Self;
}
#[cfg(not(feature="parallel_systems"))]
pub trait CacheConstructor {
fn new(
entities_index_per_mask: &mut SkipMap<(Bitmask, TypeId), Vec<HiddenFastIndex>>,
component_mask: &MaskType) -> Self;
}
impl CacheConstructor for CacheGuard {
#[cfg(feature="parallel_systems")]
fn new(
entities_index_per_mask: &SkipMap<(Bitmask, TypeId), Vec<HiddenFastIndex>>,
component_mask: &MaskType) -> Self
{
CacheGuard {
entities_index_per_mask: unsafe{ delete_lifetime(entities_index_per_mask) },
component_mask: unsafe{ delete_lifetime(component_mask) },
}
}
#[cfg(not(feature="parallel_systems"))]
fn new(
entities_index_per_mask: &mut SkipMap<(Bitmask, TypeId), Vec<HiddenFastIndex>>,
component_mask: &MaskType) -> Self
{
CacheGuard {
entities_index_per_mask: unsafe{ delete_lifetime_mut(entities_index_per_mask) },
component_mask: unsafe{ delete_lifetime(component_mask) },
}
}
}
#[cfg(feature="parallel_systems")]
impl CacheConstructor for () {
fn new(_: &SkipMap<(Bitmask, TypeId), Vec<HiddenFastIndex>>, _: &MaskType) -> Self{
()
}
}
#[cfg(not(feature="parallel_systems"))]
impl CacheConstructor for () {
fn new(_: &mut SkipMap<(Bitmask, TypeId), Vec<HiddenFastIndex>>, _: &MaskType) -> Self{
()
}
}
pub type StorageWriteGuard<'a, C> = WriteGuardRef<'a, <C as Component>::Storage, <C as Component>::MutStorageCacheGuard>;
pub struct WriteGuardRef<'a, S: 'a + ?Sized, C = ()>{
_guard: WriteGuard<'a, S>,
reference: &'a mut S,
cache_guard: C,
}
impl<'a, S: 'a> WriteGuardRef<'a, S>{
pub fn new(mut guard: WriteGuard<'a, S>) -> WriteGuardRef<'a, S>{
WriteGuardRef{
reference: unsafe{ mem::transmute::<&mut S, &mut S>(guard.deref_mut()) },
_guard: guard,
cache_guard: ()
}
}
}
impl<'a, S: 'a> WriteGuardRef<'a, S, CacheGuard>{
#[cfg(feature="parallel_systems")]
pub fn with_cache_guard<Cache: CacheConstructor>(
mut guard: WriteGuard<'a, S>,
entities_index_per_mask: &'a SkipMap<(Bitmask, TypeId), Vec<HiddenFastIndex>>,
component_mask: &'a MaskType) -> WriteGuardRef<'a, S, Cache>
{
WriteGuardRef{
reference: unsafe{ mem::transmute::<&mut S, &mut S>(guard.deref_mut()) },
_guard: guard,
cache_guard: Cache::new(entities_index_per_mask, component_mask)
}
}
#[cfg(not(feature="parallel_systems"))]
pub fn with_cache_guard<Cache: CacheConstructor>(
mut guard: WriteGuard<'a, S>,
entities_index_per_mask: &'a mut SkipMap<(Bitmask, TypeId), Vec<HiddenFastIndex>>,
component_mask: &'a MaskType) -> WriteGuardRef<'a, S, Cache>
{
WriteGuardRef{
reference: unsafe{ mem::transmute::<&mut S, &mut S>(guard.deref_mut()) },
_guard: guard,
cache_guard: Cache::new(entities_index_per_mask, component_mask)
}
}
}
impl<'a, S: 'a + ?Sized, C> WriteGuardRef<'a, S, C>{
pub fn map<F, SS: ?Sized>(guard: Self, mapf: F) -> WriteGuardRef<'a, SS, C>
where F: Fn(&mut S) -> &mut SS{
WriteGuardRef{
reference: mapf(guard.reference),
_guard: WriteGuard::map(guard._guard, mapf),
cache_guard: guard.cache_guard,
}
}
}
impl<'a, S: 'a + ?Sized, C> Deref for WriteGuardRef<'a, S, C>{
type Target = S;
#[inline]
fn deref(&self) -> &S{
self.reference
}
}
impl<'a, S: 'a + ?Sized, C> DerefMut for WriteGuardRef<'a, S, C>{
#[inline]
fn deref_mut(&mut self) -> &mut S{
self.reference
}
}
pub struct Ptr<'a, C: Component>
where for<'s> <C as Component>::Storage: Storage<'s, C>
{
_guard: ReadGuardRef<'a, <C as Component>::Storage>,
reference: <<C as Component>::Storage as Storage<'a,C>>::Get,
}
impl<'a, C: Component> Ptr<'a, C>
where for<'s> <C as Component>::Storage: Storage<'s, C>
{
pub(crate) fn new(_guard: ReadGuardRef<'a, <C as Component>::Storage>, entity: Entity) -> Ptr<'a, C>{
Ptr{
reference: unsafe{ _guard.reference.get(entity.guid()) },
_guard,
}
}
}
impl<'a, C: Component> Deref for Ptr<'a,C>
where for<'s> <C as Component>::Storage: Storage<'s, C>
{
type Target = <<C as Component>::Storage as Storage<'a,C>>::Get;
fn deref(&self) -> &<<C as Component>::Storage as Storage<'a,C>>::Get{
&self.reference
}
}
impl<'a, C: Component> DerefMut for Ptr<'a,C>
where for<'s> <C as Component>::Storage: Storage<'s, C>
{
fn deref_mut(&mut self) -> &mut <<C as Component>::Storage as Storage<'a,C>>::Get{
&mut self.reference
}
}
impl<'a, C: Component> Debug for Ptr<'a,C>
where
for<'s> <C as Component>::Storage: Storage<'s, C>,
<<C as Component>::Storage as Storage<'a,C>>::Get: Debug
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result{
self.reference.fmt(fmt)
}
}
pub struct PtrMut<'a, C: Component>
where for<'s> <C as Component>::Storage: Storage<'s, C>
{
_guard: WriteGuard<'a, <C as Component>::Storage>,
reference: <<C as Component>::Storage as Storage<'a,C>>::GetMut,
}
impl<'a, C: Component> PtrMut<'a, C>
where for<'s> <C as Component>::Storage: Storage<'s, C>
{
pub(crate) fn new(mut _guard: StorageWriteGuard<'a, C>, entity: Entity) -> PtrMut<'a, C>{
let s: &'a mut <C as Component>::Storage = unsafe{ mem::transmute(_guard._guard.deref_mut()) };
let reference = unsafe{ s.get_mut(entity.guid()) };
PtrMut{
reference,
_guard: _guard._guard,
}
}
}
impl<'a, C: Component> Deref for PtrMut<'a,C>
where for<'s> <C as Component>::Storage: Storage<'s, C>
{
type Target = <<C as Component>::Storage as Storage<'a,C>>::GetMut;
fn deref(&self) -> &<<C as Component>::Storage as Storage<'a,C>>::GetMut{
&self.reference
}
}
impl<'a, C: Component> DerefMut for PtrMut<'a,C>
where for<'s> <C as Component>::Storage: Storage<'s, C>
{
fn deref_mut(&mut self) -> &mut <<C as Component>::Storage as Storage<'a,C>>::GetMut{
&mut self.reference
}
}
impl<'a, C: Component> Debug for PtrMut<'a,C>
where
<<C as Component>::Storage as Storage<'a,C>>::GetMut: Debug,
for<'s> <C as Component>::Storage: Storage<'s, C>
{
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result{
self.reference.fmt(fmt)
}
}
impl<'a, C: Component> Iterator for Ptr<'a, C>
where
<<C as Component>::Storage as Storage<'a,C>>::Get: Iterator,
for<'s> <C as Component>::Storage: Storage<'s, C>
{
type Item = <<<C as Component>::Storage as Storage<'a,C>>::Get as Iterator>::Item;
fn next(&mut self) -> Option<Self::Item>{
self.reference.next()
}
}
impl<'a, C: Component> Iterator for PtrMut<'a, C>
where
<<C as Component>::Storage as Storage<'a,C>>::GetMut: Iterator,
for<'s> <C as Component>::Storage: Storage<'s, C>
{
type Item = <<<C as Component>::Storage as Storage<'a,C>>::GetMut as Iterator>::Item;
fn next(&mut self) -> Option<Self::Item>{
self.reference.next()
}
}
pub struct NodePtr<'a, C: Component>
where for<'b> <C as Component>::Storage: HierarchicalStorage<'b, C>
{
_guard: ReadGuardRef<'a, <C as Component>::Storage>,
reference: idtree::NodeRef<'a, C>,
}
impl<'a, C: Component> NodePtr<'a, C>
where
C: Component,
for<'b> <C as Component>::Storage: HierarchicalStorage<'b, C>
{
pub(crate) fn new(_guard: ReadGuardRef<'a, <C as Component>::Storage>, entity: Entity) -> NodePtr<'a, C>
{
NodePtr{
reference: unsafe{ _guard.reference.get_node(entity.guid()) },
_guard,
}
}
}
impl<'a, C: Component> Deref for NodePtr<'a,C>
where for<'b> <C as Component>::Storage: HierarchicalStorage<'b, C>
{
type Target = idtree::NodeRef<'a, C>;
fn deref(&self) -> &idtree::NodeRef<'a, C>{
&self.reference
}
}
pub struct NodePtrMut<'a, C: Component>
where for<'b> <C as Component>::Storage: HierarchicalStorage<'b, C>
{
_guard: StorageWriteGuard<'a, C>,
reference: idtree::NodeRefMut<'a, C>,
}
impl<'a, C: Component> NodePtrMut<'a, C>
where
C: Component,
for<'b> <C as Component>::Storage: HierarchicalStorage<'b, C>
{
pub(crate) fn new(mut _guard: StorageWriteGuard<'a, C>, entity: Entity) -> NodePtrMut<'a, C>
{
let s: &'a mut <C as Component>::Storage = unsafe{ mem::transmute(_guard._guard.deref_mut()) };
let reference = unsafe{ s.get_node_mut(entity.guid()) };
NodePtrMut{
reference,
_guard,
}
}
pub unsafe fn into_node(self) -> idtree::NodeRefMut<'a, C>{
self.reference
}
}
impl<'a, C: Component> Deref for NodePtrMut<'a,C>
where for<'b> <C as Component>::Storage: HierarchicalStorage<'b, C>
{
type Target = idtree::NodeRefMut<'a, C>;
fn deref(&self) -> &idtree::NodeRefMut<'a, C>{
&self.reference
}
}
impl<'a, C: Component> DerefMut for NodePtrMut<'a,C>
where for<'b> <C as Component>::Storage: HierarchicalStorage<'b, C>
{
fn deref_mut(&mut self) -> &mut idtree::NodeRefMut<'a, C>{
&mut self.reference
}
}