use super::{IRenderDataPayload, RenderDataOpcode};
use crate::rendering::composition::transport::BatchValue;
#[derive(Debug, Default)]
pub struct RenderDataWriter {
buffer: Option<Vec<u8>>,
length: usize,
}
impl RenderDataWriter {
pub fn new() -> Self {
Self::default()
}
pub fn length(&self) -> usize {
self.length
}
pub fn written(&self) -> &[u8] {
match &self.buffer {
Some(buffer) => &buffer[..self.length],
None => &[],
}
}
fn buffer(buffer: &mut Option<Vec<u8>>, length: usize) -> &mut Vec<u8> {
let buffer = buffer.get_or_insert_with(|| Vec::with_capacity(256));
buffer.truncate(length);
buffer
}
fn advance(&mut self, size: usize) -> &mut [u8] {
let start = self.length;
self.length = start + size;
let buffer = Self::buffer(&mut self.buffer, start);
buffer.resize(start + size, 0);
&mut buffer[start..]
}
pub fn reserve(&mut self, count: usize) -> &mut [u8] {
self.advance(count)
}
pub fn rewind(&mut self, length: usize) {
self.length = length;
}
pub fn write<T: BatchValue>(&mut self, value: T) {
let buffer = Self::buffer(&mut self.buffer, self.length);
value.write_to(buffer);
self.length = buffer.len();
}
pub fn write_opcode(&mut self, opcode: RenderDataOpcode) {
self.write(opcode);
}
pub fn write_payload<T: IRenderDataPayload>(&mut self, payload: T) {
self.write(T::OPCODE);
self.write(payload);
}
pub fn dispose(&mut self) {
self.buffer = None;
self.length = 0;
}
}