89 lines
3.0 KiB
Rust
89 lines
3.0 KiB
Rust
use std::cell::RefCell;
|
|
use std::rc::Rc;
|
|
use std::time::Instant;
|
|
|
|
use gpui::{
|
|
AppContext as _, Context, Entity, IntoElement, ParentElement as _, Render, SharedString,
|
|
Styled as _, TestAppContext, Window, div,
|
|
};
|
|
use gpui_native_core::combobox::{Combobox, ComboboxOption, ComboboxState};
|
|
use gpui_native_core::init;
|
|
|
|
fn option(label: &'static str) -> ComboboxOption<SharedString> {
|
|
(SharedString::from(label), SharedString::from(label))
|
|
}
|
|
|
|
struct Host {
|
|
combobox: Entity<ComboboxState<SharedString>>,
|
|
renders: Rc<RefCell<usize>>,
|
|
}
|
|
|
|
impl Render for Host {
|
|
fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
|
|
*self.renders.borrow_mut() += 1;
|
|
div().size_full().p_4().child(self.combobox.clone())
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn real_keystrokes_are_not_pathologically_slow() {
|
|
let cx = TestAppContext::single();
|
|
cx.update(init);
|
|
let (state, renders, window) = cx.update(|cx| {
|
|
let renders = Rc::new(RefCell::new(0));
|
|
let state_cell: Rc<RefCell<Option<Entity<ComboboxState<SharedString>>>>> =
|
|
Rc::new(RefCell::new(None));
|
|
let renders_for_host = renders.clone();
|
|
let cell = state_cell.clone();
|
|
let window = cx
|
|
.open_window(gpui::WindowOptions::default(), |window, cx| {
|
|
let state = cx.new(|cx| {
|
|
ComboboxState::new(
|
|
Combobox::new(
|
|
"bench-combo",
|
|
"Fruit",
|
|
vec![
|
|
option("main"),
|
|
option("maintain"),
|
|
option("release"),
|
|
option("banana"),
|
|
],
|
|
),
|
|
window,
|
|
cx,
|
|
)
|
|
});
|
|
let state_for_host = state.clone();
|
|
cell.borrow_mut().replace(state.clone());
|
|
cx.new(|_| Host {
|
|
combobox: state_for_host,
|
|
renders: renders_for_host,
|
|
})
|
|
})
|
|
.unwrap();
|
|
let state = state_cell.borrow().clone().expect("state captured");
|
|
(state, renders, window)
|
|
});
|
|
let mut visual = gpui::VisualTestContext::from_window(window.into(), &cx);
|
|
visual.update(|window, cx| {
|
|
state.update(cx, |state, cx| state.focus(window, cx));
|
|
window.draw(cx).clear(cx);
|
|
});
|
|
|
|
let started = Instant::now();
|
|
for letter in "abcdefghijklmnopqrstuvwxyz".chars() {
|
|
visual.simulate_keystrokes(&letter.to_string());
|
|
visual.update(|window, cx| {
|
|
window.draw(cx).clear(cx);
|
|
});
|
|
}
|
|
let elapsed = started.elapsed();
|
|
|
|
let total_renders = *renders.borrow();
|
|
println!(
|
|
"26 real keystrokes: {elapsed:?}, host renders: {total_renders} ({} per keystroke)",
|
|
total_renders as f32 / 26.
|
|
);
|
|
assert!(elapsed.as_millis() < 2000, "typing took {elapsed:?}");
|
|
}
|