implement hot reloading for desktop

This commit is contained in:
Evan Almloff committed 2023-01-11 13:40:02 -06:00
1 parent 0e40619b52
commit 1073574896
9 files changed
+155 -32

No files matched your search

+84
View File
@@ -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();
}
}
});
}
}
}