Skip to content

Commit

Permalink
Some work on IO and VFS
Browse files Browse the repository at this point in the history
  • Loading branch information
mattkleiny committed Jul 15, 2024
1 parent 0d8f328 commit dc43986
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 54 deletions.
29 changes: 19 additions & 10 deletions crates/common/src/abstractions/assets.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
//! Asset management for the engine
/// An error that can occur when loading an asset
#[derive(Debug)]
pub enum AssetError {
/// The asset could not be found
NotFound,
/// The asset could not be loaded
LoadFailed,
/// The asset is not of the expected type
TypeMismatch,
}
use crate::{FileSystemError, FromStream, ToVirtualPath};

/// Represents an asset that can be loaded and used by the engine
pub trait Asset {}

/// A manager for assets
#[derive(Default)]
pub struct AssetManager {}

impl AssetManager {
/// Loads an asset from the given path
pub fn load<A: Asset + FromStream>(&self, path: impl ToVirtualPath) -> Result<A, AssetError> {
let path = path.to_virtual_path();
let mut stream = path.open_input_stream().map_err(|_| AssetError::NotFound)?;

A::from_stream(&mut stream).map_err(|_| AssetError::LoadFailed)
}
}

/// An error that can occur when loading an asset
#[derive(Debug)]
pub enum AssetError {
NotFound,
LoadFailed,
TypeMismatch,
}
53 changes: 38 additions & 15 deletions crates/common/src/io/streams.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,54 @@ use crate::{FileSystemError, ToVirtualPath};

