Browse Source

automaticly reload when rsx requires it

Evan Almloff 3 years ago
parent
commit
61e9f56816
1 changed files with 32 additions and 27 deletions
  1. 32 27
      src/server/mod.rs

+ 32 - 27
src/server/mod.rs

@@ -7,7 +7,7 @@ use axum::{
     Router,
 };
 use notify::{RecommendedWatcher, Watcher};
-use std::{fs::File, io::Read};
+use std::{fs::File, io::Read, sync::Mutex};
 use syn::__private::ToTokens;
 
 use std::{path::PathBuf, sync::Arc};
@@ -23,10 +23,13 @@ use dioxus_rsx_interpreter::{error::RecompileReason, CodeLocation, SetRsxMessage
 
 struct WsReloadState {
     update: broadcast::Sender<String>,
+    last_file_rebuild: Arc<Mutex<HashMap<String, String>>>,
+    watcher_config: CrateConfig,
 }
 
 struct HotReloadState {
     messages: broadcast::Sender<SetRsxMessage>,
+    update: broadcast::Sender<String>,
 }
 
 pub async fn startup(config: CrateConfig) -> Result<()> {
@@ -36,20 +39,23 @@ pub async fn startup(config: CrateConfig) -> Result<()> {
 
     let (reload_tx, _) = broadcast::channel(100);
 
+    let last_file_rebuild = Arc::new(Mutex::new(HashMap::new()));
+
     let ws_reload_state = Arc::new(WsReloadState {
         update: reload_tx.clone(),
+        last_file_rebuild: last_file_rebuild.clone(),
+        watcher_config: config.clone(),
     });
 
     let hot_reload_tx = broadcast::channel(100).0;
     let hot_reload_state = Arc::new(HotReloadState {
         messages: hot_reload_tx.clone(),
+        update: reload_tx.clone(),
     });
 
     let mut last_update_time = chrono::Local::now().timestamp();
 
     // file watcher: check file change
-    let watcher_conf = config.clone();
-    let mut old_files_parsed: HashMap<String, String> = HashMap::new();
     let allow_watch_path = config
         .dioxus_config
         .web
@@ -64,7 +70,6 @@ pub async fn startup(config: CrateConfig) -> Result<()> {
         if let Ok(evt) = evt {
             if let notify::EventKind::Modify(_) = evt.kind {
                 for path in evt.paths {
-                    log::info!("File changed: {}", path.display());
                     let mut file = File::open(path.clone()).unwrap();
                     let mut src = String::new();
                     file.read_to_string(&mut src).expect("Unable to read file");
@@ -72,35 +77,19 @@ pub async fn startup(config: CrateConfig) -> Result<()> {
                         continue;
                     }
                     if let Ok(syntax) = syn::parse_file(&src) {
-                        if let Some(old_str) = old_files_parsed.get(path.to_str().unwrap()) {
+                        let mut last_file_rebuild = last_file_rebuild.lock().unwrap();
+                        if let Some(old_str) = last_file_rebuild.get(path.to_str().unwrap()) {
                             if let Ok(old) = syn::parse_file(&old_str) {
                                 match find_rsx(&syntax, &old) {
                                     crate::DiffResult::CodeChanged => {
                                         log::info!("reload required");
                                         if chrono::Local::now().timestamp() > last_update_time {
-                                            log::info!("Start to rebuild project...");
-                                            if builder::build(&watcher_conf).is_ok() {
-                                                // change the websocket reload state to true;
-                                                // the page will auto-reload.
-                                                if watcher_conf
-                                                    .dioxus_config
-                                                    .web
-                                                    .watcher
-                                                    .reload_html
-                                                    .unwrap_or(false)
-                                                {
-                                                    let _ = Serve::regen_dev_page(&watcher_conf);
-                                                }
-                                                let _ = reload_tx.send("reload".into());
-                                                old_files_parsed.insert(
-                                                    path.to_str().unwrap().to_string(),
-                                                    src,
-                                                );
-                                                last_update_time = chrono::Local::now().timestamp();
-                                            }
+                                            let _ = reload_tx.send("reload".into());
+                                            last_update_time = chrono::Local::now().timestamp();
                                         }
                                     }
                                     crate::DiffResult::RsxChanged(changed) => {
+                                        log::info!("reloading rsx");
                                         for (old, new) in changed.into_iter() {
                                             if let Some(hr) = old
                                                 .to_token_stream()
@@ -135,7 +124,7 @@ pub async fn startup(config: CrateConfig) -> Result<()> {
                                 }
                             }
                         } else {
-                            old_files_parsed.insert(path.to_str().unwrap().to_string(), src);
+                            last_file_rebuild.insert(path.to_str().unwrap().to_string(), src);
                         }
                     }
                 }
@@ -229,6 +218,22 @@ async fn ws_handler(
             loop {
                 let v = rx.recv().await.unwrap();
                 if v == "reload" {
+                    log::info!("Start to rebuild project...");
+                    if builder::build(&state.watcher_config).is_ok() {
+                        // change the websocket reload state to true;
+                        // the page will auto-reload.
+                        if state
+                            .watcher_config
+                            .dioxus_config
+                            .web
+                            .watcher
+                            .reload_html
+                            .unwrap_or(false)
+                        {
+                            let _ = Serve::regen_dev_page(&state.watcher_config);
+                        }
+                        *state.last_file_rebuild.lock().unwrap() = HashMap::new();
+                    }
                     // ignore the error
                     if socket
                         .send(Message::Text(String::from("reload")))
@@ -261,6 +266,7 @@ async fn hot_reload_handler(
                     if let Some(Ok(Message::Text(err))) = err {
                         let error: RecompileReason = serde_json::from_str(&err).unwrap();
                         log::error!("{:?}", error);
+                        state.update.send("reload".to_string()).unwrap();
                     };
                 },
                 set_rsx = read_set_rsx => {
@@ -272,7 +278,6 @@ async fn hot_reload_handler(
                         {
                             break;
                         };
-                        // println!("{:?}", rsx);
                     }
                 }
             };