use qecs_core::*;
use std::collections::btree_set::{self, BTreeSet};
use std::iter;
pub struct WithDirtyState<S: StoreBase> {
store: S,
flags: BTreeSet<Dirtied<'static, S::Id>>,
was_cleared: bool,
}
impl<S> From<S> for WithDirtyState<S>
where S: StoreBase
{
fn from(store: S) -> Self {
WithDirtyState{
store: store,
flags: BTreeSet::new(),
was_cleared: false,
}
}
}
impl<S> Default for WithDirtyState<S>
where S: StoreBase + Default
{
fn default() -> Self {
Self::from(S::default())
}
}
impl<S> ServiceBase for WithDirtyState<S>
where S: StoreBase
{
fn on_before_frame(&mut self){
self.flags.clear();
self.was_cleared = false;
}
}
impl<S> StoreBase for WithDirtyState<S>
where S: StoreBase
{
type Id = S::Id;
fn len(&self) -> usize {
self.store.len()
}
fn is_assigned<'id>(&self, id: Valid<'id, Self::Id>) -> bool {
self.store.is_assigned(id)
}
fn release_drop<'id>(&mut self, id: Valid<'id, Self::Id>) -> bool {
if !self.store.release_drop(id) { return false; }
let mut negated = false;
match self.flags.replace(Dirtied::Released(*id)) {
Some(Dirtied::Assigned(_)) => { negated = true; }
_ => {}
}
if negated {
self.flags.remove(&*id);
}
true
}
fn clear(&mut self){
self.store.clear();
self.flags.clear();
self.was_cleared = true;
}
}
impl<'a, S> _ComponentStore<'a> for WithDirtyState<S>
where S: _ComponentStore<'a>
{
type _Value = S::_Value;
type Values = S::Values;
type ValuesMut = S::ValuesMut;
}
impl<S> ComponentStore for WithDirtyState<S>
where S: ComponentStore
{
type Value = S::Value;
fn assign<'id, T>(&mut self, id: Valid<'id, Self::Id>, com: T) -> Option<Self::Value>
where T: Into<Self::Value>
{
let ret = self.store.assign(id, com.into());
let id = unsafe { Valid::new(*id) };
let mut modified = false;
match self.flags.replace(Dirtied::Assigned(id)) {
Some(Dirtied::Released(_)) => { modified = true; }
Some(Dirtied::Modified(_)) => { modified = true; }
_ => {}
}
if modified {
self.flags.replace(Dirtied::Modified(id));;
}
ret
}
fn release<'id>(&mut self, id: Valid<'id, Self::Id>) -> Option<Self::Value> {
let ret = match self.store.release(id) {
Some(r) => r, None => return None
};
let id = unsafe { Valid::new(*id) };
let mut negated = false;
match self.flags.replace(Dirtied::Released(*id)) {
Some(Dirtied::Assigned(_)) => { negated = true; }
_ => {}
}
if negated {
self.flags.remove(&*id);;
}
Some(ret)
}
fn get<'id>(&self, id: Valid<'id, Self::Id>) -> Option<&Self::Value> {
self.store.get(id)
}
fn get_mut<'id>(&mut self, id: Valid<'id, Self::Id>) -> Option<&mut Self::Value> {
let ret = match self.store.get_mut(id) {
Some(r) => r, None => return None
};
let id = unsafe { Valid::new(*id) };
let mut assigned = false;
match self.flags.replace(Dirtied::Modified(id)) {
Some(Dirtied::Assigned(_)) => { assigned = true; }
_ => {}
}
if assigned {
self.flags.replace(Dirtied::Assigned(id));;
}
Some(ret)
}
fn values<'a>(&'a self) -> <Self as _ComponentStore<'a>>::Values {
self.store.values()
}
fn values_mut<'a>(&'a mut self) -> <Self as _ComponentStore<'a>>::ValuesMut {
unimplemented!()
}
}
impl<'a, S> _ComponentStoreIter<'a> for WithDirtyState<S>
where S: _ComponentStoreIter<'a>
{
type Iter = S::Iter;
type IterMut = S::IterMut;
}
impl<S> ComponentStoreIter for WithDirtyState<S>
where S: ComponentStoreIter
{
fn iter<'a>(&'a self) -> <Self as _ComponentStoreIter<'a>>::Iter {
self.store.iter()
}
fn iter_mut<'a>(&'a mut self) -> <Self as _ComponentStoreIter<'a>>::IterMut {
unimplemented!()
}
}
impl<S> EntityStore for WithDirtyState<S>
where S: EntityStore
{
fn assign<'id>(&mut self, id: Valid<'id, Self::Id>) -> bool {
let ret = self.store.assign(id);
let id = unsafe { Valid::new(*id) };
let mut negated = false;
match self.flags.replace(Dirtied::Assigned(id)) {
Some(Dirtied::Released(_)) => { negated = true; }
_ => {}
}
if negated {
self.flags.remove(&*id);;
}
ret
}
fn release<'id>(&mut self, id: Valid<'id, Self::Id>) -> bool {
if !self.store.release(id){ return false; }
let mut negated = false;
match self.flags.replace(Dirtied::Released(*id)) {
Some(Dirtied::Assigned(_)) => { negated = true; }
_ => {}
}
if negated {
self.flags.remove(&*id);;
}
true
}
}
impl<'a, S> _EntityStoreIter<'a> for WithDirtyState<S>
where S: _EntityStoreIter<'a>
{
type Iter = S::Iter;
}
impl<S> EntityStoreIter for WithDirtyState<S>
where S: EntityStoreIter
{
fn iter<'a>(&'a self) -> <Self as _EntityStoreIter<'a>>::Iter {
self.store.iter()
}
}
pub type DirtyEntities<'a, ID: Id> = iter::Cloned<btree_set::Iter<'a, Dirtied<'a, ID>>>;
impl<'a, S> _StoreWithDirtyState<'a> for WithDirtyState<S>
where S: StoreBase
{
type DirtyEntities = DirtyEntities<'a, S::Id>;
}
impl<S> StoreWithDirtyState for WithDirtyState<S>
where S: StoreBase
{
fn was_cleared(&self) -> bool {
self.was_cleared
}
fn dirty_entities<'a>(&'a self) -> <Self as _StoreWithDirtyState<'a>>::DirtyEntities {
unsafe { ::std::mem::transmute(self.flags.iter().cloned()) }
}
}
impl<'a, S> IntoIterator for &'a WithDirtyState<S>
where S: StoreBase, &'a S: IntoIterator
{
type Item = <Self::IntoIter as Iterator>::Item;
type IntoIter = <&'a S as IntoIterator>::IntoIter;
fn into_iter(self) -> Self::IntoIter { self.store.into_iter() }
}