From b671d8e0281c8cb4b75afcee3cd46096ab1f5ba8 Mon Sep 17 00:00:00 2001 From: unspeaker Date: Sat, 21 Dec 2024 03:42:58 +0100 Subject: [PATCH] remove ArrangerTrackApi and HasTracks --- crates/tek/src/tui/app_arranger.rs | 9 +- crates/tek/src/tui/arranger_mode_v.rs | 2 +- crates/tek/src/tui/arranger_scene.rs | 2 +- crates/tek/src/tui/arranger_track.rs | 135 +++++++++----------------- 4 files changed, 54 insertions(+), 94 deletions(-) diff --git a/crates/tek/src/tui/app_arranger.rs b/crates/tek/src/tui/app_arranger.rs index 70524722..9e003a96 100644 --- a/crates/tek/src/tui/app_arranger.rs +++ b/crates/tek/src/tui/app_arranger.rs @@ -77,17 +77,16 @@ audio!(|self: ArrangerTui, client, scope|{ // Start profiling cycle let t0 = self.perf.get_t0(); // Update transport clock - if ClockAudio(self).process(client, scope) == Control::Quit { + if Control::Quit == ClockAudio(self).process(client, scope) { return Control::Quit } // Update MIDI sequencers let tracks = &mut self.tracks; let note_buf = &mut self.note_buf; let midi_buf = &mut self.midi_buf; - if TracksAudio(tracks, note_buf, midi_buf, Default::default()) - .process(client, scope) == Control::Quit { - return Control::Quit - } + if Control::Quit == TracksAudio(tracks, note_buf, midi_buf).process(client, scope) { + return Control::Quit + } // FIXME: one of these per playing track //self.now.set(0.); //if let ArrangerSelection::Clip(t, s) = self.selected { diff --git a/crates/tek/src/tui/arranger_mode_v.rs b/crates/tek/src/tui/arranger_mode_v.rs index bbb1a416..35b27563 100644 --- a/crates/tek/src/tui/arranger_mode_v.rs +++ b/crates/tek/src/tui/arranger_mode_v.rs @@ -28,7 +28,7 @@ from!(<'a>|state: &'a ArrangerTui|ArrangerVHead<'a> = Self { // A }); render!(|self: ArrangerVHead<'a>|Tui::push_x(self.scenes_w, row!( (_, track, x1, x2) in ArrangerTrack::with_widths(self.tracks) => { - let (w, h) = (x2 - x1, HEADER_H); + let (w, h) = (ArrangerTrack::MIN_WIDTH.max(x2 - x1), HEADER_H); let color = track.color(); Tui::bg(color.base.rgb, Tui::min_xy(w as u16, h, Fixed::wh(w as u16, 5, col!([ row!(![Tui::fg(color.light.rgb, "▎"), Self::format_name(track, w)]), diff --git a/crates/tek/src/tui/arranger_scene.rs b/crates/tek/src/tui/arranger_scene.rs index 71df8055..8ad8a9bf 100644 --- a/crates/tek/src/tui/arranger_scene.rs +++ b/crates/tek/src/tui/arranger_scene.rs @@ -42,7 +42,7 @@ impl ArrangerScene { } /// Returns true if all phrases in the scene are /// currently playing on the given collection of tracks. - pub fn is_playing (&self, tracks: &[T]) -> bool { + pub fn is_playing (&self, tracks: &[ArrangerTrack]) -> bool { self.clips().iter().any(|clip|clip.is_some()) && self.clips().iter().enumerate() .all(|(track_index, clip)|match clip { Some(clip) => tracks diff --git a/crates/tek/src/tui/arranger_track.rs b/crates/tek/src/tui/arranger_track.rs index 80c366ff..d5f08186 100644 --- a/crates/tek/src/tui/arranger_track.rs +++ b/crates/tek/src/tui/arranger_track.rs @@ -1,6 +1,39 @@ use crate::*; use KeyCode::{Char, Delete}; +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); + } + } +} + + #[derive(Debug)] pub struct ArrangerTrack { /// Name of track pub(crate) name: Arc>, @@ -35,10 +68,8 @@ impl ArrangerTrack { data }) } -} -impl ArrangerTrackApi for ArrangerTrack { /// Name of track - fn name (&self) -> &Arc> { + pub fn name (&self) -> &Arc> { &self.name } /// Preferred width of track column @@ -50,30 +81,20 @@ impl ArrangerTrackApi for ArrangerTrack { &mut self.width } /// Identifying color of track - fn color (&self) -> ItemPalette { + pub fn color (&self) -> ItemPalette { self.color } -} - -pub trait HasTracks: Send + Sync { - fn tracks (&self) -> &Vec; - fn tracks_mut (&mut self) -> &mut Vec; -} - -impl HasTracks for Vec { - fn tracks (&self) -> &Vec { - self + fn longest_name (tracks: &[Self]) -> usize { + tracks.iter().map(|s|s.name().read().unwrap().len()).fold(0, usize::max) } - fn tracks_mut (&mut self) -> &mut Vec { - self + pub const MIN_WIDTH: usize = 6; + fn width_inc (&mut self) { + *self.width_mut() += 1; } -} - -pub trait ArrangerTracksApi: HasTracks { - fn track_add (&mut self, name: Option<&str>, color: Option)-> Usually<&mut T>; - fn track_del (&mut self, index: usize); - fn track_default_name (&self) -> String { - format!("T{}", self.tracks().len() + 1) + fn width_dec (&mut self) { + if self.width() > Self::MIN_WIDTH { + *self.width_mut() -= 1; + } } } @@ -88,51 +109,22 @@ pub enum ArrangerTrackCommand { SetZoom(usize), } -pub trait ArrangerTrackApi: HasPlayer + Send + Sync + Sized { - /// Name of track - fn name (&self) -> &Arc>; - /// Preferred width of track column - fn width (&self) -> usize; - /// Preferred width of track column - fn width_mut (&mut self) -> &mut usize; - /// Identifying color of track - fn color (&self) -> ItemPalette; - - fn longest_name (tracks: &[Self]) -> usize { - tracks.iter().map(|s|s.name().read().unwrap().len()).fold(0, usize::max) - } - - const MIN_WIDTH: usize = 6; - - fn width_inc (&mut self) { - *self.width_mut() += 1; - } - - fn width_dec (&mut self) { - if self.width() > Self::MIN_WIDTH { - *self.width_mut() -= 1; - } - } -} - /// Hosts the JACK callback for a collection of tracks -pub struct TracksAudio<'a, T: ArrangerTrackApi, H: HasTracks>( +pub struct TracksAudio<'a>( // Track collection - pub &'a mut H, + pub &'a mut [ArrangerTrack], /// Note buffer pub &'a mut Vec, /// Note chunk buffer pub &'a mut Vec>>, - /// Marker - pub PhantomData, ); -impl<'a, T: ArrangerTrackApi, H: HasTracks> Audio for TracksAudio<'a, T, H> { +impl<'a> Audio for TracksAudio<'a> { #[inline] fn process (&mut self, client: &Client, scope: &ProcessScope) -> Control { let model = &mut self.0; let note_buffer = &mut self.1; let output_buffer = &mut self.2; - for track in model.tracks_mut().iter_mut() { + for track in model.iter_mut() { if PlayerAudio(track.player_mut(), note_buffer, output_buffer).process(client, scope) == Control::Quit { return Control::Quit } @@ -157,34 +149,3 @@ pub fn to_arranger_track_command (input: &TuiInput, t: usize, len: usize) -> Opt _ => return None }) } -impl HasTracks for ArrangerTui { - fn tracks (&self) -> &Vec { - &self.tracks - } - fn tracks_mut (&mut self) -> &mut Vec { - &mut self.tracks - } -} -impl ArrangerTracksApi for ArrangerTui { - fn track_add (&mut self, name: Option<&str>, color: Option) - -> Usually<&mut ArrangerTrack> - { - let name = name.map_or_else(||self.track_default_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]) - } - fn track_del (&mut self, index: usize) { - self.tracks_mut().remove(index); - for scene in self.scenes_mut().iter_mut() { - scene.clips.remove(index); - } - } -} -