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>>> {
let backend = CrosstermBackend::new(stdout());
let area = backend.size()?;
let mut engine = Self {
let engine = Self {
exited: Arc::new(AtomicBool::new(false)),
event: RwLock::new(None),
buffer: 0,
buffers: [Buffer::empty(area), Buffer::empty(area)],
area: area.xywh(),
backend,
area: area.xywh(),
};
engine.setup()?;
let engine = Arc::new(RwLock::new(engine));
let _input_thread = {
let engine = engine.clone();
let state = state.clone();
let poll = Duration::from_millis(100);
spawn(move || loop {
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}")
}
let _input_thread = Self::spawn_input_thread(&engine, &state, Duration::from_millis(100));
engine.write().unwrap().setup()?;
let render_thread = Self::spawn_render_thread(&engine, &state, Duration::from_millis(20));
render_thread.join().expect("main thread failed");
engine.write().unwrap().teardown()?;
Ok(state)
}
fn spawn_input_thread <R: Component<Tui> + Sized + 'static> (
engine: &Arc<RwLock<Self>>, state: &Arc<RwLock<R>>, poll: Duration
) -> JoinHandle<()> {
let exited = engine.read().unwrap().exited.clone();
let engine = engine.clone();
let state = state.clone();
spawn(move || loop {
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");
})
};
let main_thread = {
let engine = engine.clone();
let state = state.clone();
let sleep = Duration::from_millis(20);
spawn(move || loop {
let size = {
let engine = engine.read().unwrap();
if engine.exited() {
break
}
engine.backend.size().expect("get size failed").xywh()
};
{
let mut engine = engine.write().unwrap();
engine.area = size;
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)
}
//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
) -> JoinHandle<()> {
let exited = engine.read().unwrap().exited.clone();
let engine = engine.clone();
let state = state.clone();
spawn(move || loop {
if exited.fetch_and(true, Ordering::Relaxed) {
break
}
if let Ok(state) = state.try_read() {
let mut engine = engine.write().unwrap();
engine.area = engine.backend.size().expect("get size failed").xywh();
state.render(&mut engine).expect("render failed");
engine.flip();
}
std::thread::sleep(sleep);
})
}
pub fn event (&self) -> TuiEvent {
self.event.read().unwrap().clone().unwrap()