use crate::storage::{
Storage, HierarchicalStorage, OneToNStorage, SliceView, SliceViewMut,
IntoIter, IntoIterMut,
IntoIdedIterMut,
IntoOrderedIter, IntoOrderedIterMut,
IntoOrderedIdedIterMut,
ChangedStorageExt,
IntoChangesIter, IntoOrderedChangesIter, OrderedId
};
#[cfg(feature = "parallel_iter")]
use crate::storage::ParStorage;
use crate::sync::{ReadGuardRef, WriteGuardRef};
use std::marker;
use crate::utils::*;
use crate::idtree;
use hashbrown::HashSet;
pub struct Changed<S,T>{
storage: S,
changed: HashSet<usize>,
storage_changed: bool,
_marker: marker::PhantomData<T>,
}
impl<'a, S, T> ChangedStorageExt<'a> for Changed<S,T>
where S: Storage<'a,T>
{
fn changed_entities(&self) -> hashbrown::hash_set::Iter<usize>{
self.changed.iter()
}
}
impl<'a, T: 'a, S: Storage<'a,T>> Storage<'a, T> for Changed<S,T> {
type Get = <S as Storage<'a,T>>::Get;
type GetMut = <S as Storage<'a,T>>::GetMut;
type DerefTarget = <S as Storage<'a,T>>::DerefTarget;
type IdedIter = <S as Storage<'a,T>>::IdedIter;
type Iter = <S as Storage<'a,T>>::Iter;
type IterMut = <S as Storage<'a,T>>::IterMut;
#[inline]
fn new() -> Changed<S,T>{
Changed{
storage: S::new(),
changed: HashSet::new(),
storage_changed: false,
_marker: marker::PhantomData
}
}
#[inline]
fn with_capacity(capacity: usize) -> Self{
Changed{
storage: S::with_capacity(capacity),
changed: HashSet::with_capacity(capacity),
storage_changed: false,
_marker: marker::PhantomData
}
}
#[inline]
fn insert(&mut self, guid: usize, t: T){
self.storage_changed = true;
self.storage.insert(guid, t);
}
#[inline]
fn remove(&mut self, guid: usize){
self.storage_changed = true;
self.changed.remove(&guid);
self.storage.remove(guid);
}
#[inline]
unsafe fn get(&self, guid: usize) -> <S as Storage<'a,T>>::Get {
self.storage.get(guid)
}
#[inline]
unsafe fn get_mut(&mut self, guid: usize) -> <S as Storage<'a,T>>::GetMut {
self.storage.get_mut(guid)
}
#[inline]
unsafe fn fast_get(&self, guid: usize) -> <S as Storage<'a,T>>::Get {
self.storage.fast_get(guid)
}
#[inline]
unsafe fn fast_get_mut(&mut self, guid: usize) -> <S as Storage<'a,T>>::GetMut {
self.storage.fast_get_mut(guid)
}
fn fast_index(&self, guid: usize) -> usize{
self.storage.fast_index(guid)
}
fn guid_from_fast_index(&self, idx: usize) -> usize{
self.storage.guid_from_fast_index(idx)
}
#[inline]
fn contains(&self, guid: usize) -> bool{
self.storage.contains(guid)
}
fn update(&mut self){
self.storage_changed = false;
self.changed.clear();
}
fn storage_changed(&self) -> bool{
self.storage_changed || !self.changed.is_empty()
}
fn tracks_changes() -> bool { true }
fn ided_iter(&self) -> Self::IdedIter{
self.storage.ided_iter()
}
fn iter(&self) -> Self::Iter{
self.storage.iter()
}
fn iter_mut(&mut self) -> Self::IterMut{
self.storage.iter_mut()
}
}
#[cfg(feature = "parallel_iter")]
impl<'a, T: 'a, S: ParStorage<'a,T>> ParStorage<'a, T> for Changed<S,T>
where
S: Storage<'a, T>,
<S as Storage<'a,T>>::Get: Send,
<S as Storage<'a,T>>::GetMut: Send,
{
type ParIter = <S as ParStorage<'a,T>>::ParIter;
type ParIterMut = <S as ParStorage<'a,T>>::ParIterMut;
fn par_iter(&self) -> Self::ParIter{
self.storage.par_iter()
}
fn par_iter_mut(&mut self) -> Self::ParIterMut{
self.storage.par_iter_mut()
}
}
impl<'a, S, T> HierarchicalStorage<'a,T> for Changed<S, T>
where S: HierarchicalStorage<'a,T>,
T: 'a,
{
unsafe fn insert_child(&mut self, parent_guid: usize, guid: usize, value: T){
self.storage_changed = true;
self.storage.insert_child(parent_guid, guid, value)
}
unsafe fn get_node(&self, guid: usize) -> idtree::NodeRef<T>{
self.storage.get_node(guid)
}
unsafe fn get_node_mut(&mut self, guid: usize) -> idtree::NodeRefMut<T>{
self.storage.get_node_mut(guid)
}
unsafe fn fast_get_node(&self, idx: idtree::NodeId) -> idtree::NodeRef<T>{
self.storage.fast_get_node(idx)
}
unsafe fn fast_get_node_mut(&mut self, idx: idtree::NodeId) -> idtree::NodeRefMut<T>{
self.storage.fast_get_node_mut(idx)
}
unsafe fn guid_for(&self, nodeid: idtree::NodeId) -> usize{
self.storage.guid_for(nodeid)
}
unsafe fn ordered_fast_index(&self, guid: usize) -> idtree::NodeId{
self.storage.ordered_fast_index(guid)
}
fn ordered_ids(&self) -> ReadGuardRef<Vec<OrderedId<idtree::NodeId>>> {
self.storage.ordered_ids()
}
}
impl<'a, S, T> OneToNStorage<'a,T> for Changed<S, T>
where S: OneToNStorage<'a,T>,
T: 'a,
{
fn insert_slice<I: IntoIterator<Item = T>>(&mut self, guid: usize, t: I){
self.storage_changed = true;
self.storage.insert_slice(guid, t)
}
unsafe fn get_slice(&self, guid: usize) -> SliceView<T>{
self.storage.get_slice(guid)
}
unsafe fn get_slice_mut(&mut self, guid: usize) -> SliceViewMut<T>{
self.storage.get_slice_mut(guid)
}
}
impl<'a, S, T> IntoIter for ReadGuardRef<'a, Changed<S,T>>
where ReadGuardRef<'a,S>: IntoIter
{
type Iter = <ReadGuardRef<'a,S> as IntoIter>::Iter;
fn into_iter(self) -> <ReadGuardRef<'a,S> as IntoIter>::Iter{
ReadGuardRef::map(self, |changed| &changed.storage).into_iter()
}
}
impl<'a, S, T> IntoIterMut for WriteGuardRef<'a, Changed<S,T>>
where WriteGuardRef<'a,S>: IntoIterMut
{
type IterMut = <WriteGuardRef<'a,S> as IntoIterMut>::IterMut;
fn into_iter_mut(self) -> <WriteGuardRef<'a,S> as IntoIterMut>::IterMut {
WriteGuardRef::map(self, |changed| &mut changed.storage).into_iter_mut()
}
}
impl<'a, S, T> IntoOrderedIter for ReadGuardRef<'a, Changed<S, T>>
where ReadGuardRef<'a, S>: IntoOrderedIter
{
type OrderedIter = <ReadGuardRef<'a, S> as IntoOrderedIter>::OrderedIter;
fn into_ordered_iter(self) -> Self::OrderedIter {
ReadGuardRef::map(self, |changed| &changed.storage).into_ordered_iter()
}
}
impl<'a, S, T> IntoOrderedIterMut for WriteGuardRef<'a, Changed<S, T>>
where WriteGuardRef<'a, S>: IntoOrderedIterMut
{
type OrderedIterMut = <WriteGuardRef<'a, S> as IntoOrderedIterMut>::OrderedIterMut;
fn into_ordered_iter_mut(self) -> Self::OrderedIterMut {
WriteGuardRef::map(self, |changed| &mut changed.storage).into_ordered_iter_mut()
}
}
impl<'a,S,T> IntoChangesIter<'a,T> for WriteGuardRef<'a, Changed<S, T>>
where S: Storage<'a,T>,
WriteGuardRef<'a, S>: IntoIdedIterMut,
<WriteGuardRef<'a, S> as IntoIdedIterMut>::IdedIterMut: Iterator<Item = (usize, <S as Storage<'a,T>>::GetMut)>,
{
type ChangesItem = <S as Storage<'a,T>>::GetMut;
type RawSubStorage = S;
type SubStorage = WriteGuardRef<'a, S>;
fn extend_changes<F>(mut self, mut has_chagend: F)
where F: FnMut(Self::ChangesItem) -> bool
{
let changed = unsafe{ delete_lifetime_mut(&mut self.changed) };
let iter = WriteGuardRef::map(
self,
|changed| &mut changed.storage
).into_ided_iter_mut();
changed.extend(iter.filter_map(|(id, t)| if has_chagend(t){
Some(id)
}else{
None
}));
}
unsafe fn into_storage_and_changes(mut self) -> (Self::SubStorage, &'a mut HashSet<usize>){
let changed = delete_lifetime_mut(&mut self.changed);
let substorage = WriteGuardRef::map(
self,
|changed| &mut changed.storage
);
(substorage, changed)
}
}
impl<'a,S,T> IntoOrderedChangesIter<'a,T> for WriteGuardRef<'a, Changed<S, T>>
where S: Storage<'a,T>,
S: HierarchicalStorage<'a,T> + 'a,
WriteGuardRef<'a, S>: IntoOrderedIdedIterMut,
<WriteGuardRef<'a, S> as IntoOrderedIdedIterMut>::OrderedIdedIterMut: Iterator<Item = (usize, idtree::NodeRefMut<'a,T>)>
{
type OrderedChangesItem = idtree::NodeRefMut<'a,T>;
type RawSubStorage = S;
type SubStorage = WriteGuardRef<'a, S>;
fn ordered_extend_changes<F>(self, mut has_changed: F)
where F: FnMut(Self::OrderedChangesItem) -> bool
{
let (guard, changed) = unsafe{ self.into_storage_and_changes() };
let iter = guard.into_ordered_ided_iter_mut();
changed.extend(iter.filter_map(|(id, t)| if has_changed(t){
Some(id)
}else{
None
}));
}
unsafe fn into_storage_and_changes(mut self) -> (Self::SubStorage, &'a mut HashSet<usize>){
let changed = delete_lifetime_mut(&mut self.changed);
let substorage = WriteGuardRef::map(self, |changed| &mut changed.storage);
(substorage, changed)
}
}