extern crate log;
use std::slice::Iter;
use derive_deref::{Deref, DerefMut};
#[derive(Debug)]
pub struct LayerDirty<T> {
dirtys: Vec<Vec<T>>, count: usize, start: usize, end: usize, }
impl<T: Eq> Default for LayerDirty<T> {
fn default() -> LayerDirty<T> {
LayerDirty {
dirtys: vec![Vec::new()],
count: 0,
start: 0,
end: 0,
}
}
}
impl<T: Eq> LayerDirty<T> {
pub fn count(&self) -> usize {
self.count
}
pub fn mark(&mut self, id: T, layer: usize) {
self.count += 1;
if self.start > layer {
self.start = layer;
}
if self.end <= layer {
self.end = layer + 1;
}
if self.dirtys.len() <= layer {
for _ in self.dirtys.len()..layer + 1 {
self.dirtys.push(Vec::new())
}
}
let vec = unsafe { self.dirtys.get_unchecked_mut(layer) };
vec.push(id);
}
pub fn delete(&mut self, id: T, layer: usize) {
let vec = unsafe { self.dirtys.get_unchecked_mut(layer) };
for i in 0..vec.len() {
if vec[i] == id {
vec.swap_remove(i);
self.count -= 1;
break;
}
}
}
pub fn iter(&self) -> DirtyIterator<T> {
if self.count == 0 {
DirtyIterator {
inner: self,
layer: self.start,
iter: self.dirtys[0].iter(),
}
} else {
DirtyIterator {
inner: self,
layer: self.start + 1,
iter: self.dirtys[self.start].iter(),
}
}
}
pub fn iter_reverse(&self) -> ReverseDirtyIterator<T> {
if self.count == 0 {
ReverseDirtyIterator {
inner: self,
layer: self.start,
iter: self.dirtys[0].iter(),
}
} else {
ReverseDirtyIterator {
inner: self,
layer: self.end - 1,
iter: self.dirtys[self.end - 1].iter(),
}
}
}
pub fn clear(&mut self) {
while self.start < self.end {
let vec = unsafe { self.dirtys.get_unchecked_mut(self.start) };
self.start += 1;
vec.clear();
}
self.count = 0;
self.end = 0;
}
pub fn end (&self) -> usize {
self.end
}
pub fn start (&self) -> usize {
self.start
}
pub fn split(&mut self, layer: usize) -> (PreDirty<T>, NextDirty<T>) {
if layer >= self.dirtys.len() {
panic!("LayerDirty split fail, layer:{}, dirty_len:{}", layer, self.dirtys.len())
}
let vec = unsafe { &mut * (self.dirtys.get_unchecked_mut(layer) as *mut Vec<T>) };
(PreDirty {dirtys: self, out_index: layer}, NextDirty {dirtys: vec})
}
}
pub struct DirtyIterator<'a, T> {
inner: &'a LayerDirty<T>,
layer: usize,
iter: Iter<'a, T>,
}
impl<'a, T: Eq> Iterator for DirtyIterator<'a, T> {
type Item = (&'a T, usize);
fn next(&mut self) -> Option<Self::Item> {
let mut r = self.iter.next();
if r == None {
let len = self.inner.dirtys.len();
while self.layer < len {
let vec = unsafe { self.inner.dirtys.get_unchecked(self.layer) };
self.layer += 1;
if vec.len() > 0 {
self.iter = vec.iter();
r = self.iter.next();
break;
}
}
}
match r {
Some(r) => Some((r, self.layer - 1)),
None => None,
}
}
}
pub struct ReverseDirtyIterator<'a, T> {
inner: &'a LayerDirty<T>,
layer: usize,
iter: Iter<'a, T>,
}
impl<'a, T: Eq> Iterator for ReverseDirtyIterator<'a, T> {
type Item = (&'a T, usize);
fn next(&mut self) -> Option<Self::Item> {
let mut r = self.iter.next();
if r == None {
while self.layer > 0 {
let vec = unsafe { self.inner.dirtys.get_unchecked(self.layer - 1) };
self.layer -= 1;
if vec.len() > 0 {
self.iter = vec.iter();
r = self.iter.next();
break;
}
}
}
match r {
Some(r) => Some((r, self.layer)),
None => None,
}
}
}
#[derive(Deref, DerefMut)]
pub struct NextDirty<'a, T> {
dirtys: &'a mut Vec<T>,
}
pub struct PreDirty<'a, T> {
dirtys: &'a mut LayerDirty<T>,
out_index: usize, }
impl<'a, T: Eq> PreDirty<'a, T>{
pub fn mark(&mut self, id: T, layer: usize) {
if layer == self.out_index {
return;
}
self.dirtys.mark(id, layer);
}
pub fn delete(&mut self, id: T, layer: usize) {
if layer == self.out_index {
return;
}
self.dirtys.delete(id, layer);
}
}