fix web imports and extract hot reload handlers into seperate files (#484)
This commit is contained in:
1 parent
7e454e770a
commit
3a5d1a2ff8
5 files changed
+154
-154
No files matched your search
@@ -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
|
// 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")]
|
#[cfg(feature = "hot-reload")]
|
||||||
{
|
crate::hot_reload::init(&dom);
|
||||||
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));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let edits = dom.rebuild();
|
let edits = dom.rebuild();
|
||||||
|
|
||||||
|
|||||||
@@ -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));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -8,6 +8,8 @@ mod controller;
|
|||||||
mod desktop_context;
|
mod desktop_context;
|
||||||
mod escape;
|
mod escape;
|
||||||
mod events;
|
mod events;
|
||||||
|
#[cfg(feature = "hot-reload")]
|
||||||
|
mod hot_reload;
|
||||||
mod protocol;
|
mod protocol;
|
||||||
|
|
||||||
use desktop_context::UserWindowEvent;
|
use desktop_context::UserWindowEvent;
|
||||||
|
|||||||
@@ -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
@@ -62,11 +62,12 @@ use dioxus_core::prelude::Component;
|
|||||||
use dioxus_core::SchedulerMsg;
|
use dioxus_core::SchedulerMsg;
|
||||||
use dioxus_core::VirtualDom;
|
use dioxus_core::VirtualDom;
|
||||||
use futures_util::FutureExt;
|
use futures_util::FutureExt;
|
||||||
use web_sys::console;
|
|
||||||
|
|
||||||
mod cache;
|
mod cache;
|
||||||
mod cfg;
|
mod cfg;
|
||||||
mod dom;
|
mod dom;
|
||||||
|
#[cfg(feature = "hot-reload")]
|
||||||
|
mod hot_reload;
|
||||||
mod rehydrate;
|
mod rehydrate;
|
||||||
mod ric_raf;
|
mod ric_raf;
|
||||||
mod util;
|
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);
|
let mut dom = VirtualDom::new_with_props(root, root_props);
|
||||||
|
|
||||||
#[cfg(feature = "hot-reload")]
|
#[cfg(feature = "hot-reload")]
|
||||||
{
|
hot_reload::init(&dom);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
for s in crate::cache::BUILTIN_INTERNED_STRINGS {
|
for s in crate::cache::BUILTIN_INTERNED_STRINGS {
|
||||||
wasm_bindgen::intern(s);
|
wasm_bindgen::intern(s);
|
||||||
|
|||||||
Reference in new issue
Block a user