Merge pull request #754 from Demonthos/desktop-hot-reload
Implement hot reloading for Desktop, TUI, and Liveview
This commit is contained in:
16 files changed
+705
-79
No files matched your search
@@ -9,6 +9,7 @@ use crate::Config;
|
||||
use crate::WebviewHandler;
|
||||
use dioxus_core::ScopeState;
|
||||
use dioxus_core::VirtualDom;
|
||||
use dioxus_hot_reload::HotReloadMsg;
|
||||
use serde_json::Value;
|
||||
use slab::Slab;
|
||||
use wry::application::event::Event;
|
||||
@@ -285,6 +286,8 @@ pub enum EventData {
|
||||
|
||||
Ipc(IpcMessage),
|
||||
|
||||
HotReloadEvent(HotReloadMsg),
|
||||
|
||||
NewWindow,
|
||||
|
||||
CloseWindow,
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
#![allow(dead_code)]
|
||||
|
||||
use dioxus_core::Template;
|
||||
|
||||
use interprocess::local_socket::{LocalSocketListener, LocalSocketStream};
|
||||
use std::io::{BufRead, BufReader};
|
||||
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(proxy: futures_channel::mpsc::UnboundedSender<Template<'static>>) {
|
||||
let latest_in_connection: Arc<Mutex<Option<BufReader<LocalSocketStream>>>> =
|
||||
Arc::new(Mutex::new(None));
|
||||
|
||||
let latest_in_connection_handle = latest_in_connection.clone();
|
||||
|
||||
// connect to processes for incoming data
|
||||
std::thread::spawn(move || {
|
||||
let temp_file = std::env::temp_dir().join("@dioxusin");
|
||||
|
||||
if let Ok(listener) = LocalSocketListener::bind(temp_file) {
|
||||
for conn in listener.incoming().filter_map(handle_error) {
|
||||
*latest_in_connection_handle.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 msg: Template<'static> =
|
||||
serde_json::from_str(Box::leak(buf.into_boxed_str())).unwrap();
|
||||
proxy.unbounded_send(msg).unwrap();
|
||||
}
|
||||
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));
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -12,9 +12,6 @@ mod protocol;
|
||||
mod waker;
|
||||
mod webview;
|
||||
|
||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||
mod hot_reload;
|
||||
|
||||
pub use cfg::Config;
|
||||
pub use desktop_context::{
|
||||
use_window, use_wry_event_handler, DesktopContext, WryEventHandler, WryEventHandlerId,
|
||||
@@ -111,6 +108,18 @@ pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config)
|
||||
|
||||
let proxy = event_loop.create_proxy();
|
||||
|
||||
// Intialize hot reloading if it is enabled
|
||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||
{
|
||||
let proxy = proxy.clone();
|
||||
dioxus_hot_reload::connect(move |template| {
|
||||
let _ = proxy.send_event(UserWindowEvent(
|
||||
EventData::HotReloadEvent(template),
|
||||
unsafe { WindowId::dummy() },
|
||||
));
|
||||
});
|
||||
}
|
||||
|
||||
// We start the tokio runtime *on this thread*
|
||||
// Any future we poll later will use this runtime to spawn tasks and for IO
|
||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||
@@ -176,6 +185,19 @@ pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config)
|
||||
}
|
||||
|
||||
Event::UserEvent(event) => match event.0 {
|
||||
EventData::HotReloadEvent(msg) => match msg {
|
||||
dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => {
|
||||
for webview in webviews.values_mut() {
|
||||
webview.dom.replace_template(template);
|
||||
|
||||
poll_vdom(webview);
|
||||
}
|
||||
}
|
||||
dioxus_hot_reload::HotReloadMsg::Shutdown => {
|
||||
*control_flow = ControlFlow::Exit;
|
||||
}
|
||||
},
|
||||
|
||||
EventData::CloseWindow => {
|
||||
webviews.remove(&event.1);
|
||||
|
||||
|
||||
Reference in new issue
Block a user