use std::collections::HashMap;
use crate::entity::EntityId;
#[derive(Debug, Clone, Default)]
pub struct PrepareScratch<T: Default> {
inner: HashMap<EntityId, T>,
}
impl<T: Default> PrepareScratch<T> {
#[must_use]
pub fn new() -> Self {
Self {
inner: HashMap::new(),
}
}
#[must_use]
pub fn get(&self, eid: EntityId) -> Option<&T> {
self.inner.get(&eid)
}
pub fn get_mut(&mut self, eid: EntityId) -> Option<&mut T> {
self.inner.get_mut(&eid)
}
pub fn entry(&mut self, eid: EntityId) -> &mut T {
self.inner.entry(eid).or_default()
}
pub fn iter(&self) -> impl Iterator<Item = (EntityId, &T)> + '_ {
self.inner.iter().map(|(id, t)| (*id, t))
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = (EntityId, &mut T)> + '_ {
self.inner.iter_mut().map(|(id, t)| (*id, t))
}
pub fn values(&self) -> impl Iterator<Item = &T> + '_ {
self.inner.values()
}
pub fn values_mut(&mut self) -> impl Iterator<Item = &mut T> + '_ {
self.inner.values_mut()
}
pub fn insert(&mut self, eid: EntityId, value: T) -> Option<T> {
self.inner.insert(eid, value)
}
pub fn remove(&mut self, eid: EntityId) -> Option<T> {
self.inner.remove(&eid)
}
pub fn clear(&mut self) {
self.inner.clear();
}
#[must_use]
pub fn len(&self) -> usize {
self.inner.len()
}
#[must_use]
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
use slotmap::KeyData;
fn fake_id(idx: u64) -> EntityId {
EntityId::from(KeyData::from_ffi(idx))
}
#[test]
fn entry_inserts_default_then_returns_mut() {
#[derive(Default, Debug, PartialEq)]
struct CarStats {
counter: u32,
}
let mut scratch: PrepareScratch<CarStats> = PrepareScratch::new();
let id = fake_id(0x4242_0000_0000_0001);
scratch.entry(id).counter = 7;
assert_eq!(scratch.get(id).map(|s| s.counter), Some(7));
scratch.entry(id).counter += 5;
assert_eq!(scratch.get(id).map(|s| s.counter), Some(12));
}
#[test]
fn remove_returns_old_value_and_drops_entry() {
let mut scratch: PrepareScratch<u32> = PrepareScratch::new();
let id = fake_id(0x1234_0000_0000_0001);
scratch.insert(id, 99);
assert_eq!(scratch.remove(id), Some(99));
assert!(scratch.get(id).is_none());
assert!(scratch.is_empty());
}
}