mirror of
https://github.com/DioxusLabs/dioxus
synced 2024-11-23 12:43:08 +00:00
implement hot reloading for TUI
This commit is contained in:
parent
1073574896
commit
6eff4438cf
3 changed files with 68 additions and 7 deletions
|
@ -14,7 +14,7 @@ license = "MIT/Apache-2.0"
|
|||
|
||||
[dependencies]
|
||||
dioxus = { path = "../dioxus", version = "^0.3.0" }
|
||||
dioxus-core = { path = "../core", version = "^0.3.0" }
|
||||
dioxus-core = { path = "../core", version = "^0.3.0", features = ["serialize"] }
|
||||
dioxus-html = { path = "../html", version = "^0.3.0" }
|
||||
dioxus-native-core = { path = "../native-core", version = "^0.2.0" }
|
||||
dioxus-native-core-macro = { path = "../native-core-macro", version = "^0.2.0" }
|
||||
|
@ -29,6 +29,9 @@ smallvec = "1.6"
|
|||
rustc-hash = "1.1.0"
|
||||
anymap = "1.0.0-beta.2"
|
||||
futures-channel = "0.3.25"
|
||||
interprocess = { version = "1.2.1", optional = true }
|
||||
serde = { version = "1.0.136", optional = true }
|
||||
serde_json = { version = "1.0.79", optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
dioxus = { path = "../dioxus" }
|
||||
|
@ -38,3 +41,7 @@ criterion = "0.3.5"
|
|||
[[bench]]
|
||||
name = "update"
|
||||
harness = false
|
||||
|
||||
[features]
|
||||
default = ["hot-reload"]
|
||||
hot-reload = ["interprocess", "serde", "serde_json"]
|
||||
|
|
31
packages/tui/src/hot_reload.rs
Normal file
31
packages/tui/src/hot_reload.rs
Normal file
|
@ -0,0 +1,31 @@
|
|||
#![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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
|
@ -22,11 +22,14 @@ use std::{
|
|||
use std::{io, time::Duration};
|
||||
use taffy::Taffy;
|
||||
pub use taffy::{geometry::Point, prelude::*};
|
||||
use tokio::{select, sync::mpsc::unbounded_channel};
|
||||
use tui::{backend::CrosstermBackend, layout::Rect, Terminal};
|
||||
|
||||
mod config;
|
||||
mod focus;
|
||||
mod hooks;
|
||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||
mod hot_reload;
|
||||
mod layout;
|
||||
mod node;
|
||||
pub mod prelude;
|
||||
|
@ -144,6 +147,12 @@ fn render_vdom(
|
|||
.enable_all()
|
||||
.build()?
|
||||
.block_on(async {
|
||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||
let mut hot_reload_rx = {
|
||||
let (hot_reload_tx, hot_reload_rx) = unbounded_channel::<Template<'static>>();
|
||||
hot_reload::init(hot_reload_tx);
|
||||
hot_reload_rx
|
||||
};
|
||||
let mut terminal = (!cfg.headless).then(|| {
|
||||
enable_raw_mode().unwrap();
|
||||
let mut stdout = std::io::stdout();
|
||||
|
@ -223,16 +232,21 @@ fn render_vdom(
|
|||
}
|
||||
}
|
||||
|
||||
use futures::future::{select, Either};
|
||||
let mut new_templete = None;
|
||||
{
|
||||
let wait = vdom.wait_for_work();
|
||||
#[cfg(all(feature = "hot-reload", debug_assertions))]
|
||||
let hot_reload_wait = hot_reload_rx.recv();
|
||||
#[cfg(not(all(feature = "hot-reload", debug_assertions)))]
|
||||
let hot_reload_wait = std::future::pending();
|
||||
|
||||
pin_mut!(wait);
|
||||
|
||||
match select(wait, event_reciever.next()).await {
|
||||
Either::Left((_a, _b)) => {
|
||||
//
|
||||
}
|
||||
Either::Right((evt, _o)) => {
|
||||
select! {
|
||||
_ = wait => {
|
||||
|
||||
},
|
||||
evt = event_reciever.next() => {
|
||||
match evt.as_ref().unwrap() {
|
||||
InputEvent::UserInput(event) => match event {
|
||||
TermEvent::Key(key) => {
|
||||
|
@ -252,10 +266,19 @@ fn render_vdom(
|
|||
if let InputEvent::UserInput(evt) = evt.unwrap() {
|
||||
register_event(evt);
|
||||
}
|
||||
},
|
||||
Some(template) = hot_reload_wait => {
|
||||
new_templete = Some(template);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// if we have a new template, replace the old one
|
||||
if let Some(template) = new_templete {
|
||||
// println!("reloading template");
|
||||
vdom.replace_template(template);
|
||||
}
|
||||
|
||||
{
|
||||
let evts = {
|
||||
let mut rdom = rdom.borrow_mut();
|
||||
|
|
Loading…
Reference in a new issue