diff --git a/src/core.rs b/src/core.rs index 7474b042..5fc218a7 100644 --- a/src/core.rs +++ b/src/core.rs @@ -34,7 +34,7 @@ submod!( handle midi render time ); pub type Usually = Result>; /// A UI component. -pub trait Component: Render + Handle { +pub trait Component: Render + Handle + Sync { /// Perform type erasure for collecting heterogeneous components. fn boxed (self) -> Box where Self: Sized + 'static { Box::new(self) @@ -42,7 +42,7 @@ pub trait Component: Render + Handle { } /// Anything that implements `Render` + `Handle` can be used as a UI component. -impl Component for T {} +impl Component for T {} /// A UI component that may be associated with a JACK client by the `Jack` factory. pub trait Device: Render + Handle + Process + Send + Sync { @@ -61,11 +61,11 @@ pub use crate::{submod, render, handle, process, phrase, keymap, key, ports}; // Reexport JACK proto-lib: pub use crate::jack::*; -impl Run for T {} +impl Run for T {} -pub trait Run: Render + Handle + Send + Sized + 'static { - fn run (self, init: Option>)->Usually<()>>) -> Usually<()> { - let app = Arc::new(Mutex::new(self)); +pub trait Run: Render + Handle + Send + Sync + Sized + 'static { + fn run (self, init: Option>)->Usually<()>>) -> Usually<()> { + let app = Arc::new(RwLock::new(self)); let exited = Arc::new(AtomicBool::new(false)); let _input_thread = input_thread(&exited, &app); terminal_setup()?; @@ -106,7 +106,7 @@ pub fn terminal_teardown () -> Usually<()> { /// Main thread render loop pub fn main_thread ( exited: &Arc, - device: &Arc> + device: &Arc> ) -> Usually> { let exited = exited.clone(); let device = device.clone(); @@ -117,7 +117,7 @@ pub fn main_thread ( terminal.draw(|frame|{ let area = frame.size(); let buffer = frame.buffer_mut(); - device.lock().unwrap() + device.read().unwrap() .render(buffer, area) .expect("Failed to render content"); }).expect("Failed to render frame"); @@ -134,7 +134,7 @@ pub fn main_thread ( /// Spawn thread that listens for user input pub fn input_thread ( exited: &Arc, - device: &Arc> + device: &Arc> ) -> JoinHandle<()> { let poll = Duration::from_millis(100); let exited = exited.clone(); @@ -155,7 +155,7 @@ pub fn input_thread ( }) => { exited.store(true, Ordering::Relaxed); }, - _ => if device.lock().unwrap().handle(&AppEvent::Input(event)).is_err() { + _ => if device.write().unwrap().handle(&AppEvent::Input(event)).is_err() { break } } diff --git a/src/core/render.rs b/src/core/render.rs index 56a3fc1d..4964a421 100644 --- a/src/core/render.rs +++ b/src/core/render.rs @@ -62,6 +62,12 @@ impl Render for Arc> { } } +impl Render for Arc> { + fn render (&self, b: &mut Buffer, a: Rect) -> Usually { + self.read().unwrap().render(b, a) + } +} + impl WidgetRef for &dyn Render { fn render_ref (&self, area: Rect, buf: &mut Buffer) { Render::render(*self, buf, area).expect("Failed to render device."); diff --git a/src/jack.rs b/src/jack.rs index ef0a2ebd..1fada643 100644 --- a/src/jack.rs +++ b/src/jack.rs @@ -43,7 +43,7 @@ pub use ::_jack::{ }; /// Just run thing with JACK. Returns the activated client. -pub fn jack_run (name: &str, app: &Arc>) -> Usually +pub fn jack_run (name: &str, app: &Arc>) -> Usually where T: Handle + Process + Send + 'static { let options = ClientOptions::NO_START_SERVER; @@ -59,7 +59,7 @@ pub fn jack_run (name: &str, app: &Arc>) -> Usually Usually<()> { app.quant = 24; // Start main loop - app.run(Some(|app: Arc>|{ - let mut state = app.lock().unwrap(); + app.run(Some(|app: Arc>|{ + let mut state = app.write().unwrap(); // Start JACK and setup device graph let jack = jack_run("tek", &app)?; diff --git a/src/model/phrase.rs b/src/model/phrase.rs index 258e82b2..d8357a63 100644 --- a/src/model/phrase.rs +++ b/src/model/phrase.rs @@ -63,7 +63,7 @@ impl Phrase { _ => {} } LiveEvent::Midi { channel, message }.write(&mut buf).unwrap(); - let t = *time as usize; + let t = *time as usize; // FIXME miscalculated, skipping notes output[t].push(buf); } }