use crate::common::chunk::Chunk;
pub const CHUNK_SIZE_U8: usize = 32768;
pub const CHUNK_SIZE_F32: usize = 8192;
#[derive(Clone, Copy, Debug)]
pub struct ChunkBuilder<T, const N: usize> {
pub data: [T; N],
pub position: usize,
}
impl<T: Default + Copy, const N: usize> ChunkBuilder<T, N> {
#[must_use]
pub fn new() -> Self {
Self {
data: [T::default(); N],
position: 0,
}
}
pub fn extend_from_slice<'a>(&mut self, slice: &'a [T]) -> Option<&'a [T]> {
let remaining = Self::space_remaining(self);
if slice.len() <= remaining {
self.data[self.position..self.position + slice.len()].copy_from_slice(slice);
self.position += slice.len();
None
} else {
self.data[self.position..].copy_from_slice(&slice[..remaining]);
self.position += remaining;
Some(&slice[remaining..])
}
}
pub fn reset_with_overflow(&mut self, slice: &[T]) {
self.data[..slice.len()].copy_from_slice(slice);
self.position = slice.len();
}
pub fn unfilled_mut(&mut self) -> &mut [T] {
&mut self.data[self.position..]
}
pub const fn space_remaining(&self) -> usize {
N - self.position
}
}
impl<'a> From<&'a ChunkBuilder<u8, CHUNK_SIZE_U8>> for Chunk<'a> {
fn from(builder: &'a ChunkBuilder<u8, CHUNK_SIZE_U8>) -> Self {
unsafe {
let ptr = builder.data.as_ptr().cast::<[f32; CHUNK_SIZE_F32]>();
Self(&*ptr)
}
}
}
impl<'a> From<&'a ChunkBuilder<f32, CHUNK_SIZE_F32>> for Chunk<'a> {
fn from(builder: &'a ChunkBuilder<f32, CHUNK_SIZE_F32>) -> Self {
Self(&builder.data)
}
}
impl<T: Default + Copy, const N: usize> Default for ChunkBuilder<T, N> {
fn default() -> Self {
Self::new()
}
}
impl ChunkBuilder<u8, CHUNK_SIZE_U8> {
#[must_use]
pub fn new_u8() -> Self {
Self::new()
}
}
impl ChunkBuilder<f32, CHUNK_SIZE_F32> {
#[must_use]
pub fn new_f32() -> Self {
Self::new()
}
}