added headless mode for CI

This commit is contained in:
Evan Almloff committed 2022-04-05 12:08:01 -05:00
1 parent 351722d136
commit 3dd18b21b3
3 files changed
+106 -42

No files matched your search

+45 -11
View File
@@ -1,15 +1,13 @@
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion}; use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use dioxus::prelude::*; use dioxus::prelude::*;
use dioxus_tui::TuiContext; use dioxus_tui::{Config, TuiContext};
criterion_group!(mbenches, update_boxes); criterion_group!(mbenches, tui_update);
criterion_main!(mbenches); criterion_main!(mbenches);
/// This benchmarks the cache performance of the TUI for small edits by changing one box at a time. /// This benchmarks the cache performance of the TUI for small edits by changing one box at a time.
fn update_boxes(c: &mut Criterion) { fn tui_update(c: &mut Criterion) {
let mut group = c.benchmark_group("Update boxes"); let mut group = c.benchmark_group("Update boxes");
// We can override the configuration on a per-group level
group.sample_size(10);
// We can also use loops to define multiple benchmarks, even over multiple dimensions. // We can also use loops to define multiple benchmarks, even over multiple dimensions.
for size in 1..=6 { for size in 1..=6 {
@@ -19,12 +17,48 @@ fn update_boxes(c: &mut Criterion) {
&size, &size,
|b, size| { |b, size| {
b.iter(|| match size { b.iter(|| match size {
1 => dioxus::tui::launch(app5), 1 => dioxus::tui::launch_cfg(
2 => dioxus::tui::launch(app10), app5,
3 => dioxus::tui::launch(app15), Config {
4 => dioxus::tui::launch(app20), headless: true,
5 => dioxus::tui::launch(app25), ..Default::default()
6 => dioxus::tui::launch(app30), },
),
2 => dioxus::tui::launch_cfg(
app10,
Config {
headless: true,
..Default::default()
},
),
3 => dioxus::tui::launch_cfg(
app15,
Config {
headless: true,
..Default::default()
},
),
4 => dioxus::tui::launch_cfg(
app20,
Config {
headless: true,
..Default::default()
},
),
5 => dioxus::tui::launch_cfg(
app25,
Config {
headless: true,
..Default::default()
},
),
6 => dioxus::tui::launch_cfg(
app30,
Config {
headless: true,
..Default::default()
},
),
_ => (), _ => (),
}) })
}, },
+4 -1
View File
@@ -1,9 +1,11 @@
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct Config { pub struct Config {
pub rendering_mode: RenderingMode, pub rendering_mode: RenderingMode,
/// Should the terminal quit when the user presses `ctrl+c`? /// Controls if the terminal quit when the user presses `ctrl+c`?
/// To handle quiting on your own, use the [crate::TuiContext] root context. /// To handle quiting on your own, use the [crate::TuiContext] root context.
pub ctrl_c_quit: bool, pub ctrl_c_quit: bool,
/// Controls if the terminal should dislay anything, usefull for testing.
pub headless: bool,
} }
impl Default for Config { impl Default for Config {
@@ -11,6 +13,7 @@ impl Default for Config {
Self { Self {
rendering_mode: Default::default(), rendering_mode: Default::default(),
ctrl_c_quit: true, ctrl_c_quit: true,
headless: false,
} }
} }
} }
+57 -30
View File
@@ -15,7 +15,7 @@ use layout::StretchLayout;
use std::{io, time::Duration}; use std::{io, time::Duration};
use stretch2::{prelude::Size, Stretch}; use stretch2::{prelude::Size, Stretch};
use style_attributes::StyleModifier; use style_attributes::StyleModifier;
use tui::{backend::CrosstermBackend, Terminal}; use tui::{backend::CrosstermBackend, layout::Rect, Terminal};
mod config; mod config;
mod hooks; mod hooks;
@@ -51,18 +51,20 @@ pub fn launch_cfg(app: Component<()>, cfg: Config) {
// Setup input handling // Setup input handling
let (event_tx, event_rx) = unbounded(); let (event_tx, event_rx) = unbounded();
let event_tx_clone = event_tx.clone(); let event_tx_clone = event_tx.clone();
std::thread::spawn(move || { if !cfg.headless {
let tick_rate = Duration::from_millis(1000); std::thread::spawn(move || {
loop { let tick_rate = Duration::from_millis(1000);
if crossterm::event::poll(tick_rate).unwrap() { loop {
// if crossterm::event::poll(timeout).unwrap() { if crossterm::event::poll(tick_rate).unwrap() {
let evt = crossterm::event::read().unwrap(); // if crossterm::event::poll(timeout).unwrap() {
if event_tx.unbounded_send(InputEvent::UserInput(evt)).is_err() { let evt = crossterm::event::read().unwrap();
break; if event_tx.unbounded_send(InputEvent::UserInput(evt)).is_err() {
break;
}
} }
} }
} });
}); }
let cx = dom.base_scope(); let cx = dom.base_scope();
cx.provide_root_context(state); cx.provide_root_context(state);
@@ -101,13 +103,17 @@ fn render_vdom(
.enable_all() .enable_all()
.build()? .build()?
.block_on(async { .block_on(async {
enable_raw_mode().unwrap(); let mut terminal = (!cfg.headless).then(|| {
let mut stdout = std::io::stdout(); enable_raw_mode().unwrap();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture).unwrap(); let mut stdout = std::io::stdout();
let backend = CrosstermBackend::new(io::stdout()); execute!(stdout, EnterAlternateScreen, EnableMouseCapture).unwrap();
let mut terminal = Terminal::new(backend).unwrap(); let backend = CrosstermBackend::new(io::stdout());
Terminal::new(backend).unwrap()
});
if let Some(terminal) = &mut terminal {
terminal.clear().unwrap();
}
terminal.clear().unwrap();
let mut to_rerender: fxhash::FxHashSet<usize> = vec![0].into_iter().collect(); let mut to_rerender: fxhash::FxHashSet<usize> = vec![0].into_iter().collect();
let mut resized = true; let mut resized = true;
@@ -125,9 +131,11 @@ fn render_vdom(
if !to_rerender.is_empty() || resized { if !to_rerender.is_empty() || resized {
resized = false; resized = false;
terminal.draw(|frame| { fn resize(
// size is guaranteed to not change when rendering dims: Rect,
let dims = frame.size(); stretch: &mut Stretch,
rdom: &RealDom<StretchLayout, StyleModifier>,
) {
let width = dims.width; let width = dims.width;
let height = dims.height; let height = dims.height;
let root_id = rdom.root_id(); let root_id = rdom.root_id();
@@ -142,9 +150,26 @@ fn render_vdom(
}, },
) )
.unwrap(); .unwrap();
let root = &rdom[rdom.root_id()]; }
render::render_vnode(frame, &stretch, &rdom, &root, cfg); if let Some(terminal) = &mut terminal {
})?; terminal.draw(|frame| {
// size is guaranteed to not change when rendering
resize(frame.size(), &mut stretch, &rdom);
let root = &rdom[rdom.root_id()];
render::render_vnode(frame, &stretch, &rdom, &root, cfg);
})?;
} else {
resize(
Rect {
x: 0,
y: 0,
width: 300,
height: 300,
},
&mut stretch,
&rdom,
);
}
} }
use futures::future::{select, Either}; use futures::future::{select, Either};
@@ -198,13 +223,15 @@ fn render_vdom(
} }
} }
disable_raw_mode()?; if let Some(terminal) = &mut terminal {
execute!( disable_raw_mode()?;
terminal.backend_mut(), execute!(
LeaveAlternateScreen, terminal.backend_mut(),
DisableMouseCapture LeaveAlternateScreen,
)?; DisableMouseCapture
terminal.show_cursor()?; )?;
terminal.show_cursor()?;
}
Ok(()) Ok(())
}) })