From f1847b62b8aa0fa54d2f0716e04f7639f7d53ba6 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Tue, 24 Dec 2024 23:49:46 +0100 Subject: [PATCH] cleanup; remove tracks/scenes[_mut]() methods in favor of direct property access --- crates/tek/src/tui/app_arranger.rs | 24 ++--- crates/tek/src/tui/arranger_command.rs | 68 +++++++++++--- crates/tek/src/tui/arranger_mode_v/v_clips.rs | 2 +- .../tek/src/tui/arranger_mode_v/v_cursor.rs | 6 +- crates/tek/src/tui/arranger_mode_v/v_head.rs | 4 +- crates/tek/src/tui/arranger_mode_v/v_sep.rs | 6 +- crates/tek/src/tui/arranger_scene.rs | 76 ++++++--------- crates/tek/src/tui/arranger_track.rs | 93 ++++++------------- 8 files changed, 125 insertions(+), 154 deletions(-) diff --git a/crates/tek/src/tui/app_arranger.rs b/crates/tek/src/tui/app_arranger.rs index 72c36158..de5372ad 100644 --- a/crates/tek/src/tui/app_arranger.rs +++ b/crates/tek/src/tui/app_arranger.rs @@ -36,8 +36,8 @@ impl ArrangerTui { self.clock().play_from(Some(0))?; } } else if let ArrangerSelection::Clip(t, s) = self.selected { - let phrase = self.scenes()[s].clips[t].clone(); - self.tracks_mut()[t].player.enqueue_next(phrase.as_ref()); + let phrase = self.scenes[s].clips[t].clone(); + self.tracks[t].player.enqueue_next(phrase.as_ref()); }; Ok(()) } @@ -51,19 +51,11 @@ impl ArrangerTui { } pub fn randomize_color (&mut self) { match self.selected { - ArrangerSelection::Mix => { - self.color = ItemPalette::random() - }, - ArrangerSelection::Track(t) => { - self.tracks_mut()[t].color = ItemPalette::random() - }, - ArrangerSelection::Scene(s) => { - self.scenes_mut()[s].color = ItemPalette::random() - }, - ArrangerSelection::Clip(t, s) => { - if let Some(phrase) = &self.scenes_mut()[s].clips[t] { - phrase.write().unwrap().color = ItemPalette::random(); - } + ArrangerSelection::Mix => { self.color = ItemPalette::random() }, + ArrangerSelection::Track(t) => { self.tracks[t].color = ItemPalette::random() }, + ArrangerSelection::Scene(s) => { self.scenes[s].color = ItemPalette::random() }, + ArrangerSelection::Clip(t, s) => if let Some(phrase) = &self.scenes[s].clips[t] { + phrase.write().unwrap().color = ItemPalette::random(); } } } @@ -138,7 +130,7 @@ audio!(|self: ArrangerTui, client, scope|{ // FIXME: one of these per playing track //self.now.set(0.); //if let ArrangerSelection::Clip(t, s) = self.selected { - //let phrase = self.scenes().get(s).map(|scene|scene.clips.get(t)); + //let phrase = self.scenes.get(s).map(|scene|scene.clips.get(t)); //if let Some(Some(Some(phrase))) = phrase { //if let Some(track) = self.tracks().get(t) { //if let Some((ref started_at, Some(ref playing))) = track.player.play_phrase { diff --git a/crates/tek/src/tui/arranger_command.rs b/crates/tek/src/tui/arranger_command.rs index 7d128e94..71e23a31 100644 --- a/crates/tek/src/tui/arranger_command.rs +++ b/crates/tek/src/tui/arranger_command.rs @@ -20,9 +20,37 @@ use KeyCode::{Char, Delete, Tab}; PutClip(usize, usize, Option>>), EnqueueClip(usize, usize), EnqueueScene(usize), - StopTrack(usize), StopAll, } +#[derive(Clone, Debug)] +pub enum ArrangerTrackCommand { + Add, + Delete(usize), + Stop(usize), + Swap(usize, usize), + SetSize(usize), + SetZoom(usize), + SetColor(usize, ItemPalette), +} +#[derive(Clone, Debug)] +pub enum ArrangerSceneCommand { + Add, + Delete(usize), + Swap(usize, usize), + SetSize(usize), + SetZoom(usize), + SetColor(usize, ItemPalette), +} +#[derive(Clone, Debug)] +pub enum ArrangerClipCommand { + Play, + Get(usize, usize), + Set(usize, usize, Option>>), + Edit(Option>>), + SetLoop(bool), + SetColor(ItemPalette), +} + input_to_command!(ArrangerCommand: |state: ArrangerTui, input|{ use ArrangerSelection as Selected; use ArrangerSceneCommand as Scene; @@ -186,10 +214,6 @@ command!(|self:ArrangerCommand,state:ArrangerTui|match self { } None }, - Self::StopTrack(track) => { - state.tracks[track].player.enqueue_next(None); - None - }, Self::StopAll => { for track in 0..state.tracks.len() { state.tracks[track].player.enqueue_next(None); @@ -197,16 +221,30 @@ command!(|self:ArrangerCommand,state:ArrangerTui|match self { None }, }); - -#[derive(Clone, Debug)] -pub enum ArrangerClipCommand { - Play, - Get(usize, usize), - Set(usize, usize, Option>>), - Edit(Option>>), - SetLoop(bool), - SetColor(ItemPalette), -} +command!(|self: ArrangerTrackCommand, state: ArrangerTui|match self { + Self::SetColor(index, color) => { + let old = state.tracks[index].color; + state.tracks[index].color = color; + Some(Self::SetColor(index, old)) + }, + Self::Stop(track) => { + state.tracks[track].player.enqueue_next(None); + None + }, + _ => None +}); +command!(|self:ArrangerSceneCommand,state:ArrangerTui|match self { + Self::Delete(index) => { + state.scene_del(index); + None + }, + Self::SetColor(index, color) => { + let old = state.scenes[index].color; + state.scenes[index].color = color; + Some(Self::SetColor(index, old)) + }, + _ => None +}); command!(|self:ArrangerClipCommand, _state:ArrangerTui|match self { _ => None }); diff --git a/crates/tek/src/tui/arranger_mode_v/v_clips.rs b/crates/tek/src/tui/arranger_mode_v/v_clips.rs index 64d785c5..41cd38e2 100644 --- a/crates/tek/src/tui/arranger_mode_v/v_clips.rs +++ b/crates/tek/src/tui/arranger_mode_v/v_clips.rs @@ -12,7 +12,7 @@ from!(<'a>|args:(&'a ArrangerTui, usize)|ArrangerVClips<'a> = Self { size: &args.0.size, scenes: &args.0.scenes, tracks: &args.0.tracks, - rows: ArrangerScene::ppqs(args.0.scenes(), args.1), + rows: ArrangerScene::ppqs(&args.0.scenes, args.1), }); render!(|self: ArrangerVClips<'a>|Fill::wh( diff --git a/crates/tek/src/tui/arranger_mode_v/v_cursor.rs b/crates/tek/src/tui/arranger_mode_v/v_cursor.rs index 3dfb0123..0dcd85e2 100644 --- a/crates/tek/src/tui/arranger_mode_v/v_cursor.rs +++ b/crates/tek/src/tui/arranger_mode_v/v_cursor.rs @@ -11,10 +11,10 @@ pub struct ArrangerVCursor { } from!(|args:(&ArrangerTui, usize)|ArrangerVCursor = Self { - cols: ArrangerTrack::widths(args.0.tracks()), - rows: ArrangerScene::ppqs(args.0.scenes(), args.1), + cols: ArrangerTrack::widths(&args.0.tracks), + rows: ArrangerScene::ppqs(&args.0.scenes, args.1), selected: args.0.selected(), - scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(args.0.scenes()) as u16, + scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(&args.0.scenes) as u16, color: args.0.color, reticle: Reticle(Style { fg: Some(args.0.color.lighter.rgb), diff --git a/crates/tek/src/tui/arranger_mode_v/v_head.rs b/crates/tek/src/tui/arranger_mode_v/v_head.rs index 7b22a523..d2e7e812 100644 --- a/crates/tek/src/tui/arranger_mode_v/v_head.rs +++ b/crates/tek/src/tui/arranger_mode_v/v_head.rs @@ -9,10 +9,10 @@ pub struct ArrangerVHead<'a> { } from!(<'a>|state: &'a ArrangerTui|ArrangerVHead<'a> = Self { // A - tracks: state.tracks(), + tracks: &state.tracks, timebase: state.clock().timebase(), current: &state.clock().playhead, - scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(state.scenes()) as u16, + scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(&state.scenes) as u16, }); render!(|self: ArrangerVHead<'a>|Tui::push_x(self.scenes_w, row!( diff --git a/crates/tek/src/tui/arranger_mode_v/v_sep.rs b/crates/tek/src/tui/arranger_mode_v/v_sep.rs index acde7617..f895e27e 100644 --- a/crates/tek/src/tui/arranger_mode_v/v_sep.rs +++ b/crates/tek/src/tui/arranger_mode_v/v_sep.rs @@ -9,8 +9,8 @@ pub struct ArrangerVColSep { from!(|state:&ArrangerTui|ArrangerVColSep = Self { fg: TuiTheme::separator_fg(false), - cols: ArrangerTrack::widths(state.tracks()), - scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(state.scenes()) as u16, + cols: ArrangerTrack::widths(&state.tracks), + scenes_w: SCENES_W_OFFSET + ArrangerScene::longest_name(&state.scenes) as u16, }); render!(|self: ArrangerVColSep|render(move|to: &mut TuiOutput|{ @@ -30,7 +30,7 @@ pub struct ArrangerVRowSep { from!(|args:(&ArrangerTui, usize)|ArrangerVRowSep = Self { fg: TuiTheme::separator_fg(false), - rows: ArrangerScene::ppqs(args.0.scenes(), args.1), + rows: ArrangerScene::ppqs(&args.0.scenes, args.1), }); render!(|self: ArrangerVRowSep|render(move|to: &mut TuiOutput|{ diff --git a/crates/tek/src/tui/arranger_scene.rs b/crates/tek/src/tui/arranger_scene.rs index 6e6b0f1a..ddbf3114 100644 --- a/crates/tek/src/tui/arranger_scene.rs +++ b/crates/tek/src/tui/arranger_scene.rs @@ -1,22 +1,33 @@ use crate::*; -#[derive(Clone, Debug)] -pub enum ArrangerSceneCommand { - Add, - Delete(usize), - Swap(usize, usize), - SetSize(usize), - SetZoom(usize), - SetColor(usize, ItemPalette), + +impl ArrangerTui { + pub fn scene_add (&mut self, name: Option<&str>, color: Option) + -> Usually<&mut ArrangerScene> + { + let name = name.map_or_else(||self.scene_default_name(), |x|x.to_string()); + let scene = ArrangerScene { + name: Arc::new(name.into()), + clips: vec![None;self.tracks.len()], + color: color.unwrap_or_else(||ItemPalette::random()), + }; + self.scenes.push(scene); + let index = self.scenes.len() - 1; + Ok(&mut self.scenes[index]) + } + pub fn scene_del (&mut self, index: usize) { + todo!("delete scene"); + } + fn scene_default_name (&self) -> String { + format!("S{:3>}", self.scenes.len() + 1) + } + pub fn selected_scene (&self) -> Option<&ArrangerScene> { + self.selected.scene().map(|s|self.scenes.get(s)).flatten() + } + pub fn selected_scene_mut (&mut self) -> Option<&mut ArrangerScene> { + self.selected.scene().map(|s|self.scenes.get_mut(s)).flatten() + } } -command!(|self:ArrangerSceneCommand,state:ArrangerTui|match self { - //Self::Delete(index) => { state.scene_del(index); }, - Self::SetColor(index, color) => { - let old = state.scenes[index].color; - state.scenes[index].color = color; - Some(Self::SetColor(index, old)) - }, - _ => None -}); + #[derive(Default, Debug, Clone)] pub struct ArrangerScene { /// Name of scene pub(crate) name: Arc>, @@ -25,6 +36,7 @@ command!(|self:ArrangerSceneCommand,state:ArrangerTui|match self { /// Identifying color of scene pub(crate) color: ItemPalette, } + impl ArrangerScene { pub fn name (&self) -> &Arc> { &self.name @@ -80,33 +92,3 @@ impl ArrangerScene { match self.clips().get(index) { Some(Some(clip)) => Some(clip), _ => None } } } -impl ArrangerTui { - pub fn scenes (&self) -> &Vec { - &self.scenes - } - pub fn scenes_mut (&mut self) -> &mut Vec { - &mut self.scenes - } - pub fn scene_add (&mut self, name: Option<&str>, color: Option) - -> Usually<&mut ArrangerScene> - { - let name = name.map_or_else(||self.scene_default_name(), |x|x.to_string()); - let scene = ArrangerScene { - name: Arc::new(name.into()), - clips: vec![None;self.tracks().len()], - color: color.unwrap_or_else(||ItemPalette::random()), - }; - self.scenes_mut().push(scene); - let index = self.scenes().len() - 1; - Ok(&mut self.scenes_mut()[index]) - } - fn scene_default_name (&self) -> String { - format!("S{:3>}", self.scenes().len() + 1) - } - pub fn selected_scene (&self) -> Option<&ArrangerScene> { - self.selected.scene().map(|s|self.scenes().get(s)).flatten() - } - pub fn selected_scene_mut (&mut self) -> Option<&mut ArrangerScene> { - self.selected.scene().map(|s|self.scenes_mut().get_mut(s)).flatten() - } -} diff --git a/crates/tek/src/tui/arranger_track.rs b/crates/tek/src/tui/arranger_track.rs index cde88c30..20c2f69f 100644 --- a/crates/tek/src/tui/arranger_track.rs +++ b/crates/tek/src/tui/arranger_track.rs @@ -1,32 +1,31 @@ use crate::*; use KeyCode::{Char, Delete}; -pub fn to_arranger_track_command (input: &TuiInput, t: usize, len: usize) -> Option { - use ArrangerCommand::*; - use ArrangerSelection as Selected; - use ArrangerTrackCommand as Tracks; - Some(match input.event() { - key_pat!(Char('s')) => Select(Selected::Clip(t, 0)), - key_pat!(Char('a')) => Select(if t > 0 { Selected::Track(t - 1) } else { Selected::Mix }), - key_pat!(Char('d')) => Select(Selected::Track((t + 1).min(len.saturating_sub(1)))), - key_pat!(Char('c')) => Track(Tracks::SetColor(t, ItemPalette::random())), - key_pat!(Char(',')) => Track(Tracks::Swap(t, t - 1)), - key_pat!(Char('.')) => Track(Tracks::Swap(t, t + 1)), - key_pat!(Char('<')) => Track(Tracks::Swap(t, t - 1)), - key_pat!(Char('>')) => Track(Tracks::Swap(t, t + 1)), - key_pat!(Delete) => Track(Tracks::Delete(t)), - //key_pat!(Char('c')) => Cmd::Track(Track::Color(t, ItemPalette::random())), - _ => return None - }) +impl ArrangerTui { + pub fn track_next_name (&self) -> String { + format!("T{}", self.tracks.len() + 1) + } + pub fn track_add (&mut self, name: Option<&str>, color: Option) + -> Usually<&mut ArrangerTrack> + { + let name = name.map_or_else(||self.track_next_name(), |x|x.to_string()); + let track = ArrangerTrack { + width: name.len() + 2, + name: Arc::new(name.into()), + color: color.unwrap_or_else(||ItemPalette::random()), + player: PhrasePlayerModel::from(&self.clock), + }; + self.tracks.push(track); + let index = self.tracks.len() - 1; + Ok(&mut self.tracks[index]) + } + pub fn track_del (&mut self, index: usize) { + self.tracks.remove(index); + for scene in self.scenes.iter_mut() { + scene.clips.remove(index); + } + } } -command!(|self: ArrangerTrackCommand, state: ArrangerTui|match self { - Self::SetColor(index, color) => { - let old = state.tracks[index].color; - state.tracks[index].color = color; - Some(Self::SetColor(index, old)) - }, - _ => None -}); #[derive(Debug)] pub struct ArrangerTrack { /// Name of track @@ -38,8 +37,10 @@ command!(|self: ArrangerTrackCommand, state: ArrangerTui|match self { /// MIDI player state pub(crate) player: PhrasePlayerModel, } + has_clock!(|self:ArrangerTrack|self.player.clock()); has_player!(|self:ArrangerTrack|self.player); + impl ArrangerTrack { pub fn widths (tracks: &[Self]) -> Vec<(usize, usize)> { let mut widths = vec![]; @@ -92,17 +93,6 @@ impl ArrangerTrack { } } -#[derive(Clone, Debug)] -pub enum ArrangerTrackCommand { - Add, - Delete(usize), - Stop, - Swap(usize, usize), - SetSize(usize), - SetZoom(usize), - SetColor(usize, ItemPalette), -} - /// Hosts the JACK callback for a collection of tracks pub struct TracksAudio<'a>( // Track collection @@ -126,34 +116,3 @@ impl<'a> Audio for TracksAudio<'a> { Control::Continue } } -impl ArrangerTui { - pub fn tracks (&self) -> &Vec { - &self.tracks - } - pub fn tracks_mut (&mut self) -> &mut Vec { - &mut self.tracks - } - pub fn track_next_name (&self) -> String { - format!("T{}", self.tracks().len() + 1) - } - pub fn track_add (&mut self, name: Option<&str>, color: Option) - -> Usually<&mut ArrangerTrack> - { - let name = name.map_or_else(||self.track_next_name(), |x|x.to_string()); - let track = ArrangerTrack { - width: name.len() + 2, - name: Arc::new(name.into()), - color: color.unwrap_or_else(||ItemPalette::random()), - player: PhrasePlayerModel::from(&self.clock), - }; - self.tracks_mut().push(track); - let index = self.tracks().len() - 1; - Ok(&mut self.tracks_mut()[index]) - } - pub fn track_del (&mut self, index: usize) { - self.tracks_mut().remove(index); - for scene in self.scenes_mut().iter_mut() { - scene.clips.remove(index); - } - } -}