trying to fix locking performance

This commit is contained in:
🪞👃🪞 2024-09-15 15:26:57 +03:00
parent 2f09e3230a
commit 60acb20a57

View file

@ -60,66 +60,67 @@ impl Tui {
) -> Usually<Arc<RwLock<R>>> { ) -> Usually<Arc<RwLock<R>>> {
let backend = CrosstermBackend::new(stdout()); let backend = CrosstermBackend::new(stdout());
let area = backend.size()?; let area = backend.size()?;
let mut engine = Self { let engine = Self {
exited: Arc::new(AtomicBool::new(false)), exited: Arc::new(AtomicBool::new(false)),
event: RwLock::new(None), event: RwLock::new(None),
buffer: 0, buffer: 0,
buffers: [Buffer::empty(area), Buffer::empty(area)], buffers: [Buffer::empty(area), Buffer::empty(area)],
area: area.xywh(),
backend, backend,
area: area.xywh(),
}; };
engine.setup()?;
let engine = Arc::new(RwLock::new(engine)); let engine = Arc::new(RwLock::new(engine));
let _input_thread = { let _input_thread = Self::spawn_input_thread(&engine, &state, Duration::from_millis(100));
let engine = engine.clone(); engine.write().unwrap().setup()?;
let state = state.clone(); let render_thread = Self::spawn_render_thread(&engine, &state, Duration::from_millis(20));
let poll = Duration::from_millis(100); render_thread.join().expect("main thread failed");
spawn(move || loop { engine.write().unwrap().teardown()?;
if ::crossterm::event::poll(poll).is_ok() { Ok(state)
let event = TuiEvent::Input(::crossterm::event::read().unwrap()); }
match event { fn spawn_input_thread <R: Component<Tui> + Sized + 'static> (
key!(Ctrl-KeyCode::Char('c')) => { engine: &Arc<RwLock<Self>>, state: &Arc<RwLock<R>>, poll: Duration
engine.write().unwrap().exited.store(true, Ordering::Relaxed); ) -> JoinHandle<()> {
}, let exited = engine.read().unwrap().exited.clone();
_ => { let engine = engine.clone();
*engine.write().unwrap().event.write().unwrap() = Some(event); let state = state.clone();
if let Err(e) = state.write().unwrap().handle(&*engine.read().unwrap()) { spawn(move || loop {
panic!("{e}") if exited.fetch_and(true, Ordering::Relaxed) {
} break
}
if ::crossterm::event::poll(poll).is_ok() {
let event = TuiEvent::Input(::crossterm::event::read().unwrap());
match event {
key!(Ctrl-KeyCode::Char('c')) => {
engine.write().unwrap().exited.store(true, Ordering::Relaxed);
},
_ => {
*engine.write().unwrap().event.write().unwrap() = Some(event);
if let Err(e) = state.write().unwrap().handle(&*engine.read().unwrap()) {
panic!("{e}")
} }
} }
} }
if engine.read().unwrap().exited() { }
break //engine.read().unwrap().handle(&mut *state.write().unwrap()).expect("handle failed");
} })
//engine.read().unwrap().handle(&mut *state.write().unwrap()).expect("handle failed"); }
}) fn spawn_render_thread <R: Component<Tui> + Sized + 'static> (
}; engine: &Arc<RwLock<Self>>, state: &Arc<RwLock<R>>, sleep: Duration
let main_thread = { ) -> JoinHandle<()> {
let engine = engine.clone(); let exited = engine.read().unwrap().exited.clone();
let state = state.clone(); let engine = engine.clone();
let sleep = Duration::from_millis(20); let state = state.clone();
spawn(move || loop { spawn(move || loop {
let size = { if exited.fetch_and(true, Ordering::Relaxed) {
let engine = engine.read().unwrap(); break
if engine.exited() { }
break if let Ok(state) = state.try_read() {
} let mut engine = engine.write().unwrap();
engine.backend.size().expect("get size failed").xywh() engine.area = engine.backend.size().expect("get size failed").xywh();
}; state.render(&mut engine).expect("render failed");
{ engine.flip();
let mut engine = engine.write().unwrap(); }
engine.area = size; std::thread::sleep(sleep);
state.read().unwrap().render(&mut engine).expect("render failed"); })
engine.flip();
std::mem::drop(engine);
}
std::thread::sleep(sleep);
})
};
main_thread.join().expect("main thread failed");
engine.write().unwrap().teardown()?;
Ok(state)
} }
pub fn event (&self) -> TuiEvent { pub fn event (&self) -> TuiEvent {
self.event.read().unwrap().clone().unwrap() self.event.read().unwrap().clone().unwrap()