Browse Source

added headless mode for CI

Evan Almloff 3 năm trước cách đây
mục cha
commit
3dd18b21b3
3 tập tin đã thay đổi với 106 bổ sung42 xóa
  1. 45 11
      benches/tui_update.rs
  2. 4 1
      packages/tui/src/config.rs
  3. 57 30
      packages/tui/src/lib.rs

+ 45 - 11
benches/tui_update.rs

@@ -1,15 +1,13 @@
 use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
 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);
 
 /// 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");
-    // 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.
     for size in 1..=6 {
@@ -19,12 +17,48 @@ fn update_boxes(c: &mut Criterion) {
             &size,
             |b, size| {
                 b.iter(|| match size {
-                    1 => dioxus::tui::launch(app5),
-                    2 => dioxus::tui::launch(app10),
-                    3 => dioxus::tui::launch(app15),
-                    4 => dioxus::tui::launch(app20),
-                    5 => dioxus::tui::launch(app25),
-                    6 => dioxus::tui::launch(app30),
+                    1 => dioxus::tui::launch_cfg(
+                        app5,
+                        Config {
+                            headless: true,
+                            ..Default::default()
+                        },
+                    ),
+                    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
packages/tui/src/config.rs

@@ -1,9 +1,11 @@
 #[derive(Clone, Copy)]
 pub struct Config {
     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.
     pub ctrl_c_quit: bool,
+    /// Controls if the terminal should dislay anything, usefull for testing.
+    pub headless: bool,
 }
 
 impl Default for Config {
@@ -11,6 +13,7 @@ impl Default for Config {
         Self {
             rendering_mode: Default::default(),
             ctrl_c_quit: true,
+            headless: false,
         }
     }
 }

+ 57 - 30
packages/tui/src/lib.rs

@@ -15,7 +15,7 @@ use layout::StretchLayout;
 use std::{io, time::Duration};
 use stretch2::{prelude::Size, Stretch};
 use style_attributes::StyleModifier;
-use tui::{backend::CrosstermBackend, Terminal};
+use tui::{backend::CrosstermBackend, layout::Rect, Terminal};
 
 mod config;
 mod hooks;
@@ -51,18 +51,20 @@ pub fn launch_cfg(app: Component<()>, cfg: Config) {
     // Setup input handling
     let (event_tx, event_rx) = unbounded();
     let event_tx_clone = event_tx.clone();
-    std::thread::spawn(move || {
-        let tick_rate = Duration::from_millis(1000);
-        loop {
-            if crossterm::event::poll(tick_rate).unwrap() {
-                // if crossterm::event::poll(timeout).unwrap() {
-                let evt = crossterm::event::read().unwrap();
-                if event_tx.unbounded_send(InputEvent::UserInput(evt)).is_err() {
-                    break;
+    if !cfg.headless {
+        std::thread::spawn(move || {
+            let tick_rate = Duration::from_millis(1000);
+            loop {
+                if crossterm::event::poll(tick_rate).unwrap() {
+                    // if crossterm::event::poll(timeout).unwrap() {
+                    let evt = crossterm::event::read().unwrap();
+                    if event_tx.unbounded_send(InputEvent::UserInput(evt)).is_err() {
+                        break;
+                    }
                 }
             }
-        }
-    });
+        });
+    }
 
     let cx = dom.base_scope();
     cx.provide_root_context(state);
@@ -101,13 +103,17 @@ fn render_vdom(
         .enable_all()
         .build()?
         .block_on(async {
-            enable_raw_mode().unwrap();
-            let mut stdout = std::io::stdout();
-            execute!(stdout, EnterAlternateScreen, EnableMouseCapture).unwrap();
-            let backend = CrosstermBackend::new(io::stdout());
-            let mut terminal = Terminal::new(backend).unwrap();
+            let mut terminal = (!cfg.headless).then(|| {
+                enable_raw_mode().unwrap();
+                let mut stdout = std::io::stdout();
+                execute!(stdout, EnterAlternateScreen, EnableMouseCapture).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 resized = true;
 
@@ -125,9 +131,11 @@ fn render_vdom(
 
                 if !to_rerender.is_empty() || resized {
                     resized = false;
-                    terminal.draw(|frame| {
-                        // size is guaranteed to not change when rendering
-                        let dims = frame.size();
+                    fn resize(
+                        dims: Rect,
+                        stretch: &mut Stretch,
+                        rdom: &RealDom<StretchLayout, StyleModifier>,
+                    ) {
                         let width = dims.width;
                         let height = dims.height;
                         let root_id = rdom.root_id();
@@ -142,9 +150,26 @@ fn render_vdom(
                                 },
                             )
                             .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};
@@ -198,13 +223,15 @@ fn render_vdom(
                 }
             }
 
-            disable_raw_mode()?;
-            execute!(
-                terminal.backend_mut(),
-                LeaveAlternateScreen,
-                DisableMouseCapture
-            )?;
-            terminal.show_cursor()?;
+            if let Some(terminal) = &mut terminal {
+                disable_raw_mode()?;
+                execute!(
+                    terminal.backend_mut(),
+                    LeaveAlternateScreen,
+                    DisableMouseCapture
+                )?;
+                terminal.show_cursor()?;
+            }
 
             Ok(())
         })