mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
96 lines
3.0 KiB
Rust
96 lines
3.0 KiB
Rust
use std::{borrow::Cow, io};
|
|
|
|
use assets_manager::{
|
|
hot_reloading::{DynUpdateSender, EventSender, FsWatcherBuilder},
|
|
source::{DirEntry, FileSystem as RawFs, Source},
|
|
BoxedError,
|
|
};
|
|
|
|
/// Loads assets from the default path or `VELOREN_ASSETS_OVERRIDE` env if it is
|
|
/// set.
|
|
#[derive(Debug, Clone)]
|
|
pub struct FileSystem {
|
|
default: RawFs,
|
|
override_dir: Option<RawFs>,
|
|
}
|
|
|
|
impl FileSystem {
|
|
pub fn new() -> io::Result<Self> {
|
|
let default = RawFs::new(&*super::ASSETS_PATH)?;
|
|
let override_dir = std::env::var_os("VELOREN_ASSETS_OVERRIDE").and_then(|path| {
|
|
RawFs::new(path)
|
|
.map_err(|err| tracing::error!("Error setting override assets directory: {}", err))
|
|
.ok()
|
|
});
|
|
|
|
Ok(Self {
|
|
default,
|
|
override_dir,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl Source for FileSystem {
|
|
fn read(&self, id: &str, ext: &str) -> io::Result<Cow<[u8]>> {
|
|
if let Some(dir) = &self.override_dir {
|
|
match dir.read(id, ext) {
|
|
Ok(content) => return Ok(content),
|
|
Err(err) => {
|
|
if err.kind() != io::ErrorKind::NotFound {
|
|
let path = dir.path_of(DirEntry::File(id, ext));
|
|
tracing::warn!(
|
|
"Error reading \"{}\": {}. Falling back to default",
|
|
path.display(),
|
|
err
|
|
);
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
// If not found in override path, try load from main asset path
|
|
self.default.read(id, ext)
|
|
}
|
|
|
|
fn read_dir(&self, id: &str, f: &mut dyn FnMut(DirEntry)) -> io::Result<()> {
|
|
if let Some(dir) = &self.override_dir {
|
|
match dir.read_dir(id, f) {
|
|
Ok(()) => return Ok(()),
|
|
Err(err) => {
|
|
if err.kind() != io::ErrorKind::NotFound {
|
|
let path = dir.path_of(DirEntry::Directory(id));
|
|
tracing::warn!(
|
|
"Error reading \"{}\": {}. Falling back to default",
|
|
path.display(),
|
|
err
|
|
);
|
|
}
|
|
},
|
|
}
|
|
}
|
|
|
|
// If not found in override path, try load from main asset path
|
|
self.default.read_dir(id, f)
|
|
}
|
|
|
|
fn exists(&self, entry: DirEntry) -> bool {
|
|
self.override_dir
|
|
.as_ref()
|
|
.map_or(false, |dir| dir.exists(entry))
|
|
|| self.default.exists(entry)
|
|
}
|
|
|
|
fn make_source(&self) -> Option<Box<dyn Source + Send>> { Some(Box::new(self.clone())) }
|
|
|
|
fn configure_hot_reloading(&self, events: EventSender) -> Result<DynUpdateSender, BoxedError> {
|
|
let mut builder = FsWatcherBuilder::new()?;
|
|
|
|
if let Some(dir) = &self.override_dir {
|
|
builder.watch(dir.root().to_owned())?;
|
|
}
|
|
builder.watch(self.default.root().to_owned())?;
|
|
|
|
Ok(builder.build(events))
|
|
}
|
|
}
|