From d4e554241c5252331c5a850f257ae4ff3a2b710e Mon Sep 17 00:00:00 2001 From: Imbris Date: Sun, 28 Apr 2019 20:23:14 -0400 Subject: [PATCH] add load_expect, change error reporting Former-commit-id: 6064384b14e055701f11c3a1f4931aa6eb27adda --- common/src/assets/mod.rs | 75 +++++++++++++++++++++++-------------- voxygen/src/scene/figure.rs | 2 +- 2 files changed, 48 insertions(+), 29 deletions(-) diff --git a/common/src/assets/mod.rs b/common/src/assets/mod.rs index 3dfe59e872..99bbbc6db5 100644 --- a/common/src/assets/mod.rs +++ b/common/src/assets/mod.rs @@ -11,19 +11,21 @@ use std::{ #[derive(Debug, Clone)] pub enum Error { + /// An asset has already been loaded with this specifier but anot type InvalidType, - NotFound, + /// Asset does not exist + NotFound(String), } impl From> for Error { - fn from(_err: Arc) -> Self { + fn from(_: Arc) -> Self { Error::InvalidType } } impl From for Error { - fn from(_err: std::io::Error) -> Self { - Error::NotFound + fn from(err: std::io::Error) -> Self { + Error::NotFound(format!("{:?}", err)) } } @@ -33,13 +35,14 @@ lazy_static! { } /// Function used to load assets +/// loaded assets are cached in a global singleton hashmap /// Example usage: /// ``` /// use image::DynamicImage; +/// use common::assets; /// -/// let my_image = common::asset::load::("core.ui.backgrounds.city").unwrap(); +/// let my_image = assets::load::("core.ui.backgrounds.city").unwrap(); /// ``` -// TODO: consider assets that we only need in one place or that don't need to be kept in memory? pub fn load(specifier: &str) -> Result, Error> { Ok(ASSETS .write().unwrap() @@ -49,6 +52,21 @@ pub fn load(specifier: &str) -> Result, Error> { .downcast()?) } +/// Function used to load assets that will panic if the asset is not found +/// Use this to load essential assets +/// loaded assets are cached in a global singleton hashmap +/// Example usage: +/// ``` +/// use image::DynamicImage; +/// use common::assets; +/// +/// let my_image = assets::load_expect::("core.ui.backgrounds.city"); +/// ``` +pub fn load_expect(specifier: &str) -> Arc { + load(specifier) + .expect(&format!("Failed loading essential asset: {}", specifier)) +} + /// Asset Trait pub trait Asset: Send + Sync + Sized { fn load(specifier: &str) -> Result; @@ -75,41 +93,42 @@ impl Asset for DotVoxData { } // TODO: System to load file from specifiers (eg "core.ui.backgrounds.city") -fn try_load_from_path(name: &str) -> Option { - let basepaths = [ - [env!("CARGO_MANIFEST_DIR"), "/../assets"].concat(), - // if it's stupid and it works.., +fn try_open_with_path(name: &str) -> Option { + // if it's stupid and it works.., + [ "assets".to_string(), - "../../assets".to_string(), "../assets".to_string(), /* optimizations */ + "../../assets".to_string(), + [env!("CARGO_MANIFEST_DIR"), "/../assets"].concat(), [env!("CARGO_MANIFEST_DIR"), "/assets"].concat(), [env!("CARGO_MANIFEST_DIR"), "/../../assets"].concat(), "../../../assets".to_string(), [env!("CARGO_MANIFEST_DIR"), "/../../../assets"].concat(), - ]; - for bp in &basepaths { - let filename = [bp, name].concat(); - match File::open(&filename) { - Ok(f) => { - debug!("Loading {} successful", filename); - return Some(f); - }, - Err(e) => { - debug!("Loading {} failed: {}", filename, e); - } - }; - }; - None + ] + .into_iter() + .map(|bp| [bp, name].concat()) + .find_map(|ref filename| match File::open(filename) { + Ok(file) => { + debug!("Loading {} successful", filename); + Some(file) + } + Err(err) => { + error!("Loading {} failed: {}", filename, err); + None + } + }) } pub fn load_from_path(name: &str) -> Result, Error> { - match try_load_from_path(name) { + match try_open_with_path(name) { Some(mut f) => { - let mut content: Vec = vec!(); + let mut content = Vec::::new(); f.read_to_end(&mut content)?; Ok(content) }, - None => Err(Error::NotFound), + None => { + Err(Error::NotFound(name.to_owned())) + } } } diff --git a/voxygen/src/scene/figure.rs b/voxygen/src/scene/figure.rs index ce51b1b2d5..0754a73b34 100644 --- a/voxygen/src/scene/figure.rs +++ b/voxygen/src/scene/figure.rs @@ -101,7 +101,7 @@ impl FigureCache { fn load_mesh(filename: &str, position: Vec3) -> Mesh { let fullpath: String = ["/voxygen/voxel/", filename].concat(); Segment::from( - assets::load::(fullpath.as_str()).unwrap().as_ref() + assets::load_expect::(fullpath.as_str()).as_ref() ) .generate_mesh(position) }