mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Windows is weird, cargo is weird..... (also tidy up a few things)
This commit is contained in:
parent
18e6b59966
commit
124ed52554
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -4606,6 +4606,7 @@ version = "0.6.0"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"libloading 0.6.2",
|
||||
"log",
|
||||
"notify",
|
||||
"vek",
|
||||
"veloren-common",
|
||||
|
@ -9,7 +9,7 @@ name = "voxygen_anim"
|
||||
crate-type = ["lib", "cdylib"]
|
||||
|
||||
[features]
|
||||
use-dyn-lib = ["libloading", "notify", "lazy_static"]
|
||||
use-dyn-lib = ["libloading", "notify", "lazy_static", "log"]
|
||||
be-dyn-lib = []
|
||||
|
||||
default = ["be-dyn-lib"]
|
||||
@ -20,4 +20,4 @@ common = { package = "veloren-common", path = "../../../common" }
|
||||
libloading = { version = "0.6.2", optional = true }
|
||||
notify = { version = "5.0.0-pre.2", optional = true }
|
||||
lazy_static = { version = "1.4.0", optional = true }
|
||||
|
||||
log = { version = "0.4.8", optional = true }
|
||||
|
@ -3,7 +3,9 @@ use libloading::Library;
|
||||
use notify::{immediate_watcher, EventKind, RecursiveMode, Watcher};
|
||||
use std::{
|
||||
process::{Command, Stdio},
|
||||
sync::Mutex,
|
||||
sync::{mpsc, Mutex},
|
||||
thread,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
lazy_static! {
|
||||
@ -17,21 +19,17 @@ pub struct LoadedLib {
|
||||
impl LoadedLib {
|
||||
fn compile_load() -> Self {
|
||||
// Compile
|
||||
let _output = Command::new("cargo")
|
||||
.stderr(Stdio::inherit())
|
||||
.stdout(Stdio::inherit())
|
||||
.arg("build")
|
||||
.arg("--package")
|
||||
.arg("veloren-voxygen-anim")
|
||||
.output()
|
||||
.unwrap();
|
||||
compile();
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
copy();
|
||||
|
||||
Self::load()
|
||||
}
|
||||
|
||||
fn load() -> Self {
|
||||
#[cfg(target_os = "windows")]
|
||||
let lib = Library::new("../target/debug/voxygen_anim.dll").unwrap();
|
||||
let lib = Library::new("../target/debug/voxygen_anim_active.dll").unwrap();
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let lib = Library::new("../target/debug/libvoxygen_anim.so").unwrap();
|
||||
|
||||
@ -41,8 +39,11 @@ impl LoadedLib {
|
||||
|
||||
// Starts up watcher
|
||||
pub fn init() {
|
||||
// Make sure first compile is done
|
||||
drop(LIB.lock());
|
||||
|
||||
// TODO: use crossbeam
|
||||
let (reload_send, reload_recv) = std::sync::mpsc::channel();
|
||||
let (reload_send, reload_recv) = mpsc::channel();
|
||||
|
||||
// Start watcher
|
||||
let mut watcher = immediate_watcher(move |res| event_fn(res, &reload_send)).unwrap();
|
||||
@ -51,10 +52,24 @@ pub fn init() {
|
||||
// Start reloader that watcher signals
|
||||
// "Debounces" events since I can't find the option to do this in the latest
|
||||
// `notify`
|
||||
std::thread::spawn(move || {
|
||||
while let Ok(()) = reload_recv.recv() {
|
||||
// Wait for another modify event before reloading
|
||||
while let Ok(()) = reload_recv.recv_timeout(std::time::Duration::from_millis(300)) {}
|
||||
thread::spawn(move || {
|
||||
let mut modified_paths = std::collections::HashSet::new();
|
||||
|
||||
while let Ok(path) = reload_recv.recv() {
|
||||
modified_paths.insert(path);
|
||||
// Wait for to see if there are more modify events before reloading
|
||||
while let Ok(path) = reload_recv.recv_timeout(Duration::from_millis(300)) {
|
||||
modified_paths.insert(path);
|
||||
}
|
||||
|
||||
let mut info = "Hot reloading animations because these files were modified:".to_owned();
|
||||
for path in std::mem::take(&mut modified_paths) {
|
||||
info.push('\n');
|
||||
info.push('\"');
|
||||
info.push_str(&path);
|
||||
info.push('\"');
|
||||
}
|
||||
log::warn!("{}", info);
|
||||
|
||||
// Reload
|
||||
reload();
|
||||
@ -67,32 +82,48 @@ pub fn init() {
|
||||
|
||||
// Recompiles and hotreloads the lib if the source is changed
|
||||
// Note: designed with voxygen dir as working dir, could be made more flexible
|
||||
fn event_fn(res: notify::Result<notify::Event>, sender: &std::sync::mpsc::Sender<()>) {
|
||||
fn event_fn(res: notify::Result<notify::Event>, sender: &mpsc::Sender<String>) {
|
||||
match res {
|
||||
Ok(event) => match event.kind {
|
||||
EventKind::Modify(_) => {
|
||||
if event
|
||||
event
|
||||
.paths
|
||||
.iter()
|
||||
.any(|p| p.extension().map(|e| e == "rs").unwrap_or(false))
|
||||
{
|
||||
println!(
|
||||
"Hot reloading animations because these files were modified:\n{:?}",
|
||||
event.paths
|
||||
);
|
||||
|
||||
.filter(|p| p.extension().map(|e| e == "rs").unwrap_or(false))
|
||||
.map(|p| p.to_string_lossy().into_owned())
|
||||
// Signal reloader
|
||||
let _ = sender.send(());
|
||||
}
|
||||
.for_each(|p| { let _ = sender.send(p); });
|
||||
},
|
||||
_ => {},
|
||||
},
|
||||
Err(e) => println!("watch error: {:?}", e),
|
||||
Err(e) => log::error!("Animation hotreload watch error: {:?}", e),
|
||||
}
|
||||
}
|
||||
|
||||
fn reload() {
|
||||
// Compile
|
||||
// Stop if recompile failed
|
||||
if !compile() {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut lock = LIB.lock().unwrap();
|
||||
|
||||
// Close lib
|
||||
lock.take().unwrap().lib.close().unwrap();
|
||||
|
||||
// Rename lib file on windows
|
||||
// Called after closing lib so file will be unlocked
|
||||
#[cfg(target_os = "windows")]
|
||||
copy();
|
||||
|
||||
// Open new lib
|
||||
*lock = Some(LoadedLib::load());
|
||||
|
||||
log::warn!("Updated animations");
|
||||
}
|
||||
|
||||
// Returns false if compile failed
|
||||
fn compile() -> bool {
|
||||
let output = Command::new("cargo")
|
||||
.stderr(Stdio::inherit())
|
||||
.stdout(Stdio::inherit())
|
||||
@ -102,21 +133,23 @@ fn reload() {
|
||||
.output()
|
||||
.unwrap();
|
||||
|
||||
// Stop if recompile failed
|
||||
// If compile failed
|
||||
if !output.status.success() {
|
||||
println!("Failed to compile anim crate");
|
||||
return;
|
||||
log::error!("Failed to compile anim crate");
|
||||
false
|
||||
} else {
|
||||
log::warn!("Animation recompile success!!");
|
||||
true
|
||||
}
|
||||
|
||||
println!("Compile Success!!");
|
||||
|
||||
let mut lock = LIB.lock().unwrap();
|
||||
|
||||
// Close lib
|
||||
lock.take().unwrap().lib.close().unwrap();
|
||||
|
||||
// Open new lib
|
||||
*lock = Some(LoadedLib::load());
|
||||
|
||||
println!("Updated");
|
||||
}
|
||||
|
||||
// Copy lib file if on windows since loading the lib locks the file blocking
|
||||
// future compilation
|
||||
#[cfg(target_os = "windows")]
|
||||
fn copy() {
|
||||
std::fs::copy(
|
||||
"../target/debug/voxygen_anim.dll",
|
||||
"../target/debug/voxygen_anim_active.dll",
|
||||
)
|
||||
.expect("Failed to rename animations dll");
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ pub mod quadruped_small;
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
pub use dyn_lib::init;
|
||||
|
||||
#[cfg(feature = "use-dyn-lib")]
|
||||
use std::ffi::CStr;
|
||||
use vek::*;
|
||||
|
||||
// TODO: replace with inner type everywhere
|
||||
@ -83,7 +85,16 @@ pub trait Skeleton: Send + Sync + 'static {
|
||||
let lib = &lock.as_ref().unwrap().lib;
|
||||
|
||||
let compute_fn: libloading::Symbol<fn(&Self) -> ([FigureBoneData; 16], Vec3<f32>)> =
|
||||
unsafe { lib.get(Self::COMPUTE_FN).unwrap() };
|
||||
unsafe { lib.get(Self::COMPUTE_FN) }.unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"Trying to use: {} but had error: {:?}",
|
||||
CStr::from_bytes_with_nul(Self::COMPUTE_FN)
|
||||
.map(CStr::to_str)
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
err
|
||||
)
|
||||
});
|
||||
|
||||
compute_fn(self)
|
||||
}
|
||||
@ -135,10 +146,20 @@ pub trait Animation {
|
||||
> = unsafe {
|
||||
//let start = std::time::Instant::now();
|
||||
// Overhead of 0.5-5 us (could use hashmap to mitigate if this is an issue)
|
||||
let f = lib.get(Self::UPDATE_FN).unwrap();
|
||||
let f = lib.get(Self::UPDATE_FN);
|
||||
//println!("{}", start.elapsed().as_nanos());
|
||||
f
|
||||
};
|
||||
}
|
||||
.unwrap_or_else(|err| {
|
||||
panic!(
|
||||
"Trying to use: {} but had error: {:?}",
|
||||
CStr::from_bytes_with_nul(Self::UPDATE_FN)
|
||||
.map(CStr::to_str)
|
||||
.unwrap()
|
||||
.unwrap(),
|
||||
err
|
||||
)
|
||||
});
|
||||
|
||||
update_fn(skeleton, dependency, anim_time, rate, skeleton_attr)
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use crate::{
|
||||
render::{FigurePipeline, Mesh, Model, Renderer},
|
||||
scene::camera::CameraMode,
|
||||
};
|
||||
use anim::{Skeleton};
|
||||
use anim::Skeleton;
|
||||
use common::{
|
||||
assets::watch::ReloadIndicator,
|
||||
comp::{
|
||||
|
@ -2103,21 +2103,21 @@ impl<S: Skeleton> FigureState<S> {
|
||||
|
||||
fn figure_bone_data_from_anim(mats: [anim::FigureBoneData; 16]) -> [FigureBoneData; 16] {
|
||||
[
|
||||
FigureBoneData::new(mats[0].0),
|
||||
FigureBoneData::new(mats[1].0),
|
||||
FigureBoneData::new(mats[2].0),
|
||||
FigureBoneData::new(mats[3].0),
|
||||
FigureBoneData::new(mats[4].0),
|
||||
FigureBoneData::new(mats[5].0),
|
||||
FigureBoneData::new(mats[6].0),
|
||||
FigureBoneData::new(mats[7].0),
|
||||
FigureBoneData::new(mats[8].0),
|
||||
FigureBoneData::new(mats[9].0),
|
||||
FigureBoneData::new(mats[10].0),
|
||||
FigureBoneData::new(mats[11].0),
|
||||
FigureBoneData::new(mats[12].0),
|
||||
FigureBoneData::new(mats[13].0),
|
||||
FigureBoneData::new(mats[14].0),
|
||||
FigureBoneData::new(mats[15].0),
|
||||
FigureBoneData::new(mats[0].0),
|
||||
FigureBoneData::new(mats[1].0),
|
||||
FigureBoneData::new(mats[2].0),
|
||||
FigureBoneData::new(mats[3].0),
|
||||
FigureBoneData::new(mats[4].0),
|
||||
FigureBoneData::new(mats[5].0),
|
||||
FigureBoneData::new(mats[6].0),
|
||||
FigureBoneData::new(mats[7].0),
|
||||
FigureBoneData::new(mats[8].0),
|
||||
FigureBoneData::new(mats[9].0),
|
||||
FigureBoneData::new(mats[10].0),
|
||||
FigureBoneData::new(mats[11].0),
|
||||
FigureBoneData::new(mats[12].0),
|
||||
FigureBoneData::new(mats[13].0),
|
||||
FigureBoneData::new(mats[14].0),
|
||||
FigureBoneData::new(mats[15].0),
|
||||
]
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user