mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-24 08:41:34 +11:00
add arena library
This commit is contained in:
parent
88e1635fb1
commit
5d21f720a5
100
agb/src/arena.rs
Normal file
100
agb/src/arena.rs
Normal 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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -164,6 +164,7 @@ mod memory_mapped;
|
||||||
pub mod mgba;
|
pub mod mgba;
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use agb_fixnum as fixnum;
|
pub use agb_fixnum as fixnum;
|
||||||
|
pub mod arena;
|
||||||
/// Contains an implementation of a hashmap which suits the gameboy advance's hardware.
|
/// Contains an implementation of a hashmap which suits the gameboy advance's hardware.
|
||||||
pub mod hash_map;
|
pub mod hash_map;
|
||||||
/// Simple random number generator
|
/// Simple random number generator
|
||||||
|
|
Loading…
Reference in a new issue