use std::ops::Deref; use crate::util::{Id, IdNum, IdTracker}; pub struct Arena { data: Vec, tracker: IdTracker, } impl Arena { pub fn new() -> Self { Self { data: Vec::new(), tracker: IdTracker::default(), } } pub fn push(&mut self, value: T) -> Id { let id = self.tracker.next(); let i = id.idx(); if i == self.data.len() { self.data.push(value); } else { self.data[i] = value; } id } pub fn remove(&mut self, id: Id) -> T where T: Copy, { let i = id.idx(); self.tracker.free(id); self.data[i] } } impl Default for Arena { fn default() -> Self { Self::new() } } pub struct TrackedArena { inner: Arena, refs: Vec, pub changed: bool, } impl TrackedArena { pub fn new() -> Self { Self { inner: Arena::default(), refs: Vec::new(), changed: true, } } pub fn push(&mut self, value: T) -> Id { self.changed = true; let id = self.inner.push(value); let i = id.idx(); if i == self.refs.len() { self.refs.push(0); } id } pub fn push_ref(&mut self, i: Id) { self.refs[i.idx()] += 1; } pub fn remove(&mut self, id: Id) -> T where T: Copy, { let i = id.idx(); self.refs[i] -= 1; if self.refs[i] == 0 { self.changed = true; self.inner.remove(id) } else { self[i] } } } impl Default for TrackedArena { fn default() -> Self { Self::new() } } impl Deref for TrackedArena { type Target = Vec; fn deref(&self) -> &Self::Target { &self.inner.data } } impl Deref for Arena { type Target = Vec; fn deref(&self) -> &Self::Target { &self.data } }