diff --git a/demo/build.rs b/demo/build.rs new file mode 100644 index 0000000..b67f22c --- /dev/null +++ b/demo/build.rs @@ -0,0 +1,30 @@ +use std::env; +use std::fs::File; +use std::io::{Read, Write}; +use std::path::Path; +use std::time::{SystemTime, UNIX_EPOCH}; + +fn main() { + let lib_name = "reloadable"; + + let cargo_manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + let cargo_toml_path = Path::new(&cargo_manifest_dir).join("Cargo.toml"); + + let mut cargo_toml_src = File::open(&cargo_toml_path).unwrap(); + let mut data = String::new(); + cargo_toml_src.read_to_string(&mut data).unwrap(); + drop(cargo_toml_src); + + let search = format!("name = \"{}", lib_name); + let line = data.lines().find(|l| l.contains(&search)); + + if let Some(line) = line { + let epoch_time = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + let replace = format!("name = \"{}_{}\"", lib_name, epoch_time.as_secs()); + + let mut cargo_toml_dst = File::create(&cargo_toml_path).unwrap(); + cargo_toml_dst + .write(data.replace(line, &replace).as_bytes()) + .unwrap(); + } +} diff --git a/src/lib.rs b/src/lib.rs index d003206..49b6eca 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -276,12 +276,15 @@ impl Reloadable { /// /// [`live_reload!`]: macro.live_reload.html pub fn new>(path: P, host: Host) -> Result { - let sym = AppSym::new(&path)?; + let sym = AppSym::new(find_latest_path(&path))?; + let size = (unsafe { &**sym.api }.size)(); let (tx, rx) = channel(); let mut watcher = notify::watcher(tx, Duration::from_secs(1))?; + let mut new_path = PathBuf::new(); new_path.push(path); + watcher.watch( new_path.parent().unwrap(), notify::RecursiveMode::NonRecursive, @@ -313,10 +316,8 @@ impl Reloadable { while let Ok(evt) = self.rx.try_recv() { use notify::DebouncedEvent::*; match evt { - NoticeWrite(ref path) | - Write(ref path) | - Create(ref path) => { - if *path == self.path { + NoticeWrite(ref path) | Write(ref path) | Create(ref path) => { + if *path == find_latest_path(&self.path) { should_reload = true; } } @@ -344,8 +345,11 @@ impl Reloadable { if let Some(AppSym { ref mut api, .. }) = self.sym { (unsafe { &***api }.unload)(&mut self.host, Self::get_state_ptr(&mut self.state)); } + + let path = find_latest_path(&self.path); + self.sym = None; - let sym = AppSym::new(&self.path)?; + let sym = AppSym::new(path)?; // @Avoid reallocating if unnecessary self.realloc_buffer((unsafe { &**sym.api }.size)()); (unsafe { &**sym.api }.reload)(&mut self.host, Self::get_state_ptr(&mut self.state)); @@ -532,3 +536,39 @@ macro_rules! live_reload { }; } } + +fn find_latest_path>(path: P) -> PathBuf { + let path = path.as_ref(); + + let paths = { + let file_stem = path.file_stem(); + let ext = path.extension(); + + std::fs::read_dir(path.parent().unwrap()) + .unwrap() + .filter(|e| e.is_ok()) + .map(|e| e.unwrap().path()) + .filter(|path| { + let file_stem2 = path.file_stem(); + let ext2 = path.extension(); + + match (file_stem, ext, file_stem2, ext2) { + (Some(file_stem), Some(ext), Some(file_stem2), Some(ext2)) => { + file_stem2 + .to_str() + .unwrap() + .starts_with(&format!("{}_", file_stem.to_str().unwrap())) + && ext == ext2 + } + _ => false, + } + }) + .collect::>() + }; + + if paths.len() == 0 { + path.to_path_buf() + } else { + paths.iter().max_by_key(|p| p.file_stem()).unwrap().clone() + } +}