use crate::{BUFFER_SIZE, MAX_BUFFERS};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BufferId(pub u32);
impl BufferId {
pub const SILENCE: Self = Self(u32::MAX);
}
pub struct BufferPool {
storage: Vec<f32>,
free_list: Vec<u32>,
capacity: usize,
}
impl BufferPool {
pub fn new(capacity: usize) -> Self {
let storage = vec![0.0f32; capacity * BUFFER_SIZE];
let free_list: Vec<u32> = (0..capacity as u32).rev().collect();
Self {
storage,
free_list,
capacity,
}
}
pub fn acquire(&mut self) -> Option<BufferId> {
let id = self.free_list.pop()?;
let start = id as usize * BUFFER_SIZE;
self.storage[start..start + BUFFER_SIZE].fill(0.0);
Some(BufferId(id))
}
pub fn release(&mut self, id: BufferId) {
debug_assert!((id.0 as usize) < self.capacity, "BufferId out of range");
self.free_list.push(id.0);
}
#[inline(always)]
pub fn get(&self, id: BufferId) -> &[f32; BUFFER_SIZE] {
let start = id.0 as usize * BUFFER_SIZE;
self.storage[start..start + BUFFER_SIZE].try_into().unwrap()
}
#[inline(always)]
pub fn get_mut(&mut self, id: BufferId) -> &mut [f32; BUFFER_SIZE] {
let start = id.0 as usize * BUFFER_SIZE;
(&mut self.storage[start..start + BUFFER_SIZE])
.try_into()
.unwrap()
}
pub fn silence() -> &'static [f32; BUFFER_SIZE] {
static SILENCE: [f32; BUFFER_SIZE] = [0.0f32; BUFFER_SIZE];
&SILENCE
}
pub fn available(&self) -> usize {
self.free_list.len()
}
pub fn capacity(&self) -> usize {
self.capacity
}
}
impl Default for BufferPool {
fn default() -> Self {
Self::new(MAX_BUFFERS)
}
}