implement hot reloading for desktop
This commit is contained in:
1 parent
0e40619b52
commit
1073574896
9 files changed
+155
-32
No files matched your search
@@ -0,0 +1,84 @@
|
||||
use std::{
|
||||
io::Write,
|
||||
path::PathBuf,
|
||||
str::FromStr,
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
pub use dioxus_hot_reload_macro::hot_reload;
|
||||
use dioxus_html::HtmlCtx;
|
||||
use dioxus_rsx::hot_reload::{FileMap, UpdateResult};
|
||||
use interprocess::local_socket::LocalSocketListener;
|
||||
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
|
||||
|
||||
pub fn init(path: &'static str) {
|
||||
if let Ok(crate_dir) = PathBuf::from_str(path) {
|
||||
let temp_file = std::env::temp_dir().join("@dioxusin");
|
||||
let channels = Arc::new(Mutex::new(Vec::new()));
|
||||
if let Ok(local_socket_stream) = LocalSocketListener::bind(temp_file.as_path()) {
|
||||
// listen for connections
|
||||
std::thread::spawn({
|
||||
let channels = channels.clone();
|
||||
move || {
|
||||
for connection in local_socket_stream.incoming() {
|
||||
if let Ok(connection) = connection {
|
||||
channels.lock().unwrap().push(connection);
|
||||
println!("Connected to hot reloading 🚀");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// watch for changes
|
||||
std::thread::spawn(move || {
|
||||
let mut last_update_time = chrono::Local::now().timestamp();
|
||||
let mut file_map = FileMap::<HtmlCtx>::new(crate_dir.clone());
|
||||
|
||||
let (tx, rx) = std::sync::mpsc::channel();
|
||||
|
||||
let mut watcher = RecommendedWatcher::new(tx, notify::Config::default()).unwrap();
|
||||
|
||||
let mut examples_path = crate_dir.clone();
|
||||
examples_path.push("examples");
|
||||
let _ = watcher.watch(&examples_path, RecursiveMode::Recursive);
|
||||
let mut src_path = crate_dir.clone();
|
||||
src_path.push("src");
|
||||
let _ = watcher.watch(&src_path, RecursiveMode::Recursive);
|
||||
|
||||
for evt in rx {
|
||||
// Give time for the change to take effect before reading the file
|
||||
std::thread::sleep(std::time::Duration::from_millis(100));
|
||||
if chrono::Local::now().timestamp() > last_update_time {
|
||||
if let Ok(evt) = evt {
|
||||
let mut channels = channels.lock().unwrap();
|
||||
for path in &evt.paths {
|
||||
// skip non rust files
|
||||
if path.extension().and_then(|p| p.to_str()) != Some("rs") {
|
||||
continue;
|
||||
}
|
||||
|
||||
// find changes to the rsx in the file
|
||||
match file_map.update_rsx(&path, crate_dir.as_path()) {
|
||||
UpdateResult::UpdatedRsx(msgs) => {
|
||||
for msg in msgs {
|
||||
for channel in channels.iter_mut() {
|
||||
let msg = serde_json::to_string(&msg).unwrap();
|
||||
channel.write_all(msg.as_bytes()).unwrap();
|
||||
channel.write_all(&[b'\n']).unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
UpdateResult::NeedsRebuild => {
|
||||
println!("Rebuild needed... shutting down hot reloading");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
last_update_time = chrono::Local::now().timestamp();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user