add arena library

This commit is contained in:
Corwin 2022-10-02 14:52:35 +01:00
parent 88e1635fb1
commit 5d21f720a5
2 changed files with 101 additions and 0 deletions

100
agb/src/arena.rs Normal file
View file

@ -0,0 +1,100 @@
use alloc::vec::Vec;
pub struct Arena<T> {
first: Option<usize>,
data: Vec<Item<T>>,
}
enum Item<T> {
Next {
next: Option<usize>,
generation: usize,
},
Item {
item: T,
generation: usize,
},
}
#[derive(Debug, Clone, Copy)]
pub struct Index {
generation: usize,
index: usize,
}
impl<T> Arena<T> {
#[must_use]
pub fn new() -> Self {
Arena {
first: None,
data: Vec::new(),
}
}
pub fn remove(&mut self, idx: Index) {
if let Item::Item {
item: _,
generation,
} = self.data[idx.index]
{
if generation != idx.generation {
return;
}
self.data[idx.index] = Item::Next {
next: self.first,
generation,
};
self.first = Some(idx.index);
}
}
pub fn get_mut(&mut self, idx: Index) -> Option<&mut T> {
match &mut self.data[idx.index] {
Item::Next {
next: _,
generation: _,
} => None,
Item::Item { item, generation } => {
if *generation == idx.generation {
Some(item)
} else {
None
}
}
}
}
pub fn insert(&mut self, data: T) -> Index {
match self.first {
Some(idx) => {
let (next, generation) = match &self.data[idx] {
Item::Next { next, generation } => (*next, *generation),
_ => unreachable!(),
};
self.data[idx] = Item::Item {
item: data,
generation: generation + 1,
};
self.first = next;
Index {
generation: generation + 1,
index: idx,
}
}
None => {
self.data.push(Item::Item {
item: data,
generation: 0,
});
Index {
generation: 0,
index: self.data.len() - 1,
}
}
}
}
}
impl<T> Default for Arena<T> {
fn default() -> Self {
Self::new()
}
}

View file

@ -164,6 +164,7 @@ mod memory_mapped;
pub mod mgba;
#[doc(inline)]
pub use agb_fixnum as fixnum;
pub mod arena;
/// Contains an implementation of a hashmap which suits the gameboy advance's hardware.
pub mod hash_map;
/// Simple random number generator