Something went wrong. Try again.
modern vulkan rust rhi
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105//! Generational resource pool.//! Handles are a packed (index, generation) u64 where 0 is never valid —//! zero-initialized handles fail lookup instead of aliasing slot 0 (ZII).
pub(crate) struct Pool<T> { slots: Vec<Slot<T>>, free: Vec<u32>,}
struct Slot<T> { generation: u32, value: Option<T>,}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]pub struct PoolHandle(pub(crate) u64);
impl PoolHandle { pub(crate) fn pack(idx: u32, generation: u32) -> Self { Self(((generation as u64) << 32) | idx as u64) } fn idx(self) -> u32 { self.0 as u32 } fn generation(self) -> u32 { (self.0 >> 32) as u32 } // The public handle newtypes (Semaphore, CommandBuffer, ...) are // pointer-sized; pool handles ride in them bit-for-bit, preserving // ZII (null pointer == null handle). pub(crate) fn to_ptr(self) -> *mut core::ffi::c_void { self.0 as usize as *mut core::ffi::c_void } pub(crate) fn from_ptr(p: *mut core::ffi::c_void) -> Self { Self(p as usize as u64) }}
impl<T> Default for Pool<T> { fn default() -> Self { Self { slots: Vec::new(), free: Vec::new(), } }}
impl<T> Pool<T> { pub fn add(&mut self, value: T) -> PoolHandle { match self.free.pop() { Some(idx) => { let slot = &mut self.slots[idx as usize]; slot.value = Some(value); PoolHandle::pack(idx, slot.generation) } None => { // Generation starts at 1 so (idx 0, first generation) never packs to 0. self.slots.push(Slot { generation: 1, value: Some(value), }); PoolHandle::pack(self.slots.len() as u32 - 1, 1) } } }
pub fn get(&self, handle: PoolHandle) -> Option<&T> { let slot = self.slots.get(handle.idx() as usize)?; if slot.generation != handle.generation() { return None; } slot.value.as_ref() }
pub fn get_mut(&mut self, handle: PoolHandle) -> Option<&mut T> { let slot = self.slots.get_mut(handle.idx() as usize)?; if slot.generation != handle.generation() { return None; } slot.value.as_mut() }
pub fn iter(&self) -> impl Iterator<Item = &T> { self.slots.iter().filter_map(|slot| slot.value.as_ref()) }
pub fn drain_values(&mut self) -> impl Iterator<Item = T> + '_ { self.free.clear(); self.slots.drain(..).filter_map(|slot| slot.value) }
pub fn remove(&mut self, handle: PoolHandle) -> Option<T> { let slot = self.slots.get_mut(handle.idx() as usize)?; if slot.generation != handle.generation() { return None; } let value = slot.value.take(); if value.is_some() { slot.generation = slot.generation.wrapping_add(1).max(1); self.free.push(handle.idx()); } value }}