fix desktop hot reloading

This commit is contained in:
Evan Almloff committed 2023-07-18 11:55:56 -07:00
1 parent 0c5025ffa0
commit 2c1c147828
15 files changed
+130 -115

No files matched your search

+1
View File
@@ -364,6 +364,7 @@ pub fn build_desktop(config: &CrateConfig, _is_serve: bool) -> Result<BuildResul
.display()
);
}
println!("build desktop done");
Ok(BuildResult {
warnings: vec![],
+1 -15
View File
@@ -57,21 +57,7 @@ impl Serve {
.await?;
}
cfg::Platform::Desktop => {
crate::builder::build_desktop(&crate_config, true)?;
match &crate_config.executable {
crate::ExecutableType::Binary(name)
| crate::ExecutableType::Lib(name)
| crate::ExecutableType::Example(name) => {
let mut file = crate_config.out_dir.join(name);
if cfg!(windows) {
file.set_extension("exe");
}
Command::new(file.to_str().unwrap())
.stdout(Stdio::inherit())
.output()?;
}
}
server::desktop::startup(crate_config.clone()).await?;
}
}
Ok(())
+24 -14
View File
@@ -3,7 +3,7 @@ use crate::{
serve::Serve,
server::{
output::{print_console_info, PrettierOptions, WebServerInfo},
setup_file_watcher, setup_file_watcher_hot_reload, BuildManager,
setup_file_watcher, setup_file_watcher_hot_reload,
},
BuildResult, CrateConfig, Result,
};
@@ -72,7 +72,15 @@ pub async fn serve_default(config: CrateConfig) -> Result<()> {
// We got to own watcher so that it exists for the duration of serve
// Otherwise full reload won't work.
let _watcher = setup_file_watcher(crate::cfg::Platform::Desktop, &config, None, None).await?;
let _watcher = setup_file_watcher(
{
let config = config.clone();
move || start_desktop(&config)
},
&config,
None,
)
.await?;
// Print serve info
print_console_info(
@@ -107,15 +115,13 @@ pub async fn serve_hot_reload(config: CrateConfig) -> Result<()> {
}
let file_map = Arc::new(Mutex::new(map));
let build_manager = Arc::new(BuildManager {
platform: crate::cfg::Platform::Web,
config: config.clone(),
reload_tx: None,
});
let (hot_reload_tx, mut hot_reload_rx) = broadcast::channel(100);
// States
// The open interprocess sockets
let channels = Arc::new(Mutex::new(Vec::new()));
// Setup file watcher
// We got to own watcher so that it exists for the duration of serve
// Otherwise hot reload won't work.
@@ -123,7 +129,17 @@ pub async fn serve_hot_reload(config: CrateConfig) -> Result<()> {
&config,
hot_reload_tx,
file_map.clone(),
build_manager,
{
let config = config.clone();
let channels = channels.clone();
move || {
for channel in &mut *channels.lock().unwrap() {
send_msg(HotReloadMsg::Shutdown, channel);
}
start_desktop(&config)
}
},
None,
)
.await?;
@@ -153,8 +169,6 @@ pub async fn serve_hot_reload(config: CrateConfig) -> Result<()> {
}
}
let channels = Arc::new(Mutex::new(Vec::new()));
match LocalSocketListener::bind("@dioxusin") {
Ok(local_socket_stream) => {
let aborted = Arc::new(Mutex::new(false));
@@ -196,10 +210,6 @@ pub async fn serve_hot_reload(config: CrateConfig) -> Result<()> {
}
});
// for channel in &mut *channels.lock().unwrap() {
// send_msg(HotReloadMsg::Shutdown, channel);
// }
while let Ok(template) = hot_reload_rx.recv().await {
let channels = &mut *channels.lock().unwrap();
let mut i = 0;
+7 -46
View File
@@ -39,18 +39,11 @@ pub mod desktop;
pub mod web;
/// Sets up a file watcher
async fn setup_file_watcher(
platform: Platform,
async fn setup_file_watcher<F: Fn() -> Result<BuildResult> + Send + 'static>(
build_with: F,
config: &CrateConfig,
reload_tx: Option<Sender<()>>,
web_info: Option<WebServerInfo>,
) -> Result<RecommendedWatcher> {
let build_manager = BuildManager {
platform,
config: config.clone(),
reload_tx,
};
let mut last_update_time = chrono::Local::now().timestamp();
// file watcher: check file change
@@ -67,7 +60,7 @@ async fn setup_file_watcher(
let config = watcher_config.clone();
if let Ok(e) = info {
if chrono::Local::now().timestamp() > last_update_time {
match build_manager.rebuild() {
match build_with() {
Ok(res) => {
last_update_time = chrono::Local::now().timestamp();
@@ -108,11 +101,11 @@ async fn setup_file_watcher(
// Todo: reduce duplication and merge with setup_file_watcher()
/// Sets up a file watcher with hot reload
async fn setup_file_watcher_hot_reload(
async fn setup_file_watcher_hot_reload<F: Fn() -> Result<BuildResult> + Send + 'static>(
config: &CrateConfig,
hot_reload_tx: Sender<Template<'static>>,
file_map: Arc<Mutex<FileMap<HtmlCtx>>>,
build_manager: Arc<BuildManager>,
build_with: F,
web_info: Option<WebServerInfo>,
) -> Result<RecommendedWatcher> {
// file watcher: check file change
@@ -138,7 +131,7 @@ async fn setup_file_watcher_hot_reload(
for path in evt.paths.clone() {
// if this is not a rust file, rebuild the whole project
if path.extension().and_then(|p| p.to_str()) != Some("rs") {
match build_manager.rebuild() {
match build_with() {
Ok(res) => {
print_console_info(
&config,
@@ -164,7 +157,7 @@ async fn setup_file_watcher_hot_reload(
messages.extend(msgs);
}
Ok(UpdateResult::NeedsRebuild) => {
match build_manager.rebuild() {
match build_with() {
Ok(res) => {
print_console_info(
&config,
@@ -209,35 +202,3 @@ async fn setup_file_watcher_hot_reload(
Ok(watcher)
}
pub struct BuildManager {
platform: Platform,
config: CrateConfig,
reload_tx: Option<broadcast::Sender<()>>,
}
impl BuildManager {
fn rebuild(&self) -> Result<BuildResult> {
log::info!("🪁 Rebuild project");
match self.platform {
Platform::Web => {
let result = builder::build(&self.config, true)?;
// change the websocket reload state to true;
// the page will auto-reload.
if self
.config
.dioxus_config
.web
.watcher
.reload_html
.unwrap_or(false)
{
let _ = Serve::regen_dev_page(&self.config);
}
let _ = self.reload_tx.as_ref().map(|tx| tx.send(()));
Ok(result)
}
Platform::Desktop => start_desktop(&self.config),
}
}
}
@@ -10,12 +10,10 @@ use dioxus_html::HtmlCtx;
use dioxus_rsx::hot_reload::FileMap;
use tokio::sync::broadcast;
use super::BuildManager;
use crate::CrateConfig;
pub struct HotReloadState {
pub messages: broadcast::Sender<Template<'static>>,
pub build_manager: Arc<BuildManager>,
pub file_map: Arc<Mutex<FileMap<HtmlCtx>>>,
pub watcher_config: CrateConfig,
}
+28 -10
View File
@@ -3,7 +3,7 @@ use crate::{
serve::Serve,
server::{
output::{print_console_info, PrettierOptions, WebServerInfo},
setup_file_watcher, setup_file_watcher_hot_reload, BuildManager,
setup_file_watcher, setup_file_watcher_hot_reload,
},
BuildResult, CrateConfig, Result,
};
@@ -86,9 +86,12 @@ pub async fn serve_default(
// We got to own watcher so that it exists for the duration of serve
// Otherwise full reload won't work.
let _watcher = setup_file_watcher(
crate::cfg::Platform::Web,
{
let config = config.clone();
let reload_tx = reload_tx.clone();
move || build(&config, &reload_tx)
},
&config,
Some(reload_tx.clone()),
Some(WebServerInfo {
ip: ip.clone(),
port,
@@ -148,18 +151,12 @@ pub async fn serve_hot_reload(
}
let file_map = Arc::new(Mutex::new(map));
let build_manager = Arc::new(BuildManager {
platform: crate::cfg::Platform::Web,
config: config.clone(),
reload_tx: Some(reload_tx.clone()),
});
let hot_reload_tx = broadcast::channel(100).0;
// States
let hot_reload_state = Arc::new(HotReloadState {
messages: hot_reload_tx.clone(),
build_manager: build_manager.clone(),
file_map: file_map.clone(),
watcher_config: config.clone(),
});
@@ -175,7 +172,11 @@ pub async fn serve_hot_reload(
&config,
hot_reload_tx,
file_map,
build_manager,
{
let config = config.clone();
let reload_tx = reload_tx.clone();
move || build(&config, &reload_tx)
},
Some(WebServerInfo {
ip: ip.clone(),
port,
@@ -473,3 +474,20 @@ async fn ws_handler(
reload_watcher.await.unwrap();
})
}
fn build(config: &CrateConfig, reload_tx: &Sender<()>) -> Result<BuildResult> {
let result = builder::build(&config, true)?;
// change the websocket reload state to true;
// the page will auto-reload.
if config
.dioxus_config
.web
.watcher
.reload_html
.unwrap_or(false)
{
let _ = Serve::regen_dev_page(&config);
}
let _ = reload_tx.send(());
Ok(result)
}