Merge branch 'desktop-hot-reload' of https://github.com/demonthos/dioxus into desktop-hot-reload
This commit is contained in:
commit
ee57046b58
15 files changed
+58
-138
No files matched your search
@@ -21,7 +21,6 @@ members = [
|
|||||||
"packages/rsx-rosetta",
|
"packages/rsx-rosetta",
|
||||||
"packages/signals",
|
"packages/signals",
|
||||||
"packages/hot-reload",
|
"packages/hot-reload",
|
||||||
"packages/hot-reload-macro",
|
|
||||||
"docs/guide",
|
"docs/guide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ keywords = ["dom", "ui", "gui", "react", "wasm"]
|
|||||||
dioxus-core = { path = "../core", version = "^0.3.0", features = ["serialize"] }
|
dioxus-core = { path = "../core", version = "^0.3.0", features = ["serialize"] }
|
||||||
dioxus-html = { path = "../html", features = ["serialize"], version = "^0.3.0" }
|
dioxus-html = { path = "../html", features = ["serialize"], version = "^0.3.0" }
|
||||||
dioxus-interpreter-js = { path = "../interpreter", version = "^0.3.0" }
|
dioxus-interpreter-js = { path = "../interpreter", version = "^0.3.0" }
|
||||||
|
dioxus-hot-reload = { path = "../hot-reload" }
|
||||||
|
|
||||||
serde = "1.0.136"
|
serde = "1.0.136"
|
||||||
serde_json = "1.0.79"
|
serde_json = "1.0.79"
|
||||||
|
|||||||
@@ -1,38 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use dioxus_core::Template;
|
|
||||||
|
|
||||||
use interprocess::local_socket::LocalSocketStream;
|
|
||||||
use std::io::{BufRead, BufReader};
|
|
||||||
use wry::application::{event_loop::EventLoopProxy, window::WindowId};
|
|
||||||
|
|
||||||
use crate::desktop_context::{EventData, UserWindowEvent};
|
|
||||||
|
|
||||||
pub(crate) fn init(proxy: EventLoopProxy<UserWindowEvent>) {
|
|
||||||
std::thread::spawn(move || {
|
|
||||||
let temp_file = std::env::temp_dir().join("@dioxusin");
|
|
||||||
if let Ok(socket) = LocalSocketStream::connect(temp_file.as_path()) {
|
|
||||||
let mut buf_reader = BufReader::new(socket);
|
|
||||||
loop {
|
|
||||||
let mut buf = String::new();
|
|
||||||
match buf_reader.read_line(&mut buf) {
|
|
||||||
Ok(_) => {
|
|
||||||
let template: Template<'static> =
|
|
||||||
serde_json::from_str(Box::leak(buf.into_boxed_str())).unwrap();
|
|
||||||
proxy
|
|
||||||
.send_event(UserWindowEvent(
|
|
||||||
EventData::TemplateUpdated(template),
|
|
||||||
unsafe { WindowId::dummy() },
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
if err.kind() != std::io::ErrorKind::WouldBlock {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -12,9 +12,6 @@ mod protocol;
|
|||||||
mod waker;
|
mod waker;
|
||||||
mod webview;
|
mod webview;
|
||||||
|
|
||||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
|
||||||
mod hot_reload;
|
|
||||||
|
|
||||||
pub use cfg::Config;
|
pub use cfg::Config;
|
||||||
pub use desktop_context::{use_window, DesktopContext};
|
pub use desktop_context::{use_window, DesktopContext};
|
||||||
use desktop_context::{EventData, UserWindowEvent, WebviewQueue};
|
use desktop_context::{EventData, UserWindowEvent, WebviewQueue};
|
||||||
@@ -111,7 +108,15 @@ pub fn launch_with_props<P: 'static>(root: Component<P>, props: P, cfg: Config)
|
|||||||
|
|
||||||
// Intialize hot reloading if it is enabled
|
// Intialize hot reloading if it is enabled
|
||||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
hot_reload::init(proxy.clone());
|
{
|
||||||
|
let proxy = proxy.clone();
|
||||||
|
dioxus_hot_reload::connect(move |template| {
|
||||||
|
let _ = proxy.send_event(UserWindowEvent(
|
||||||
|
EventData::TemplateUpdated(template),
|
||||||
|
unsafe { WindowId::dummy() },
|
||||||
|
));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// We start the tokio runtime *on this thread*
|
// We start the tokio runtime *on this thread*
|
||||||
// Any future we poll later will use this runtime to spawn tasks and for IO
|
// Any future we poll later will use this runtime to spawn tasks and for IO
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "dioxus-hot-reload-macro"
|
|
||||||
version = "0.1.0"
|
|
||||||
edition = "2021"
|
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
syn = { version = "1.0.107", features = ["full"] }
|
|
||||||
proc-macro2 = { version = "1.0" }
|
|
||||||
|
|
||||||
[lib]
|
|
||||||
proc-macro = true
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
use proc_macro::TokenStream;
|
|
||||||
use syn::__private::quote::quote;
|
|
||||||
|
|
||||||
#[proc_macro]
|
|
||||||
pub fn hot_reload(_: TokenStream) -> TokenStream {
|
|
||||||
quote!(dioxus_hot_reload::init(core::env!("CARGO_MANIFEST_DIR"))).into()
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,6 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dioxus-hot-reload-macro = { path = "../hot-reload-macro" }
|
|
||||||
dioxus-rsx = { path = "../rsx" }
|
dioxus-rsx = { path = "../rsx" }
|
||||||
dioxus-core = { path = "../core", features = ["serialize"] }
|
dioxus-core = { path = "../core", features = ["serialize"] }
|
||||||
dioxus-html = { path = "../html", features = ["hot-reload-context"] }
|
dioxus-html = { path = "../html", features = ["hot-reload-context"] }
|
||||||
|
|||||||
@@ -1,18 +1,18 @@
|
|||||||
use std::{
|
use std::{
|
||||||
io::Write,
|
io::{BufRead, BufReader, Write},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
|
|
||||||
use dioxus_core::Template;
|
use dioxus_core::Template;
|
||||||
pub use dioxus_hot_reload_macro::hot_reload;
|
|
||||||
use dioxus_html::HtmlCtx;
|
use dioxus_html::HtmlCtx;
|
||||||
use dioxus_rsx::hot_reload::{FileMap, UpdateResult};
|
use dioxus_rsx::hot_reload::{FileMap, UpdateResult};
|
||||||
use interprocess::local_socket::LocalSocketListener;
|
use interprocess::local_socket::{LocalSocketListener, LocalSocketStream};
|
||||||
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
|
use notify::{RecommendedWatcher, RecursiveMode, Watcher};
|
||||||
|
|
||||||
pub fn init(path: &'static str) {
|
/// Initialize the hot reloading listener on the given path
|
||||||
|
pub fn init(path: &'static str, listening_paths: &'static [&'static str]) {
|
||||||
if let Ok(crate_dir) = PathBuf::from_str(path) {
|
if let Ok(crate_dir) = PathBuf::from_str(path) {
|
||||||
let temp_file = std::env::temp_dir().join("@dioxusin");
|
let temp_file = std::env::temp_dir().join("@dioxusin");
|
||||||
let channels = Arc::new(Mutex::new(Vec::new()));
|
let channels = Arc::new(Mutex::new(Vec::new()));
|
||||||
@@ -121,3 +121,39 @@ fn send_template(template: Template<'static>, channel: &mut impl Write) -> bool
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Connect to the hot reloading listener. The callback provided will be called every time a template change is detected
|
||||||
|
pub fn connect(mut f: impl FnMut(Template<'static>) + Send + 'static) {
|
||||||
|
std::thread::spawn(move || {
|
||||||
|
let temp_file = std::env::temp_dir().join("@dioxusin");
|
||||||
|
if let Ok(socket) = LocalSocketStream::connect(temp_file.as_path()) {
|
||||||
|
let mut buf_reader = BufReader::new(socket);
|
||||||
|
loop {
|
||||||
|
let mut buf = String::new();
|
||||||
|
match buf_reader.read_line(&mut buf) {
|
||||||
|
Ok(_) => {
|
||||||
|
let template: Template<'static> =
|
||||||
|
serde_json::from_str(Box::leak(buf.into_boxed_str())).unwrap();
|
||||||
|
f(template);
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
if err.kind() != std::io::ErrorKind::WouldBlock {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! hot_reload {
|
||||||
|
() => {
|
||||||
|
dioxus_hot_reload::init(core::env!("CARGO_MANIFEST_DIR"), &[])
|
||||||
|
};
|
||||||
|
|
||||||
|
($($paths: literal,)*,?) => {
|
||||||
|
dioxus_hot_reload::init(core::env!("CARGO_MANIFEST_DIR"), &[$($path,)*])
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ license = "MIT/Apache-2.0"
|
|||||||
dioxus-html = { path = "../html", features = ["serialize"], version = "^0.3.0" }
|
dioxus-html = { path = "../html", features = ["serialize"], version = "^0.3.0" }
|
||||||
dioxus-core = { path = "../core", features = ["serialize"], version = "^0.3.0" }
|
dioxus-core = { path = "../core", features = ["serialize"], version = "^0.3.0" }
|
||||||
dioxus-interpreter-js = { path = "../interpreter", version = "0.3.0" }
|
dioxus-interpreter-js = { path = "../interpreter", version = "0.3.0" }
|
||||||
|
dioxus-hot-reload = { path = "../hot-reload" }
|
||||||
|
|
||||||
tokio = { version = "1.23.0", features = ["full"] }
|
tokio = { version = "1.23.0", features = ["full"] }
|
||||||
futures-util = { version = "0.3.25", default-features = false, features = [
|
futures-util = { version = "0.3.25", default-features = false, features = [
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use dioxus_core::Template;
|
|
||||||
|
|
||||||
use interprocess::local_socket::LocalSocketStream;
|
|
||||||
use std::io::{BufRead, BufReader};
|
|
||||||
use tokio::sync::mpsc::UnboundedSender;
|
|
||||||
|
|
||||||
pub(crate) fn init(proxy: UnboundedSender<Template<'static>>) {
|
|
||||||
std::thread::spawn(move || {
|
|
||||||
let temp_file = std::env::temp_dir().join("@dioxusin");
|
|
||||||
if let Ok(socket) = LocalSocketStream::connect(temp_file.as_path()) {
|
|
||||||
let mut buf_reader = BufReader::new(socket);
|
|
||||||
loop {
|
|
||||||
let mut buf = String::new();
|
|
||||||
match buf_reader.read_line(&mut buf) {
|
|
||||||
Ok(_) => {
|
|
||||||
let template: Template<'static> =
|
|
||||||
serde_json::from_str(Box::leak(buf.into_boxed_str())).unwrap();
|
|
||||||
if proxy.send(template).is_err() {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
if err.kind() != std::io::ErrorKind::WouldBlock {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -18,8 +18,6 @@ pub mod adapters {
|
|||||||
|
|
||||||
pub use adapters::*;
|
pub use adapters::*;
|
||||||
|
|
||||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
|
||||||
mod hot_reload;
|
|
||||||
pub mod pool;
|
pub mod pool;
|
||||||
use futures_util::{SinkExt, StreamExt};
|
use futures_util::{SinkExt, StreamExt};
|
||||||
pub use pool::*;
|
pub use pool::*;
|
||||||
|
|||||||
@@ -106,7 +106,9 @@ where
|
|||||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
let mut hot_reload_rx = {
|
let mut hot_reload_rx = {
|
||||||
let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
|
let (tx, rx) = tokio::sync::mpsc::unbounded_channel();
|
||||||
crate::hot_reload::init(tx);
|
dioxus_hot_reload::connect(move |template| {
|
||||||
|
let _ = tx.send(template);
|
||||||
|
});
|
||||||
rx
|
rx
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ dioxus-core = { path = "../core", version = "^0.3.0", features = ["serialize"] }
|
|||||||
dioxus-html = { path = "../html", version = "^0.3.0" }
|
dioxus-html = { path = "../html", version = "^0.3.0" }
|
||||||
dioxus-native-core = { path = "../native-core", version = "^0.2.0" }
|
dioxus-native-core = { path = "../native-core", version = "^0.2.0" }
|
||||||
dioxus-native-core-macro = { path = "../native-core-macro", version = "^0.2.0" }
|
dioxus-native-core-macro = { path = "../native-core-macro", version = "^0.2.0" }
|
||||||
|
dioxus-hot-reload = { path = "../hot-reload" }
|
||||||
|
|
||||||
tui = "0.17.0"
|
tui = "0.17.0"
|
||||||
crossterm = "0.23.0"
|
crossterm = "0.23.0"
|
||||||
|
|||||||
@@ -1,31 +0,0 @@
|
|||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use dioxus_core::Template;
|
|
||||||
|
|
||||||
use interprocess::local_socket::LocalSocketStream;
|
|
||||||
use std::io::{BufRead, BufReader};
|
|
||||||
use tokio::sync::mpsc::UnboundedSender;
|
|
||||||
|
|
||||||
pub(crate) fn init(proxy: UnboundedSender<Template<'static>>) {
|
|
||||||
std::thread::spawn(move || {
|
|
||||||
let temp_file = std::env::temp_dir().join("@dioxusin");
|
|
||||||
if let Ok(socket) = LocalSocketStream::connect(temp_file.as_path()) {
|
|
||||||
let mut buf_reader = BufReader::new(socket);
|
|
||||||
loop {
|
|
||||||
let mut buf = String::new();
|
|
||||||
match buf_reader.read_line(&mut buf) {
|
|
||||||
Ok(_) => {
|
|
||||||
let template: Template<'static> =
|
|
||||||
serde_json::from_str(Box::leak(buf.into_boxed_str())).unwrap();
|
|
||||||
proxy.send(template).unwrap();
|
|
||||||
}
|
|
||||||
Err(err) => {
|
|
||||||
if err.kind() != std::io::ErrorKind::WouldBlock {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -28,8 +28,6 @@ use tui::{backend::CrosstermBackend, layout::Rect, Terminal};
|
|||||||
mod config;
|
mod config;
|
||||||
mod focus;
|
mod focus;
|
||||||
mod hooks;
|
mod hooks;
|
||||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
|
||||||
mod hot_reload;
|
|
||||||
mod layout;
|
mod layout;
|
||||||
mod node;
|
mod node;
|
||||||
pub mod prelude;
|
pub mod prelude;
|
||||||
@@ -150,7 +148,9 @@ fn render_vdom(
|
|||||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||||
let mut hot_reload_rx = {
|
let mut hot_reload_rx = {
|
||||||
let (hot_reload_tx, hot_reload_rx) = unbounded_channel::<Template<'static>>();
|
let (hot_reload_tx, hot_reload_rx) = unbounded_channel::<Template<'static>>();
|
||||||
hot_reload::init(hot_reload_tx);
|
dioxus_hot_reload::connect(move |template| {
|
||||||
|
let _ = hot_reload_tx.send(template);
|
||||||
|
});
|
||||||
hot_reload_rx
|
hot_reload_rx
|
||||||
};
|
};
|
||||||
let mut terminal = (!cfg.headless).then(|| {
|
let mut terminal = (!cfg.headless).then(|| {
|
||||||
|
|||||||
Reference in new issue
Block a user