/// Allows a type to be imported from a VFS stream.
pub trait FromStream: Sized {
/// Imports the type from a stream.
fn from_stream(stream: &mut dyn InputStream) -> Result<Self, FileSystemError>;

/// Imports the type from a path.
fn from_path(path: impl ToVirtualPath) -> Result<Self, FileSystemError> {
fn from_path(path: impl ToVirtualPath) -> Result<Self, StreamError> {
let path = path.to_virtual_path();
let mut stream = path.open_input_stream()?;

Self::from_stream(&mut stream)
}

/// Imports the type from a byte array.
fn from_bytes(bytes: &[u8]) -> Result<Self, StreamError> {
let mut stream = std::io::Cursor::new(bytes);

Self::from_stream(&mut stream)
}

/// Imports the type from a stream.
fn from_stream(stream: &mut dyn InputStream) -> Result<Self, StreamError>;
}

/// Allows a type to be exported to a VFS stream.
pub trait ToStream: Sized {
/// Exports the type to a stream.
fn to_stream(&self, stream: &mut dyn OutputStream) -> Result<(), FileSystemError>;

/// Exports the type to a path.
fn to_path(&self, path: impl ToVirtualPath) -> Result<(), FileSystemError> {
fn to_path(&self, path: impl ToVirtualPath) -> Result<(), StreamError> {
let path = path.to_virtual_path();
let mut stream = path.open_output_stream()?;

self.to_stream(&mut stream)
}

/// Exports the type to a byte array.
fn to_bytes(&self) -> Result<Vec<u8>, StreamError> {
let mut stream = std::io::Cursor::new(Vec::new());

self.to_stream(&mut stream)?;

Ok(stream.into_inner())
}

/// Exports the type to a stream.
fn to_stream(&self, stream: &mut dyn OutputStream) -> Result<(), StreamError>;
}

/// Represents an error that occurred while reading or writing to a stream.
#[derive(Debug)]
pub enum StreamError {
UnexpectedEof,
UnexpectedEncoding,
FailedToDeserialize,
GeneralFailure,
}

impl From<std::io::Error> for StreamError {
Expand All @@ -52,6 +68,13 @@ impl From<std::string::FromUtf8Error> for StreamError {
}
}

impl From<FileSystemError> for StreamError {
#[inline]
fn from(_: FileSystemError) -> Self {
Self::GeneralFailure
}
}

/// A stream for reading from some [`VirtualPath`].
pub trait InputStream: Seek + BufRead {
fn read_u8(&mut self) -> Result<u8, StreamError>;
Expand All @@ -70,8 +93,8 @@ pub trait InputStream: Seek + BufRead {
fn read_f64(&mut self) -> Result<f64, StreamError>;
fn read_string(&mut self) -> Result<String, StreamError>;
fn read_bytes(&mut self, amount: usize) -> Result<Vec<u8>, StreamError>;
fn to_buffer(&mut self) -> Result<Vec<u8>, StreamError>;
fn to_string(&mut self) -> Result<String, StreamError>;
fn to_buffer(self) -> Result<Vec<u8>, StreamError>;
fn to_string(self) -> Result<String, StreamError>;
}

macro_rules! impl_read {
Expand Down Expand Up @@ -113,7 +136,7 @@ impl<T: BufRead + Seek> InputStream for T {

#[inline]
fn read_usize(&mut self) -> Result<usize, StreamError> {
impl_read!(self, std::mem::size_of::<usize>(), usize)
impl_read!(self, size_of::<usize>(), usize)
}

#[inline]
Expand Down Expand Up @@ -143,7 +166,7 @@ impl<T: BufRead + Seek> InputStream for T {

#[inline]
fn read_isize(&mut self) -> Result<isize, StreamError> {
impl_read!(self, std::mem::size_of::<isize>(), isize)
impl_read!(self, size_of::<isize>(), isize)
}

#[inline]
Expand Down Expand Up @@ -173,15 +196,15 @@ impl<T: BufRead + Seek> InputStream for T {
Ok(buffer)
}

fn to_buffer(&mut self) -> Result<Vec<u8>, StreamError> {
fn to_buffer(mut self) -> Result<Vec<u8>, StreamError> {
let mut buffer = Vec::new();

self.read_to_end(&mut buffer)?;

Ok(buffer)
}

fn to_string(&mut self) -> Result<String, StreamError> {
fn to_string(mut self) -> Result<String, StreamError> {
let mut buffer = String::new();

self.read_to_string(&mut buffer)?;
Expand Down
51 changes: 24 additions & 27 deletions crates/common/src/io/virtualfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,6 @@ use crate::{Singleton, StringName, ToStringName};
mod local;
mod memory;

/// A potential error that can occur when interacting with a [`FileSystem`].
#[derive(Debug)]
pub enum FileSystemError {
GeneralError(std::io::Error),
StreamError(super::StreamError),
}

impl From<std::io::Error> for FileSystemError {
#[inline]
fn from(error: std::io::Error) -> Self {
Self::GeneralError(error)
}
}

impl From<super::StreamError> for FileSystemError {
#[inline]
fn from(error: super::StreamError) -> Self {
Self::StreamError(error)
}
}

/// Represents a type capable of acting as a file system.
///
/// File systems are resolved from the scheme used in [`VirtualPath`]s, and
Expand Down Expand Up @@ -187,17 +166,14 @@ impl VirtualPath {

/// Attempts to read all bytes from the given path.
pub fn read_all_bytes(&self) -> Result<Vec<u8>, FileSystemError> {
let mut buffer = Vec::new();
let mut stream = self.open_input_stream()?;

stream.read_to_end(&mut buffer)?;
let stream = self.open_input_stream()?;

Ok(buffer)
Ok(stream.to_buffer()?)
}

/// Attempts to read all text from the given path.
pub fn read_all_text(&self) -> Result<String, FileSystemError> {
let mut stream = self.open_input_stream()?;
let stream = self.open_input_stream()?;

Ok(stream.to_string()?)
}
Expand Down Expand Up @@ -251,6 +227,27 @@ impl Into<VirtualPath> for String {
}
}

/// A potential error that can occur when interacting with a [`FileSystem`].
#[derive(Debug)]
pub enum FileSystemError {
GeneralError(std::io::Error),
StreamError(super::StreamError),
}

impl From<std::io::Error> for FileSystemError {
#[inline]
fn from(error: std::io::Error) -> Self {
Self::GeneralError(error)
}
}

impl From<super::StreamError> for FileSystemError {
#[inline]
fn from(error: super::StreamError) -> Self {
Self::StreamError(error)
}
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
4 changes: 2 additions & 2 deletions crates/graphics/src/fonts/otf.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use common::{FastHashMap, FileSystemError, FromStream, InputStream};
use common::{FastHashMap, FromStream, InputStream, StreamError};

/// A single glyph in an OpenType font.
struct OpenTypeGlyph {}
Expand All @@ -9,7 +9,7 @@ pub struct OpenTypeFont {
}

impl FromStream for OpenTypeFont {
fn from_stream(stream: &mut dyn InputStream) -> Result<Self, FileSystemError> {
fn from_stream(stream: &mut dyn InputStream) -> Result<Self, StreamError> {
let _a = stream.read_u16()?;
let _b = stream.read_u16()?;

Expand Down

0 comments on commit dc43986

Please sign in to comment.