diff --git a/crates/tek_snd/src/snd_arrange.rs b/crates/tek_snd/src/snd_arrange.rs index 90d9829f..7af4782c 100644 --- a/crates/tek_snd/src/snd_arrange.rs +++ b/crates/tek_snd/src/snd_arrange.rs @@ -18,24 +18,3 @@ impl<'a, T: ArrangerModelApi + Send + Sync> Audio for ArrangerRefAudio<'a, T> { Control::Continue } } - -//pub struct ArrangerAudio(pub Arc>); - -//impl Audio for ArrangerAudio { - //#[inline] fn process (&mut self, client: &Client, scope: &ProcessScope) -> Control { - //ArrangerRefAudio(&mut*self.0.write().unwrap()).process(client, scope) - //} -//} - -//pub struct ArrangerRefAudio<'a>(pub &'a mut ArrangerModel); - -//impl<'a> Audio for ArrangerRefAudio<'a> { - //#[inline] fn process (&mut self, client: &Client, scope: &ProcessScope) -> Control { - //for track in self.0.tracks.iter_mut() { - //if MIDIPlayerAudio::from(&mut track.player).process(client, scope) == Control::Quit { - //return Control::Quit - //} - //} - //Control::Continue - //} -//} diff --git a/crates/tek_tui/src/tui_arranger.rs b/crates/tek_tui/src/tui_arranger.rs index d9bd6a12..81bf4fe3 100644 --- a/crates/tek_tui/src/tui_arranger.rs +++ b/crates/tek_tui/src/tui_arranger.rs @@ -12,35 +12,18 @@ pub type ArrangerApp = AppContainer< impl TryFrom<&Arc>> for ArrangerApp { type Error = Box; fn try_from (jack: &Arc>) -> Usually { - let clock = Arc::new(Clock::from(Instant::default())); - - let transport = Arc::new(RwLock::new(tek_api::Transport { - metronome: false, - transport: jack.read().unwrap().transport(), - jack: jack.clone(), - clock: clock.clone() - })); - - let phrases = Arc::new(RwLock::new(PhrasePool { phrases: vec![] })); - - let model = Arc::new(RwLock::new(Arranger { - arrangement: Arc::new(RwLock::new(ArrangerModel { + let model = Arc::new(RwLock::new(ArrangerModel { + name: Arc::new(RwLock::new(String::new())), + phrases: vec![], + scenes: vec![], + tracks: vec![], + transport: TransportModel { + metronome: false, + transport: jack.read().unwrap().transport(), + clock: Arc::new(Clock::from(Instant::default())), jack: jack.clone(), - clock: clock.clone(), - name: Arc::new(RwLock::new(String::new())), - phrases: phrases.clone(), // FIXME - tracks: vec![], - scenes: vec![], - })), - sequencer: Arc::new(RwLock::new(SequencerModel { - transport: transport.clone(), - phrases: phrases.clone(), - player: Arc::new(RwLock::new(MIDIPlayer::new(jack, &clock, "preview")?)), - })), - transport: transport.clone(), - phrases: phrases.clone(), + }, })); - Ok(Self::new( &model, ArrangerView::from(&model), @@ -51,15 +34,8 @@ impl TryFrom<&Arc>> for ArrangerApp { } } -pub struct Arranger { - pub arrangement: Arc>, - pub sequencer: Arc>, - pub transport: Arc>, - pub phrases: Arc>, -} - -impl From<&Arc>> for ArrangerView { - fn from (model: &Arc>) -> Self { +impl From<&Arc>> for ArrangerView { + fn from (model: &Arc>) -> Self { let mut view = Self { model: model.clone(), sequencer: SequencerView::from(&model.read().unwrap().sequencer), @@ -78,7 +54,7 @@ impl From<&Arc>> for ArrangerView { /// Root level object for standalone `tek_arranger` pub struct ArrangerView { - pub model: Arc>, + pub model: ArrangerModel, /// Sequencer component pub sequencer: SequencerView, /// Height of arrangement @@ -124,13 +100,13 @@ impl Audio for ArrangerView { #[inline] fn process (&mut self, _: &Client, _: &ProcessScope) -> Control { // FIXME: one of these per playing track if let ArrangerFocus::Clip(t, s) = self.selected { - let phrase = self.model.scenes.get(s).map(|scene|scene.clips.get(t)); + let phrase = self.model.scenes().get(s).map(|scene|scene.clips.get(t)); if let Some(Some(Some(phrase))) = phrase { - if let Some(track) = self.model.tracks.get(t) { + if let Some(track) = self.model.tracks().get(t) { if let Some((ref started_at, Some(ref playing))) = track.player.phrase { let phrase = phrase.read().unwrap(); if *playing.read().unwrap() == *phrase { - let pulse = self.sequencer.transport.model.clock.current.pulse.get(); + let pulse = self.sequencer.transport.model.clock().current.pulse.get(); let start = started_at.pulse.get(); let now = (pulse - start) % phrase.length as f64; self.sequencer.editor.now.set(now); @@ -192,17 +168,15 @@ impl ArrangerView { /// Focus the editor with the current phrase pub fn show_phrase (&mut self) { - let arrangement = self.model.read().unwrap().arrangement.read().unwrap(); self.sequencer.editor.show(self.selected_phrase().as_ref()); } pub fn activate (&mut self) { - let arrangement = self.model.read().unwrap().arrangement.read().unwrap(); match self.selected { ArrangerFocus::Scene(s) => { - for (t, track) in self.model.tracks.iter_mut().enumerate() { + for (t, track) in self.model.tracks_mut().iter_mut().enumerate() { let player = &mut track.player; - let clip = self.model.scenes[s].clips[t].as_ref(); + let clip = self.model.scenes()[s].clips[t].as_ref(); if player.phrase.is_some() || clip.is_some() { player.enqueue_next(clip); } @@ -214,25 +188,23 @@ impl ArrangerView { //} }, ArrangerFocus::Clip(t, s) => { - let clip = self.model.scenes[s].clips[t].as_ref(); - self.model.tracks[t].player.enqueue_next(clip); + let clip = self.model.scenes()[s].clips[t].as_ref(); + self.model.tracks_mut()[t].player.enqueue_next(clip); }, _ => {} } } pub fn is_first_row (&self) -> bool { - let arrangement = self.model.read().unwrap().arrangement.read().unwrap(); let selected = self.selected; selected.is_mix() || selected.is_track() } pub fn is_last_row (&self) -> bool { - let arrangement = self.model.read().unwrap().arrangement.read().unwrap(); let selected = self.selected; - (self.model.scenes.len() == 0 && (selected.is_mix() || selected.is_track())) || match selected { - ArrangerFocus::Scene(s) => s == self.model.scenes.len() - 1, - ArrangerFocus::Clip(_, s) => s == self.model.scenes.len() - 1, + (self.model.scenes().len() == 0 && (selected.is_mix() || selected.is_track())) || match selected { + ArrangerFocus::Scene(s) => s == self.model.scenes().len() - 1, + ArrangerFocus::Clip(_, s) => s == self.model.scenes().len() - 1, _ => false } } @@ -244,29 +216,28 @@ impl ArrangerView { } pub fn randomize_color (&mut self) { - let arrangement = self.model.read().unwrap().arrangement.read().unwrap(); match self.selected { ArrangerFocus::Mix => { self.color = ItemColor::random_dark() }, ArrangerFocus::Track(t) => { - self.model.tracks[t].color = ItemColor::random() + self.model.tracks_mu()[t].color = ItemColor::random() }, ArrangerFocus::Scene(s) => { - self.model.scenes[s].color = ItemColor::random() + self.model.scenes_mut()[s].color = ItemColor::random() }, ArrangerFocus::Clip(t, s) => { - if let Some(phrase) = &self.model.scenes[s].clips[t] { + if let Some(phrase) = &self.model.scenes_mut()[s].clips[t] { phrase.write().unwrap().color = ItemColorTriplet::random(); } } } } pub fn selected_scene (&self) -> Option<&ArrangerScene> { - self.selected.scene().map(|s|self.model.scenes.get(s)).flatten() + self.selected.scene().map(|s|self.model.scenes().get(s)).flatten() } pub fn selected_scene_mut (&mut self) -> Option<&mut ArrangerScene> { - self.selected.scene().map(|s|self.model.scenes.get_mut(s)).flatten() + self.selected.scene().map(|s|self.model.scenes_mut().get_mut(s)).flatten() } pub fn selected_phrase (&self) -> Option>> { self.selected_scene()?.clips.get(self.selected.track()?)?.clone() diff --git a/crates/tek_tui/src/tui_transport.rs b/crates/tek_tui/src/tui_transport.rs index d3ac96df..af5bc988 100644 --- a/crates/tek_tui/src/tui_transport.rs +++ b/crates/tek_tui/src/tui_transport.rs @@ -1,5 +1,4 @@ use crate::*; -use tek_api::Transport; pub type TransportApp = AppContainer< Tui, @@ -13,13 +12,12 @@ pub type TransportApp = AppContainer< impl TryFrom<&Arc>> for TransportApp { type Error = Box; fn try_from (jack: &Arc>) -> Usually { - let model = Arc::new(RwLock::new(Transport { + let model = Arc::new(RwLock::new(TransportModel { metronome: false, transport: jack.read().unwrap().transport(), jack: jack.clone(), clock: Arc::new(Clock::from(Instant::default())) })); - Ok(Self::new( &model, TransportView::from(&model), @@ -33,8 +31,8 @@ impl TryFrom<&Arc>> for TransportApp { /// Stores and displays time-related info. #[derive(Debug)] pub struct TransportView { - _engine: PhantomData, - pub model: Arc>, + _engine: PhantomData, + pub model: TransportModel, pub focus: TransportViewFocus, pub focused: bool, pub size: Measure,