use std::fmt::{Display, Formatter};
#[derive(Copy,Clone,Debug,PartialEq,Eq)]
pub struct Handle{
pub index: usize,
pub generation: usize,
}
impl Display for Handle {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "[index:{},gen:{}]", self.index, self.generation)
}
}
impl Default for Handle{
fn default() -> Self {
Handle{ index:0, generation:0}
}
}
pub trait IHandleArrayItem{
fn get_handle(&self)->Handle;
fn set_handle(&mut self,handle:Handle);
}
pub struct HandleArray<T:IHandleArrayItem>
{
data: Vec<T>,
free_list:Vec<Handle>,
alive:usize,
}
impl<T:IHandleArrayItem + Default> HandleArray<T>{
pub fn new(capacity:usize) -> HandleArray<T>{
HandleArray{
data:Vec::with_capacity(capacity),
free_list:Vec::with_capacity(capacity),
alive:0,
}
}
pub fn add_item(&mut self, item:T)-> Handle{
let mut item = item;
if self.free_list.len() > 0 {
let handle = self.free_list.pop().unwrap();
item.set_handle(handle);
self.data[handle.index]=item;
self.alive += 1;
return handle;
}
if self.alive == 0{
self.data.push(T::default());
}
let h = Handle{ index:self.alive+1, generation:0};
item.set_handle(h);
self.data.push(item);
self.alive += 1;
h
}
pub fn remove_item(&mut self, handle:Handle){
self.data[handle.index] = T::default();
let mut handle = handle;
handle.generation += 1;
self.free_list.push(handle);
self.alive -=1;
}
pub fn get(&self,handle: Handle)->&T{
&self.data[handle.index]
}
pub fn get_mut(&mut self,handle: Handle)->&mut T{
&mut self.data[handle.index]
}
pub fn iter(&self) -> std::slice::Iter<'_,T>{
self.data.iter()
}
pub fn iter_mut(&mut self) -> std::slice::IterMut<'_,T>{
self.data.iter_mut()
}
pub fn alive_iter(&self)->HandleArrayIter<'_,T>{
HandleArrayIter{
data:&self.data,
index:0,
}
}
pub fn alive_iter_mut(&mut self)->HandleArrayIterMut<'_,T>{
HandleArrayIterMut{
data:self.data.iter_mut(),
index:0,
}
}
}
pub struct HandleArrayIter<'a,T:IHandleArrayItem>
{
data:&'a [T],
index:usize,
}
pub struct HandleArrayIterMut<'a,T:IHandleArrayItem>
{
data:std::slice::IterMut<'a, T>,
index:usize,
}
impl<'a,T:IHandleArrayItem> Iterator for HandleArrayIter<'a,T>{
type Item = (usize,&'a T);
fn next(&mut self) -> Option<Self::Item> {
while self.index < self.data.len() {
let i = self.index;
self.index += 1;
if i== 0{
continue;
}
let item = &self.data[i];
if item.get_handle().index == 0 {
continue;
}
return Some((i,item));
}
None
}
}
impl<'a, T:IHandleArrayItem> Iterator for HandleArrayIterMut<'a, T>{
type Item = (usize,&'a mut T);
fn next(&mut self) -> Option<Self::Item> {
while let Some(item) = self.data.next(){
let i = self.index;
self.index += 1;
if i== 0{
continue;
}
if item.get_handle().index == 0{
continue;
}
return Some((i,item));
}
None
}
}