okay now it does not deadlock

This commit is contained in:
🪞👃🪞 2024-09-06 00:34:26 +03:00
parent 685ccfaf49
commit 80086b9a8b
5 changed files with 36 additions and 36 deletions

View file

@ -15,3 +15,4 @@ midly = "0.5"
once_cell = "1.19.0" once_cell = "1.19.0"
ratatui = { version = "0.26.3", features = [ "unstable-widget-ref", "underline-color" ] } ratatui = { version = "0.26.3", features = [ "unstable-widget-ref", "underline-color" ] }
toml = "0.8.12" toml = "0.8.12"
#no_deadlocks = "1.3.2"

View file

@ -1,4 +1,5 @@
use crate::{*, jack::*}; use jack::*;
use crate::*;
/// A UI component that may be associated with a JACK client by the `Jack` factory. /// A UI component that may be associated with a JACK client by the `Jack` factory.
pub trait Device<E: Engine>: Component<E> + Process { pub trait Device<E: Engine>: Component<E> + Process {

View file

@ -17,8 +17,6 @@ pub struct Tui {
backend: CrosstermBackend<Stdout>, backend: CrosstermBackend<Stdout>,
event: RwLock<Option<TuiEvent>>, event: RwLock<Option<TuiEvent>>,
area: Rect, area: Rect,
sleep: Duration,
poll: Duration,
} }
impl Engine for Tui { impl Engine for Tui {
type HandleInput = Self; type HandleInput = Self;
@ -42,26 +40,10 @@ impl Engine for Tui {
stdout().execute(LeaveAlternateScreen)?; stdout().execute(LeaveAlternateScreen)?;
disable_raw_mode().map_err(Into::into) disable_raw_mode().map_err(Into::into)
} }
fn handle (&self, state: &mut impl Handle<Self>) -> Usually<()> { fn handle (&self, _: &mut impl Handle<Self>) -> Usually<()> {
if ::crossterm::event::poll(self.poll).is_ok() {
let event = ::crossterm::event::read().unwrap();
if let Event::Key(KeyEvent {
code: KeyCode::Char('c'), modifiers: KeyModifiers::CONTROL, ..
}) = event {
self.exited.store(true, Ordering::Relaxed);
} else {
*self.event.write().unwrap() = Some(TuiEvent::Input(event));
let result = state.handle(self);
if let Err(e) = result {
panic!("{e}")
}
}
}
Ok(()) Ok(())
} }
fn render (&mut self, state: &impl Render<Self>) -> Usually<()> { fn render (&mut self, _: &impl Render<Self>) -> Usually<()> {
state.render(self).expect("render failed");
self.flip();
Ok(()) Ok(())
} }
} }
@ -72,42 +54,58 @@ 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 engine = Arc::new(RwLock::new(Self { let mut engine = Self {
sleep: Duration::from_millis(20),
poll: Duration::from_millis(100),
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)],
backend, backend,
area, area,
})); };
engine.setup()?;
let engine = Arc::new(RwLock::new(engine));
let _input_thread = { let _input_thread = {
let engine = engine.clone(); let engine = engine.clone();
let state = state.clone(); let state = state.clone();
let poll = Duration::from_millis(100);
spawn(move || loop { spawn(move || loop {
let engine = engine.read().unwrap(); if ::crossterm::event::poll(poll).is_ok() {
if engine.exited() { 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 break
} }
engine.handle(&mut *state.write().unwrap()).expect("handle failed"); //engine.read().unwrap().handle(&mut *state.write().unwrap()).expect("handle failed");
}) })
}; };
let main_thread = { let main_thread = {
let engine = engine.clone(); let engine = engine.clone();
let state = state.clone(); let state = state.clone();
let sleep = Duration::from_millis(20);
spawn(move || loop { spawn(move || loop {
let mut engine = engine.write().unwrap(); if let (Ok(mut engine), Ok(state)) = (engine.write(), state.try_read()) {
if engine.exited() { if engine.exited() {
break break
} }
if let Ok(state) = state.try_read() {
engine.render(&*state).expect("render failed"); engine.render(&*state).expect("render failed");
engine.flip();
} }
std::thread::sleep(engine.sleep); std::thread::sleep(sleep);
}) })
}; };
main_thread.join().expect("main thread failed"); main_thread.join().expect("main thread failed");
engine.write().unwrap().teardown()?;
Ok(state) Ok(state)
} }
pub fn event (&self) -> TuiEvent { pub fn event (&self) -> TuiEvent {

View file

@ -32,4 +32,4 @@ path = "src/sampler_main.rs"
[[bin]] [[bin]]
name = "tek_plugin" name = "tek_plugin"
path = "src/sampler_main.rs" path = "src/plugin_main.rs"

View file

@ -34,7 +34,7 @@ impl TransportToolbar {
transport.write().unwrap().jack = Some( transport.write().unwrap().jack = Some(
jack.activate( jack.activate(
&transport.clone(), &transport.clone(),
|state, client, scope| { |state: &Arc<RwLock<TransportToolbar>>, client, scope| {
state.write().unwrap().process(client, scope) state.write().unwrap().process(client, scope)
} }
)? )?