// Safe reusable slots. Logical handles are indices, not Goose references. pub struct SlotPool { pub items: Vec, free: Vec } impl SlotPool { pub fn new() -> Self { Self { items: Vec::new(), free: Vec::new() } } pub fn alloc(&mut self, value: T) -> usize { if let Some(i) = self.free.pop() { self.items[i] = value; i } else { let i = self.items.len(); self.items.push(value); i } } pub fn free(&mut self, i: usize) { assert!(i < self.items.len()); assert!(!self.free.contains(&i), "slot already returned"); self.free.push(i); // does not drop or invalidate the stored T } }