diff --git a/crates/tek_core/src/engine.rs b/crates/tek_core/src/engine.rs index d5fb7bff..0958fbef 100644 --- a/crates/tek_core/src/engine.rs +++ b/crates/tek_core/src/engine.rs @@ -6,7 +6,7 @@ pub trait App { } /// Platform backend. -pub trait Engine: Sized { +pub trait Engine: Send + Sync + Sized { fn setup (&mut self) -> Usually<()> { Ok(()) } fn exited (&self) -> bool; fn teardown (&mut self) -> Usually<()> { Ok(()) } diff --git a/crates/tek_core/src/lib.rs b/crates/tek_core/src/lib.rs index 0ba950a9..40967bd3 100644 --- a/crates/tek_core/src/lib.rs +++ b/crates/tek_core/src/lib.rs @@ -9,6 +9,7 @@ pub use once_cell::sync::Lazy; pub use std::sync::atomic::{Ordering, AtomicBool}; pub use std::rc::Rc; pub use std::cell::RefCell; +pub use std::marker::PhantomData; pub(crate) use std::error::Error; pub(crate) use std::io::{stdout}; pub(crate) use std::thread::{spawn, JoinHandle}; diff --git a/crates/tek_mixer/src/mixer.rs b/crates/tek_mixer/src/mixer.rs index a04a4309..a5a54fa5 100644 --- a/crates/tek_mixer/src/mixer.rs +++ b/crates/tek_mixer/src/mixer.rs @@ -30,12 +30,13 @@ impl Process for Mixer { Control::Continue } } -impl Render for Mixer { - fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { +impl Content for Mixer { + type Engine = Tui; + fn content (&self) -> impl Widget { let mut tracks = Split::right(); for channel in self.tracks.iter() { tracks = tracks.add_ref(channel) } - tracks.render(to) + tracks } } diff --git a/crates/tek_mixer/src/track_view.rs b/crates/tek_mixer/src/track_view.rs index eb26cc8b..efb7838f 100644 --- a/crates/tek_mixer/src/track_view.rs +++ b/crates/tek_mixer/src/track_view.rs @@ -1,13 +1,9 @@ use crate::*; use tek_core::Direction; -impl Layout for Track { - fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { - todo!() - } -} -impl Render for Track { - fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { +impl Content for Track { + type Engine = Tui; + fn content (&self) -> impl Widget { TrackView { chain: Some(&self), direction: tek_core::Direction::Right, @@ -26,7 +22,7 @@ impl Render for Track { //pub output_ports: Vec>, //pub post_fader_meter: f64, //pub route: String, - }.render(to) + } } } pub struct TrackView<'a, E: Engine> { @@ -35,7 +31,11 @@ pub struct TrackView<'a, E: Engine> { pub focused: bool, pub entered: bool, } -impl<'a> Render for TrackView<'a, Tui> { +impl<'a> Widget for TrackView<'a, Tui> { + type Engine = Tui; + fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { + todo!() + } fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { todo!(); //let mut area = to.area(); diff --git a/crates/tek_sequencer/src/arranger.rs b/crates/tek_sequencer/src/arranger.rs index 8fcdeee2..f2f74642 100644 --- a/crates/tek_sequencer/src/arranger.rs +++ b/crates/tek_sequencer/src/arranger.rs @@ -6,7 +6,7 @@ pub struct Arranger { /// Name of arranger pub name: Arc>, /// Collection of tracks. - pub tracks: Vec, + pub tracks: Vec>, /// Collection of scenes. pub scenes: Vec, /// Currently selected element. @@ -45,12 +45,12 @@ impl Arranger { _ => {} } } - pub fn sequencer (&self) -> Option<&Sequencer> { + pub fn sequencer (&self) -> Option<&Sequencer> { self.selected.track() .map(|track|self.tracks.get(track)) .flatten() } - pub fn sequencer_mut (&mut self) -> Option<&mut Sequencer> { + pub fn sequencer_mut (&mut self) -> Option<&mut Sequencer> { self.selected.track() .map(|track|self.tracks.get_mut(track)) .flatten() @@ -99,13 +99,11 @@ impl ArrangerViewMode { } } } -impl Layout for Arranger { +impl Widget for Arranger { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} -/// Render arranger to terminal -impl Render for Arranger { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { let area = (|to|match self.mode { ArrangerViewMode::Horizontal => diff --git a/crates/tek_sequencer/src/arranger_rename.rs b/crates/tek_sequencer/src/arranger_rename.rs index 62f82aa6..ce547f1d 100644 --- a/crates/tek_sequencer/src/arranger_rename.rs +++ b/crates/tek_sequencer/src/arranger_rename.rs @@ -13,16 +13,18 @@ impl Arranger { } } /// Appears on first run (i.e. if state dir is missing). -pub struct ArrangerRenameModal { +pub struct ArrangerRenameModal { + _engine: std::marker::PhantomData, done: bool, target: ArrangerFocus, value: String, result: Arc>, cursor: usize } -impl ArrangerRenameModal { +impl ArrangerRenameModal { pub fn new (target: ArrangerFocus, value: &Arc>) -> Self { Self { + _engine: Default::default(), done: false, target, value: value.read().unwrap().clone(), @@ -31,7 +33,11 @@ impl ArrangerRenameModal { } } } -impl Render for ArrangerRenameModal { +impl Widget for ArrangerRenameModal { + type Engine = Tui; + fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { + todo!() + } fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { let area = to.area(); let y = area.y() + area.h() / 2; @@ -53,7 +59,7 @@ impl Render for ArrangerRenameModal { Ok(Some(area)) } } -impl Handle for ArrangerRenameModal { +impl Handle for ArrangerRenameModal { fn handle (&mut self, from: &Tui) -> Perhaps { match from.event() { TuiEvent::Input(Event::Key(k)) => { @@ -91,7 +97,7 @@ impl Handle for ArrangerRenameModal { } } } -impl Exit for ArrangerRenameModal { +impl Exit for ArrangerRenameModal { fn exited (&self) -> bool { self.done } @@ -99,8 +105,3 @@ impl Exit for ArrangerRenameModal { self.done = true } } -impl Layout for ArrangerRenameModal { - fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { - todo!() - } -} diff --git a/crates/tek_sequencer/src/arranger_track.rs b/crates/tek_sequencer/src/arranger_track.rs index 267009b2..74404c54 100644 --- a/crates/tek_sequencer/src/arranger_track.rs +++ b/crates/tek_sequencer/src/arranger_track.rs @@ -4,10 +4,10 @@ use super::Arranger; /// Track management methods impl Arranger { - pub fn track (&self) -> Option<&Sequencer> { + pub fn track (&self) -> Option<&Sequencer> { self.selected.track().map(|t|self.tracks.get(t)).flatten() } - pub fn track_mut (&mut self) -> Option<&mut Sequencer> { + pub fn track_mut (&mut self) -> Option<&mut Sequencer> { self.selected.track().map(|t|self.tracks.get_mut(t)).flatten() } pub fn track_next (&mut self) { @@ -16,7 +16,7 @@ impl Arranger { pub fn track_prev (&mut self) { self.selected.track_prev() } - pub fn track_add (&mut self, name: Option<&str>) -> Usually<&mut Sequencer> { + pub fn track_add (&mut self, name: Option<&str>) -> Usually<&mut Sequencer> { self.tracks.push(name.map_or_else( || Sequencer::new(&self.track_default_name()), |name| Sequencer::new(name), @@ -32,13 +32,13 @@ impl Arranger { } } -pub fn track_name_max_len (tracks: &[Sequencer]) -> usize { +pub fn track_name_max_len (tracks: &[Sequencer]) -> usize { tracks.iter() .map(|s|s.name.read().unwrap().len()) .fold(0, usize::max) } -pub fn track_clip_name_lengths (tracks: &[Sequencer]) -> Vec<(usize, usize)> { +pub fn track_clip_name_lengths (tracks: &[Sequencer]) -> Vec<(usize, usize)> { let mut total = 0; let mut lengths: Vec<(usize, usize)> = tracks.iter().map(|track|{ let len = 4 + track.phrases diff --git a/crates/tek_sequencer/src/arranger_view_h.rs b/crates/tek_sequencer/src/arranger_view_h.rs index 4b91ee80..fdf47da2 100644 --- a/crates/tek_sequencer/src/arranger_view_h.rs +++ b/crates/tek_sequencer/src/arranger_view_h.rs @@ -17,15 +17,13 @@ pub fn draw (state: &Arranger, to: &mut Tui) -> Perhaps<[u16;4]> { ]).render(to.with_rect(area)) } -struct TrackNameColumn<'a>(&'a [Sequencer], ArrangerFocus); +struct TrackNameColumn<'a>(&'a [Sequencer], ArrangerFocus); -impl<'a> Layout for TrackNameColumn<'a> { +impl<'a> Widget for TrackNameColumn<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for TrackNameColumn<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { todo!(); //let Self(tracks, selected) = self; @@ -51,15 +49,13 @@ impl<'a> Render for TrackNameColumn<'a> { } } -struct TrackMonitorColumn<'a>(&'a [Sequencer]); +struct TrackMonitorColumn<'a>(&'a [Sequencer]); -impl<'a> Layout for TrackMonitorColumn<'a> { +impl<'a> Widget for TrackMonitorColumn<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for TrackMonitorColumn<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { todo!(); //let Self(tracks) = self; @@ -86,15 +82,13 @@ impl<'a> Render for TrackMonitorColumn<'a> { } } -struct TrackRecordColumn<'a>(&'a [Sequencer]); +struct TrackRecordColumn<'a>(&'a [Sequencer]); -impl<'a> Layout for TrackRecordColumn<'a> { +impl<'a> Widget for TrackRecordColumn<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for TrackRecordColumn<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { todo!(); //let Self(tracks) = self; @@ -121,15 +115,13 @@ impl<'a> Render for TrackRecordColumn<'a> { } } -struct TrackOverdubColumn<'a>(&'a [Sequencer]); +struct TrackOverdubColumn<'a>(&'a [Sequencer]); -impl<'a> Layout for TrackOverdubColumn<'a> { +impl<'a> Widget for TrackOverdubColumn<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for TrackOverdubColumn<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { todo!(); //let Self(tracks) = self; @@ -159,15 +151,13 @@ impl<'a> Render for TrackOverdubColumn<'a> { } } -struct TrackEraseColumn<'a>(&'a [Sequencer]); +struct TrackEraseColumn<'a>(&'a [Sequencer]); -impl<'a> Layout for TrackEraseColumn<'a> { +impl<'a> Widget for TrackEraseColumn<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for TrackEraseColumn<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { todo!(); //let Self(tracks) = self; @@ -192,15 +182,13 @@ impl<'a> Render for TrackEraseColumn<'a> { } } -struct TrackGainColumn<'a>(&'a [Sequencer]); +struct TrackGainColumn<'a>(&'a [Sequencer]); -impl<'a> Layout for TrackGainColumn<'a> { +impl<'a> Widget for TrackGainColumn<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for TrackGainColumn<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { todo!(); //let Self(tracks) = self; @@ -225,15 +213,13 @@ impl<'a> Render for TrackGainColumn<'a> { } } -struct TrackScenesColumn<'a>(&'a [Sequencer], &'a [Scene], ArrangerFocus); +struct TrackScenesColumn<'a>(&'a [Sequencer], &'a [Scene], ArrangerFocus); -impl<'a> Layout for TrackScenesColumn<'a> { +impl<'a> Widget for TrackScenesColumn<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for TrackScenesColumn<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { let Self(tracks, scenes, selected) = self; let area = to.area(); diff --git a/crates/tek_sequencer/src/arranger_view_v.rs b/crates/tek_sequencer/src/arranger_view_v.rs index 2a969b99..7921f0d4 100644 --- a/crates/tek_sequencer/src/arranger_view_v.rs +++ b/crates/tek_sequencer/src/arranger_view_v.rs @@ -51,13 +51,11 @@ pub fn draw <'a, 'b> ( struct ColumnSeparators<'a>(u16, &'a [(usize, usize)]); -impl<'a> Layout for ColumnSeparators<'a> { +impl<'a> Widget for ColumnSeparators<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for ColumnSeparators<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { let area = to.area(); let Self(offset, cols) = self; @@ -74,13 +72,11 @@ impl<'a> Render for ColumnSeparators<'a> { struct RowSeparators<'a>(&'a [(usize, usize)]); -impl<'a> Layout for RowSeparators<'a> { +impl<'a> Widget for RowSeparators<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for RowSeparators<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { let area = to.area(); let Self(rows) = self; @@ -103,13 +99,11 @@ struct CursorFocus<'a>( ArrangerFocus, u16, &'a [(usize, usize)], &'a [(usize, usize)] ); -impl<'a> Layout for CursorFocus<'a> { +impl<'a> Widget for CursorFocus<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for CursorFocus<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { let area = to.area(); let Self(selected, offset, cols, rows) = *self; @@ -173,15 +167,13 @@ impl<'a> Render for CursorFocus<'a> { } } -struct TracksHeader<'a>(u16, &'a[(usize, usize)], &'a [Sequencer]); +struct TracksHeader<'a>(u16, &'a[(usize, usize)], &'a [Sequencer]); -impl<'a> Layout for TracksHeader<'a> { +impl<'a> Widget for TracksHeader<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for TracksHeader<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { let area = to.area(); let Self(offset, track_cols, tracks) = *self; @@ -199,15 +191,13 @@ impl<'a> Render for TracksHeader<'a> { } } -struct SceneRows<'a>(u16, &'a[(usize, usize)], &'a[(usize, usize)], &'a[Sequencer], &'a[Scene]); +struct SceneRows<'a>(u16, &'a[(usize, usize)], &'a[(usize, usize)], &'a[Sequencer], &'a[Scene]); -impl<'a> Layout for SceneRows<'a> { +impl<'a> Widget for SceneRows<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for SceneRows<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { let area = to.area(); let Self(offset, track_cols, scene_rows, tracks, scenes) = *self; @@ -234,15 +224,13 @@ impl<'a> Render for SceneRows<'a> { } } -struct SceneRow<'a>(&'a[Sequencer], &'a Scene, &'a[(usize, usize)], u16); +struct SceneRow<'a>(&'a[Sequencer], &'a Scene, &'a[(usize, usize)], u16); -impl<'a> Layout for SceneRow<'a> { +impl<'a> Widget for SceneRow<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for SceneRow<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { let area = to.area(); let Self(tracks, scene, track_cols, offset) = self; @@ -266,15 +254,13 @@ impl<'a> Render for SceneRow<'a> { } } -struct SceneClip<'a>(&'a Sequencer, usize); +struct SceneClip<'a>(&'a Sequencer, usize); -impl<'a> Layout for SceneClip<'a> { +impl<'a> Widget for SceneClip<'a> { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} - -impl<'a> Render for SceneClip<'a> { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { let area = to.area(); let Self(track, clip) = self; diff --git a/crates/tek_sequencer/src/scene.rs b/crates/tek_sequencer/src/scene.rs index e8c6b76e..e762a77a 100644 --- a/crates/tek_sequencer/src/scene.rs +++ b/crates/tek_sequencer/src/scene.rs @@ -37,7 +37,7 @@ impl Scene { Self { name, clips, } } /// Returns the pulse length of the longest phrase in the scene - pub fn pulses (&self, tracks: &[Sequencer]) -> usize { + pub fn pulses (&self, tracks: &[Sequencer]) -> usize { self.clips.iter().enumerate() .filter_map(|(i, c)|c .map(|c|tracks @@ -50,7 +50,7 @@ impl Scene { .fold(0, |a, p|a.max(p.read().unwrap().length)) } /// Returns true if all phrases in the scene are currently playing - pub fn is_playing (&self, tracks: &[Sequencer]) -> bool { + pub fn is_playing (&self, tracks: &[Sequencer]) -> bool { self.clips.iter().enumerate() .all(|(track_index, phrase_index)|match phrase_index { Some(i) => tracks @@ -68,7 +68,10 @@ pub fn scene_name_max_len (scenes: &[Scene]) -> usize { .fold(0, usize::max) } -pub fn scene_ppqs (tracks: &[Sequencer], scenes: &[Scene]) -> Vec<(usize, usize)> { +pub fn scene_ppqs ( + tracks: &[Sequencer], + scenes: &[Scene] +) -> Vec<(usize, usize)> { let mut total = 0; let mut scenes: Vec<(usize, usize)> = scenes.iter().map(|scene|{ let pulses = scene.pulses(tracks).max(96); diff --git a/crates/tek_sequencer/src/sequencer.rs b/crates/tek_sequencer/src/sequencer.rs index bbb31ec2..a55f66dc 100644 --- a/crates/tek_sequencer/src/sequencer.rs +++ b/crates/tek_sequencer/src/sequencer.rs @@ -2,14 +2,14 @@ use crate::*; use tek_core::Direction; /// Phrase editor. -pub struct Sequencer { +pub struct Sequencer { pub name: Arc>, pub mode: bool, pub focused: bool, pub entered: bool, pub phrase: Option>>, - pub transport: Option>>, + pub transport: Option>>>, pub buffer: BigBuffer, pub keys: Buffer, /// Highlight input keys @@ -43,7 +43,7 @@ pub struct Sequencer { pub notes_out: [bool;128], } -impl Sequencer { +impl Sequencer { pub fn new (name: &str) -> Self { Self { name: Arc::new(RwLock::new(name.into())), diff --git a/crates/tek_sequencer/src/sequencer_cli.rs b/crates/tek_sequencer/src/sequencer_cli.rs index 71bf2283..719b8102 100644 --- a/crates/tek_sequencer/src/sequencer_cli.rs +++ b/crates/tek_sequencer/src/sequencer_cli.rs @@ -14,7 +14,7 @@ pub struct SequencerCli { #[arg(short, long)] transport: Option } -impl Sequencer { +impl Sequencer { pub fn from_args () -> Self { let args = SequencerCli::parse(); let mut seq = Self::new(""); diff --git a/crates/tek_sequencer/src/sequencer_handle.rs b/crates/tek_sequencer/src/sequencer_handle.rs index ed6ae8a4..acd8328a 100644 --- a/crates/tek_sequencer/src/sequencer_handle.rs +++ b/crates/tek_sequencer/src/sequencer_handle.rs @@ -1,6 +1,6 @@ use crate::*; -impl Handle for Sequencer { +impl Handle for Sequencer { fn handle (&mut self, from: &Tui) -> Perhaps { match from.event() { // NONE, "seq_cursor_up", "move cursor up", |sequencer: &mut Sequencer| { diff --git a/crates/tek_sequencer/src/sequencer_view.rs b/crates/tek_sequencer/src/sequencer_view.rs index 8fa93404..f1b0244a 100644 --- a/crates/tek_sequencer/src/sequencer_view.rs +++ b/crates/tek_sequencer/src/sequencer_view.rs @@ -1,11 +1,10 @@ use crate::*; -impl Layout for Sequencer { +impl Widget for Sequencer { + type Engine = Tui; fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> { todo!() } -} -impl<'a> Render for Sequencer { fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> { self.horizontal_draw(to)?; if self.focused && self.entered { @@ -15,7 +14,7 @@ impl<'a> Render for Sequencer { } } -impl Sequencer { +impl Sequencer { /// Select which pattern to display. This pre-renders it to the buffer at full resolution. pub fn show (&mut self, phrase: Option<&Arc>>) -> Usually<()> { self.phrase = phrase.map(Clone::clone); diff --git a/crates/tek_sequencer/src/sequencer_view_h.rs b/crates/tek_sequencer/src/sequencer_view_h.rs index 2126335c..d346eb45 100644 --- a/crates/tek_sequencer/src/sequencer_view_h.rs +++ b/crates/tek_sequencer/src/sequencer_view_h.rs @@ -1,6 +1,6 @@ use crate::*; -impl Sequencer { +impl Sequencer { const H_KEYS_OFFSET: usize = 5; @@ -43,15 +43,13 @@ const STYLE_VALUE: Option