mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Move the asset module to a single file
This commit is contained in:
parent
0cf164f33a
commit
d090eefb00
@ -1,182 +0,0 @@
|
||||
use crossbeam_channel::{select, unbounded, Receiver, Sender};
|
||||
use lazy_static::lazy_static;
|
||||
use notify::{Event, EventKind, RecommendedWatcher, RecursiveMode, Watcher as _};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
path::PathBuf,
|
||||
sync::{
|
||||
atomic::{AtomicBool, Ordering},
|
||||
Arc, Mutex, Weak,
|
||||
},
|
||||
thread,
|
||||
};
|
||||
use tracing::{error, warn};
|
||||
|
||||
type Handler = Box<dyn Fn() + Send>;
|
||||
|
||||
lazy_static! {
|
||||
static ref WATCHER_TX: Mutex<Sender<(PathBuf, Handler, Weak<AtomicBool>)>> =
|
||||
Mutex::new(Watcher::new().run());
|
||||
}
|
||||
|
||||
// This will need to be adjusted when specifier mapping to asset location
|
||||
// becomes more dynamic
|
||||
struct Watcher {
|
||||
watching: HashMap<PathBuf, (Handler, Vec<Weak<AtomicBool>>)>,
|
||||
watcher: RecommendedWatcher,
|
||||
event_rx: Receiver<Result<Event, notify::Error>>,
|
||||
}
|
||||
impl Watcher {
|
||||
fn new() -> Self {
|
||||
let (event_tx, event_rx) = unbounded();
|
||||
Watcher {
|
||||
watching: HashMap::new(),
|
||||
watcher: notify::Watcher::new_immediate(move |event| {
|
||||
let _ = event_tx.send(event);
|
||||
})
|
||||
.expect("Failed to create notify::Watcher"),
|
||||
event_rx,
|
||||
}
|
||||
}
|
||||
|
||||
fn watch(&mut self, path: PathBuf, handler: Handler, signal: Weak<AtomicBool>) {
|
||||
match self.watching.get_mut(&path) {
|
||||
Some((_, ref mut v)) => {
|
||||
if !v.iter().any(|s| match (s.upgrade(), signal.upgrade()) {
|
||||
(Some(arc1), Some(arc2)) => Arc::ptr_eq(&arc1, &arc2),
|
||||
_ => false,
|
||||
}) {
|
||||
v.push(signal);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
if let Err(e) = self.watcher.watch(path.clone(), RecursiveMode::Recursive) {
|
||||
warn!(?e, ?path, "Could not start watching file");
|
||||
return;
|
||||
}
|
||||
self.watching.insert(path, (handler, vec![signal]));
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_event(&mut self, event: Event) {
|
||||
if let Event {
|
||||
kind: EventKind::Modify(_),
|
||||
paths,
|
||||
..
|
||||
} = event
|
||||
{
|
||||
for path in paths {
|
||||
match self.watching.get_mut(&path) {
|
||||
Some((reloader, ref mut signals)) => {
|
||||
if !signals.is_empty() {
|
||||
// Reload this file
|
||||
reloader();
|
||||
|
||||
signals.retain(|signal| match signal.upgrade() {
|
||||
Some(signal) => {
|
||||
signal.store(true, Ordering::Release);
|
||||
true
|
||||
},
|
||||
None => false,
|
||||
});
|
||||
}
|
||||
// If there is no one to signal stop watching this path
|
||||
if signals.is_empty() {
|
||||
if let Err(err) = self.watcher.unwatch(&path) {
|
||||
warn!("Error unwatching: {}", err);
|
||||
}
|
||||
self.watching.remove(&path);
|
||||
}
|
||||
},
|
||||
None => {
|
||||
warn!(
|
||||
"Watching {:#?} but there are no signals for this path. The path will \
|
||||
be unwatched.",
|
||||
path
|
||||
);
|
||||
if let Err(err) = self.watcher.unwatch(&path) {
|
||||
warn!("Error unwatching: {}", err);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::drop_copy)] // TODO: Pending review in #587
|
||||
#[allow(clippy::single_match)] // TODO: Pending review in #587
|
||||
#[allow(clippy::zero_ptr)] // TODO: Pending review in #587
|
||||
fn run(mut self) -> Sender<(PathBuf, Handler, Weak<AtomicBool>)> {
|
||||
let (watch_tx, watch_rx) = unbounded();
|
||||
|
||||
thread::spawn(move || {
|
||||
loop {
|
||||
select! {
|
||||
recv(watch_rx) -> res => match res {
|
||||
Ok((path, handler, signal)) => self.watch(path, handler, signal),
|
||||
// Disconnected
|
||||
Err(_) => (),
|
||||
},
|
||||
recv(self.event_rx) -> res => match res {
|
||||
Ok(Ok(event)) => self.handle_event(event),
|
||||
// Notify Error
|
||||
Ok(Err(e)) => error!(?e, "Notify error"),
|
||||
// Disconnected
|
||||
Err(_) => (),
|
||||
},
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
watch_tx
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ReloadIndicator {
|
||||
reloaded: Arc<AtomicBool>,
|
||||
// Paths that have already been added
|
||||
paths: Vec<PathBuf>,
|
||||
}
|
||||
impl ReloadIndicator {
|
||||
#[allow(clippy::new_without_default)] // TODO: Pending review in #587
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
reloaded: Arc::new(AtomicBool::new(false)),
|
||||
paths: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add<F>(&mut self, path: PathBuf, reloader: F)
|
||||
where
|
||||
F: 'static + Fn() + Send,
|
||||
{
|
||||
// Check to see if this was already added
|
||||
if self.paths.iter().any(|p| *p == path) {
|
||||
// Nothing else needs to be done
|
||||
return;
|
||||
} else {
|
||||
self.paths.push(path.clone());
|
||||
};
|
||||
|
||||
if WATCHER_TX
|
||||
.lock()
|
||||
.unwrap()
|
||||
.send((path, Box::new(reloader), Arc::downgrade(&self.reloaded)))
|
||||
.is_err()
|
||||
{
|
||||
error!("Could not add. Asset watcher channel disconnected.");
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if the watched file was changed
|
||||
pub fn reloaded(&self) -> bool {
|
||||
// Optimize for the common case by performing an initial relaxed read, avoiding
|
||||
// the atomic write.
|
||||
if self.reloaded.load(Ordering::Relaxed) {
|
||||
self.reloaded.swap(false, Ordering::Acquire)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
@ -216,15 +216,6 @@ impl Item {
|
||||
.iter()
|
||||
.map(|spec| Self::new_from_asset(&spec))
|
||||
.collect()
|
||||
|
||||
/*
|
||||
let result = items
|
||||
.iter()
|
||||
.map(|item_def| Item::new(Arc::clone(item_def)))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Ok(result)
|
||||
*/
|
||||
}
|
||||
|
||||
/// Creates a new instance of an `Item from the provided asset identifier if
|
||||
|
@ -1465,7 +1465,7 @@ impl CharSelectionUi {
|
||||
pub fn update_language(&mut self, i18n: AssetHandle<Localization>) {
|
||||
let i18n = i18n.read();
|
||||
let font = ui::ice::load_font(&i18n.fonts.get("cyri").unwrap().asset_key);
|
||||
|
||||
|
||||
self.ui.clear_fonts(font);
|
||||
self.controls.fonts = Fonts::load(&i18n.fonts, &mut self.ui)
|
||||
.expect("Impossible to load fonts!");
|
||||
|
@ -121,7 +121,7 @@ struct Shaders {
|
||||
random: AssetHandle<Glsl>,
|
||||
lod: AssetHandle<Glsl>,
|
||||
shadows: AssetHandle<Glsl>,
|
||||
|
||||
|
||||
anti_alias_none: AssetHandle<Glsl>,
|
||||
anti_alias_fxaa: AssetHandle<Glsl>,
|
||||
anti_alias_msaa_x4: AssetHandle<Glsl>,
|
||||
@ -162,6 +162,8 @@ struct Shaders {
|
||||
}
|
||||
|
||||
impl assets::Compound for Shaders {
|
||||
// TODO: Taking the specifier argument as a base for shaders specifiers
|
||||
// would allow to use several shaders groups easily
|
||||
fn load<S: assets::source::Source>(_: &assets::AssetCache<S>, _: &str) -> Result<Shaders, assets::Error> {
|
||||
Ok(Shaders {
|
||||
constants: AssetExt::load("voxygen.shaders.include.constants")?,
|
||||
@ -186,7 +188,7 @@ impl assets::Compound for Shaders {
|
||||
terrain_directed_shadow_vert: AssetExt::load("voxygen.shaders.light-shadows-directed-vert")?,
|
||||
figure_directed_shadow_vert: AssetExt::load("voxygen.shaders.light-shadows-figure-vert")?,
|
||||
directed_shadow_frag: AssetExt::load("voxygen.shaders.light-shadows-directed-frag")?,
|
||||
|
||||
|
||||
skybox_vert: AssetExt::load("voxygen.shaders.skybox-vert")?,
|
||||
skybox_frag: AssetExt::load("voxygen.shaders.skybox-frag")?,
|
||||
figure_frag: AssetExt::load("voxygen.shaders.figure-frag")?,
|
||||
@ -210,7 +212,6 @@ impl assets::Compound for Shaders {
|
||||
player_shadow_frag: AssetExt::load("voxygen.shaders.player-shadow-frag")?,
|
||||
light_shadows_geom: AssetExt::load("voxygen.shaders.light-shadows-geom")?,
|
||||
light_shadows_frag: AssetExt::load("voxygen.shaders.light-shadows-frag")?,
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user