use crate::resources::GpuMesh;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct MeshId(pub(crate) usize);
impl MeshId {
pub fn from_index(index: usize) -> Self {
Self(index)
}
pub fn index(&self) -> usize {
self.0
}
}
pub(crate) struct MeshStore {
slots: Vec<Option<GpuMesh>>,
free_list: Vec<usize>,
}
impl MeshStore {
pub fn new() -> Self {
Self {
slots: Vec::new(),
free_list: Vec::new(),
}
}
pub fn insert(&mut self, mesh: GpuMesh) -> MeshId {
if let Some(idx) = self.free_list.pop() {
self.slots[idx] = Some(mesh);
MeshId(idx)
} else {
let idx = self.slots.len();
self.slots.push(Some(mesh));
MeshId(idx)
}
}
pub fn get(&self, id: MeshId) -> Option<&GpuMesh> {
self.slots.get(id.0)?.as_ref()
}
pub fn get_mut(&mut self, id: MeshId) -> Option<&mut GpuMesh> {
self.slots.get_mut(id.0)?.as_mut()
}
pub fn replace(&mut self, id: MeshId, mesh: GpuMesh) -> crate::error::ViewportResult<()> {
match self.slots.get_mut(id.0) {
Some(slot) if slot.is_some() => {
*slot = Some(mesh);
Ok(())
}
_ => Err(crate::error::ViewportError::MeshSlotEmpty { index: id.0 }),
}
}
pub fn remove(&mut self, id: MeshId) -> bool {
if let Some(slot) = self.slots.get_mut(id.0) {
if slot.is_some() {
*slot = None;
self.free_list.push(id.0);
return true;
}
}
false
}
pub fn len(&self) -> usize {
self.slots.iter().filter(|s| s.is_some()).count()
}
pub fn slot_count(&self) -> usize {
self.slots.len()
}
pub fn contains(&self, id: MeshId) -> bool {
self.get(id).is_some()
}
}