qecs 0.0.7

Soon to be highly flexible Entity-Component-System framework, core lib.
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 {
        // TODO
        //self.store.values_mut()
        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 {
        // TODO
        //self.store.iter_mut()
        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 {
        // FIXME lifetime-problems, too lazy to fix right now. we should return a iter::Map.
        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() }
}

// TODO
/*impl<'a, S> IntoIterator for &'a mut 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 { 
        unimplemented!()
    }
}*/