byte-engine-resource-management 0.1.0

Asset, resource, shader, and storage management for Byte-Engine.
use super::reader::ResourceReader;

pub type MultiResourceReader = Box<dyn ResourceReader>;

#[cfg(test)]
pub mod tests {
	use crate::{
		resource::{
			reader::{ResourceReader, ResourceReaderBacking},
			ReadTargets, ReadTargetsMut,
		},
		StreamDescription,
	};

	#[derive(Debug)]
	pub struct MemoryResourceReader {
		data: Box<[u8]>,
	}

	impl MemoryResourceReader {
		pub fn new(data: Box<[u8]>) -> Self {
			Self { data }
		}
	}

	impl ResourceReader for MemoryResourceReader {
		fn read_into<'b, 'c: 'b, 'a: 'b>(
			&mut self,
			stream_descriptions: Option<&'c [StreamDescription]>,
			read_target: ReadTargetsMut<'a>,
		) -> Result<ReadTargets<'a>, ()> {
			match read_target {
				ReadTargetsMut::Buffer { buffer, offset, size } => {
					let read_len = size
						.unwrap_or(buffer.len())
						.min(buffer.len())
						.min(self.data.len().saturating_sub(offset));
					buffer[..read_len].copy_from_slice(&self.data[offset..][..read_len]);
					Ok(ReadTargets::Buffer(&buffer[..read_len]))
				}
				ReadTargetsMut::Box {
					mut buffer,
					offset,
					size,
				} => {
					let read_len = size
						.unwrap_or(buffer.len())
						.min(buffer.len())
						.min(self.data.len().saturating_sub(offset));
					buffer[..read_len].copy_from_slice(&self.data[offset..][..read_len]);
					if read_len < buffer.len() {
						let mut v = buffer.into_vec();
						v.truncate(read_len);
						Ok(ReadTargets::Box(v.into_boxed_slice()))
					} else {
						Ok(ReadTargets::Box(buffer))
					}
				}
				ReadTargetsMut::Streams(mut streams) => {
					if let Some(stream_descriptions) = stream_descriptions {
						for sd in stream_descriptions {
							let stream_offset = sd.offset;
							if let Some(s) = streams.iter_mut().find(|s| s.name() == sd.name) {
								let offset = s.offset();
								let read_len = s
									.size()
									.unwrap_or(s.buffer().len())
									.min(s.buffer().len())
									.min(self.data.len().saturating_sub(stream_offset + offset));
								s.buffer_mut()[..read_len].copy_from_slice(&self.data[(stream_offset + offset)..][..read_len]);
							}
						}

						Ok(ReadTargets::Streams(
							streams.into_iter().map(|stream| stream.into()).collect(),
						))
					} else {
						Err(())
					}
				}
				ReadTargetsMut::BackingStorage => Ok(ReadTargets::Backing(ResourceReaderBacking::Buffer(self.data.clone()))),
			}
		}

		fn into_backing_storage(self: Box<Self>) -> Result<ResourceReaderBacking, Box<dyn ResourceReader>> {
			Ok(ResourceReaderBacking::Buffer(self.data))
		}
	}
}