Procházet zdrojové kódy

fix web imports and extract hot reload handlers into seperate files (#484)

Demonthos před 3 roky
rodič
revize
3a5d1a2ff8

+ 1 - 86
packages/desktop/src/controller.rs

@@ -52,92 +52,7 @@ impl DesktopController {
 
                 // allow other proccesses to send the new rsx text to the @dioxusin ipc channel and recieve erros on the @dioxusout channel
                 #[cfg(feature = "hot-reload")]
-                {
-                    use dioxus_rsx_interpreter::{
-                        error::Error, ErrorHandler, SetManyRsxMessage, RSX_CONTEXT,
-                    };
-                    use interprocess::local_socket::{LocalSocketListener, LocalSocketStream};
-                    use std::io::{BufRead, BufReader, Write};
-                    use std::time::Duration;
-
-                    fn handle_error(
-                        connection: std::io::Result<LocalSocketStream>,
-                    ) -> Option<LocalSocketStream> {
-                        connection
-                            .map_err(|error| eprintln!("Incoming connection failed: {}", error))
-                            .ok()
-                    }
-
-                    let latest_in_connection: Arc<Mutex<Option<BufReader<LocalSocketStream>>>> =
-                        Arc::new(Mutex::new(None));
-                    let latest_in_connection_handle = latest_in_connection.clone();
-                    let latest_out_connection: Arc<Mutex<Option<BufReader<LocalSocketStream>>>> =
-                        Arc::new(Mutex::new(None));
-                    let latest_out_connection_handle = latest_out_connection.clone();
-
-                    struct DesktopErrorHandler {
-                        latest_connection: Arc<Mutex<Option<BufReader<LocalSocketStream>>>>,
-                    }
-                    impl ErrorHandler for DesktopErrorHandler {
-                        fn handle_error(&self, err: Error) {
-                            if let Some(conn) = &mut *self.latest_connection.lock().unwrap() {
-                                conn.get_mut()
-                                    .write_all(
-                                        (serde_json::to_string(&err).unwrap() + "\n").as_bytes(),
-                                    )
-                                    .unwrap();
-                            } else {
-                                panic!("{}", err);
-                            }
-                        }
-                    }
-
-                    RSX_CONTEXT.set_error_handler(DesktopErrorHandler {
-                        latest_connection: latest_out_connection_handle,
-                    });
-                    RSX_CONTEXT.provide_scheduler_channel(dom.get_scheduler_channel());
-
-                    // connect to processes for incoming data
-                    std::thread::spawn(move || {
-                        if let Ok(listener) = LocalSocketListener::bind("@dioxusin") {
-                            for conn in listener.incoming().filter_map(handle_error) {
-                                *latest_in_connection_handle.lock().unwrap() =
-                                    Some(BufReader::new(conn));
-                            }
-                        }
-                    });
-
-                    // connect to processes for outgoing errors
-                    std::thread::spawn(move || {
-                        if let Ok(listener) = LocalSocketListener::bind("@dioxusout") {
-                            for conn in listener.incoming().filter_map(handle_error) {
-                                *latest_out_connection.lock().unwrap() = Some(BufReader::new(conn));
-                            }
-                        }
-                    });
-
-                    std::thread::spawn(move || {
-                        loop {
-                            if let Some(conn) = &mut *latest_in_connection.lock().unwrap() {
-                                let mut buf = String::new();
-                                match conn.read_line(&mut buf) {
-                                    Ok(_) => {
-                                        let msgs: SetManyRsxMessage =
-                                            serde_json::from_str(&buf).unwrap();
-                                        RSX_CONTEXT.extend(msgs);
-                                    }
-                                    Err(err) => {
-                                        if err.kind() != std::io::ErrorKind::WouldBlock {
-                                            break;
-                                        }
-                                    }
-                                }
-                            }
-                            // give the error handler time to take the mutex
-                            std::thread::sleep(Duration::from_millis(100));
-                        }
-                    });
-                }
+                crate::hot_reload::init(&dom);
 
                 let edits = dom.rebuild();
 

+ 80 - 0
packages/desktop/src/hot_reload.rs

@@ -0,0 +1,80 @@
+use dioxus_core::VirtualDom;
+use dioxus_rsx_interpreter::{error::Error, ErrorHandler, SetManyRsxMessage, RSX_CONTEXT};
+use interprocess::local_socket::{LocalSocketListener, LocalSocketStream};
+use std::io::{BufRead, BufReader, Write};
+use std::time::Duration;
+use std::{sync::Arc, sync::Mutex};
+
+fn handle_error(connection: std::io::Result<LocalSocketStream>) -> Option<LocalSocketStream> {
+    connection
+        .map_err(|error| eprintln!("Incoming connection failed: {}", error))
+        .ok()
+}
+
+pub(crate) fn init(dom: &VirtualDom) {
+    let latest_in_connection: Arc<Mutex<Option<BufReader<LocalSocketStream>>>> =
+        Arc::new(Mutex::new(None));
+    let latest_in_connection_handle = latest_in_connection.clone();
+    let latest_out_connection: Arc<Mutex<Option<BufReader<LocalSocketStream>>>> =
+        Arc::new(Mutex::new(None));
+    let latest_out_connection_handle = latest_out_connection.clone();
+
+    struct DesktopErrorHandler {
+        latest_connection: Arc<Mutex<Option<BufReader<LocalSocketStream>>>>,
+    }
+    impl ErrorHandler for DesktopErrorHandler {
+        fn handle_error(&self, err: Error) {
+            if let Some(conn) = &mut *self.latest_connection.lock().unwrap() {
+                conn.get_mut()
+                    .write_all((serde_json::to_string(&err).unwrap() + "\n").as_bytes())
+                    .unwrap();
+            } else {
+                panic!("{}", err);
+            }
+        }
+    }
+
+    RSX_CONTEXT.set_error_handler(DesktopErrorHandler {
+        latest_connection: latest_out_connection_handle,
+    });
+    RSX_CONTEXT.provide_scheduler_channel(dom.get_scheduler_channel());
+
+    // connect to processes for incoming data
+    std::thread::spawn(move || {
+        if let Ok(listener) = LocalSocketListener::bind("@dioxusin") {
+            for conn in listener.incoming().filter_map(handle_error) {
+                *latest_in_connection_handle.lock().unwrap() = Some(BufReader::new(conn));
+            }
+        }
+    });
+
+    // connect to processes for outgoing errors
+    std::thread::spawn(move || {
+        if let Ok(listener) = LocalSocketListener::bind("@dioxusout") {
+            for conn in listener.incoming().filter_map(handle_error) {
+                *latest_out_connection.lock().unwrap() = Some(BufReader::new(conn));
+            }
+        }
+    });
+
+    std::thread::spawn(move || {
+        loop {
+            if let Some(conn) = &mut *latest_in_connection.lock().unwrap() {
+                let mut buf = String::new();
+                match conn.read_line(&mut buf) {
+                    Ok(_) => {
+                        let msgs: SetManyRsxMessage = serde_json::from_str(&buf).unwrap();
+                        RSX_CONTEXT.extend(msgs);
+                    }
+                    Err(err) => {
+                        if err.kind() != std::io::ErrorKind::WouldBlock {
+                            break;
+                        }
+                    }
+                }
+            }
+            // give the error handler time to take the mutex
+            std::thread::sleep(Duration::from_millis(100));
+        }
+    });
+}

+ 2 - 0
packages/desktop/src/lib.rs

@@ -8,6 +8,8 @@ mod controller;
 mod desktop_context;
 mod escape;
 mod events;
+#[cfg(feature = "hot-reload")]
+mod hot_reload;
 mod protocol;
 
 use desktop_context::UserWindowEvent;

+ 68 - 0
packages/web/src/hot_reload.rs

@@ -0,0 +1,68 @@
+use dioxus_core::VirtualDom;
+use dioxus_rsx_interpreter::error::Error;
+use dioxus_rsx_interpreter::{ErrorHandler, SetManyRsxMessage, RSX_CONTEXT};
+use futures_channel::mpsc::unbounded;
+use futures_channel::mpsc::UnboundedSender;
+use futures_util::StreamExt;
+use wasm_bindgen::closure::Closure;
+use wasm_bindgen::JsCast;
+use web_sys::{console, MessageEvent, WebSocket};
+
+pub(crate) fn init(dom: &VirtualDom) {
+    let window = web_sys::window().unwrap();
+
+    let protocol = if window.location().protocol().unwrap() == "https:" {
+        "wss:"
+    } else {
+        "ws:"
+    };
+
+    let url = format!(
+        "{protocol}//{}/_dioxus/hot_reload",
+        window.location().host().unwrap()
+    );
+
+    let ws = WebSocket::new(&url).unwrap();
+
+    // change the rsx when new data is received
+    let cl = Closure::wrap(Box::new(|e: MessageEvent| {
+        if let Ok(text) = e.data().dyn_into::<js_sys::JsString>() {
+            let msgs: SetManyRsxMessage = serde_json::from_str(&format!("{text}")).unwrap();
+            RSX_CONTEXT.extend(msgs);
+        }
+    }) as Box<dyn FnMut(MessageEvent)>);
+
+    ws.set_onmessage(Some(cl.as_ref().unchecked_ref()));
+    cl.forget();
+
+    let (error_channel_sender, mut error_channel_receiver) = unbounded();
+
+    struct WebErrorHandler {
+        sender: UnboundedSender<Error>,
+    }
+
+    impl ErrorHandler for WebErrorHandler {
+        fn handle_error(&self, err: dioxus_rsx_interpreter::error::Error) {
+            self.sender.unbounded_send(err).unwrap();
+        }
+    }
+
+    RSX_CONTEXT.set_error_handler(WebErrorHandler {
+        sender: error_channel_sender,
+    });
+
+    RSX_CONTEXT.provide_scheduler_channel(dom.get_scheduler_channel());
+
+    // forward stream to the websocket
+    dom.base_scope().spawn_forever(async move {
+        while let Some(err) = error_channel_receiver.next().await {
+            if ws.ready_state() == WebSocket::OPEN {
+                ws.send_with_str(serde_json::to_string(&err).unwrap().as_str())
+                    .unwrap();
+            } else {
+                console::warn_1(&"WebSocket is not open, cannot send error. Run with dioxus serve --hot-reload to enable hot reloading.".into());
+                panic!("{}", err);
+            }
+        }
+    });
+}

+ 3 - 68
packages/web/src/lib.rs

@@ -62,11 +62,12 @@ use dioxus_core::prelude::Component;
 use dioxus_core::SchedulerMsg;
 use dioxus_core::VirtualDom;
 use futures_util::FutureExt;
-use web_sys::console;
 
 mod cache;
 mod cfg;
 mod dom;
+#[cfg(feature = "hot-reload")]
+mod hot_reload;
 mod rehydrate;
 mod ric_raf;
 mod util;
@@ -174,73 +175,7 @@ pub async fn run_with_props<T: 'static + Send>(root: Component<T>, root_props: T
     let mut dom = VirtualDom::new_with_props(root, root_props);
 
     #[cfg(feature = "hot-reload")]
-    {
-        use dioxus_rsx_interpreter::error::Error;
-        use dioxus_rsx_interpreter::{ErrorHandler, SetManyRsxMessage, RSX_CONTEXT};
-        use futures_channel::mpsc::unbounded;
-        use futures_channel::mpsc::UnboundedSender;
-        use futures_util::StreamExt;
-        use wasm_bindgen::closure::Closure;
-        use wasm_bindgen::JsCast;
-        use web_sys::{MessageEvent, WebSocket};
-
-        let window = web_sys::window().unwrap();
-
-        let protocol = if window.location().protocol().unwrap() == "https:" {
-            "wss:"
-        } else {
-            "ws:"
-        };
-
-        let url = format!(
-            "{protocol}//{}/_dioxus/hot_reload",
-            window.location().host().unwrap()
-        );
-
-        let ws = WebSocket::new(&url).unwrap();
-
-        // change the rsx when new data is received
-        let cl = Closure::wrap(Box::new(|e: MessageEvent| {
-            if let Ok(text) = e.data().dyn_into::<js_sys::JsString>() {
-                let msgs: SetManyRsxMessage = serde_json::from_str(&format!("{text}")).unwrap();
-                RSX_CONTEXT.extend(msgs);
-            }
-        }) as Box<dyn FnMut(MessageEvent)>);
-
-        ws.set_onmessage(Some(cl.as_ref().unchecked_ref()));
-        cl.forget();
-
-        let (error_channel_sender, mut error_channel_receiver) = unbounded();
-
-        struct WebErrorHandler {
-            sender: UnboundedSender<Error>,
-        }
-
-        impl ErrorHandler for WebErrorHandler {
-            fn handle_error(&self, err: dioxus_rsx_interpreter::error::Error) {
-                self.sender.unbounded_send(err).unwrap();
-            }
-        }
-
-        RSX_CONTEXT.set_error_handler(WebErrorHandler {
-            sender: error_channel_sender,
-        });
-
-        RSX_CONTEXT.provide_scheduler_channel(dom.get_scheduler_channel());
-
-        // forward stream to the websocket
-        dom.base_scope().spawn_forever(async move {
-            while let Some(err) = error_channel_receiver.next().await {
-                if ws.ready_state() == WebSocket::OPEN {
-                    ws.send_with_str(serde_json::to_string(&err).unwrap().as_str())
-                        .unwrap();
-                } else {
-                    console::warn_1(&"WebSocket is not open, cannot send error. Run with dioxus serve --hot-reload to enable hot reloading.".into());
-                    panic!("{}", err);
-                }
-            }
-        });
-    }
+    hot_reload::init(&dom);
 
     for s in crate::cache::BUILTIN_INTERNED_STRINGS {
         wasm_bindgen::intern(s);