63 lines
2.0 KiB
Rust
63 lines
2.0 KiB
Rust
use std::sync::Arc;
|
|
|
|
use dioxus::prelude::Template;
|
|
use tokio::sync::{
|
|
watch::{channel, Receiver},
|
|
RwLock,
|
|
};
|
|
|
|
#[derive(Clone)]
|
|
pub struct HotReloadState {
|
|
// The cache of all templates that have been modified since the last time we checked
|
|
pub(crate) templates:
|
|
Arc<RwLock<std::collections::HashSet<dioxus::prelude::Template<'static>>>>,
|
|
// The channel to send messages to the hot reload thread
|
|
pub(crate) message_receiver: Receiver<Option<Template<'static>>>,
|
|
}
|
|
|
|
impl Default for HotReloadState {
|
|
fn default() -> Self {
|
|
let templates = Arc::new(RwLock::new(std::collections::HashSet::new()));
|
|
let (tx, rx) = channel(None);
|
|
|
|
dioxus_hot_reload::connect({
|
|
let templates = templates.clone();
|
|
move |msg| match msg {
|
|
dioxus_hot_reload::HotReloadMsg::UpdateTemplate(template) => {
|
|
{
|
|
let mut templates = templates.blocking_write();
|
|
templates.insert(template);
|
|
}
|
|
|
|
if let Err(err) = tx.send(Some(template)) {
|
|
log::error!("Failed to send hot reload message: {}", err);
|
|
}
|
|
}
|
|
dioxus_hot_reload::HotReloadMsg::Shutdown => {
|
|
std::process::exit(0);
|
|
}
|
|
}
|
|
});
|
|
|
|
Self {
|
|
templates,
|
|
message_receiver: rx,
|
|
}
|
|
}
|
|
}
|
|
|
|
// Hot reloading can be expensive to start so we spawn a new thread
|
|
static HOT_RELOAD_STATE: tokio::sync::OnceCell<HotReloadState> = tokio::sync::OnceCell::const_new();
|
|
pub(crate) async fn spawn_hot_reload() -> &'static HotReloadState {
|
|
HOT_RELOAD_STATE
|
|
.get_or_init(|| async {
|
|
println!("spinning up hot reloading");
|
|
let r = tokio::task::spawn_blocking(HotReloadState::default)
|
|
.await
|
|
.unwrap();
|
|
println!("hot reloading ready");
|
|
r
|
|
})
|
|
.await
|
|
}
|