diff --git a/src/model.rs b/src/model.rs index ee01387a..b8cff6a0 100644 --- a/src/model.rs +++ b/src/model.rs @@ -116,11 +116,10 @@ impl App { }) } } - process!(App |self, _client, scope| { let ( reset, current_frames, current_usecs, next_usecs, period_usecs - ) = self.process_update_time(&scope); + ) = self.update_time(&scope); for track in self.tracks.iter_mut() { track.process( self.midi_in.as_ref().map(|p|p.iter(&scope)), @@ -138,6 +137,12 @@ process!(App |self, _client, scope| { Control::Continue }); impl App { + pub fn client (&self) -> &Client { + self.jack.as_ref().unwrap().client() + } + pub fn audio_out (&self, index: usize) -> Option>> { + self.audio_outs.get(index).map(|x|x.clone()) + } pub fn with_midi_ins (mut self, names: &[&str]) -> Usually { self.midi_ins = names.iter().map(|x|x.to_string()).collect(); Ok(self) @@ -156,35 +161,18 @@ impl App { .collect(); Ok(self) } - pub fn connect_to_midi_ins (&mut self, ports: &[&str]) -> Usually<&mut Self> { - let client = self.client(); - let midi_in = client.register_port("midi-in", MidiIn)?; - ports - .iter() - .map(|name|client - .ports(Some(name), None, PortFlags::empty()) - .iter() - .map(|name|{ - if let Some(port) = client.port_by_name(name) { - client.connect_ports(&port, &midi_in)?; - } - Ok(()) - }) - .collect::>()) - .collect::>()?; - Ok(self) - } pub fn activate (mut self, init: Option>)->Usually<()>>) -> Usually>> { let jack = self.jack.take().expect("no jack client"); let app = Arc::new(RwLock::new(self)); - app.write().unwrap().jack = Some(jack.activate(&app.clone(), Self::process)?); - if let Some(init) = init { init(&app)?; } + app.write().unwrap().jack = Some(jack.activate(&app.clone(), |state, client, scope|{ + state.write().unwrap().process(client, scope) + })?); + if let Some(init) = init { + init(&app)?; + } Ok(app) } - pub fn process (state: &Arc>, client: &Client, scope: &ProcessScope) -> Control { - state.write().unwrap().process(client, scope) - } - pub fn process_update_time (&mut self, scope: &ProcessScope) -> (bool, usize, usize, usize, f64) { + pub fn update_time (&mut self, scope: &ProcessScope) -> (bool, usize, usize, usize, f64) { let CycleTimes { current_frames, current_usecs, @@ -215,12 +203,6 @@ impl App { reset, current_frames as usize, current_usecs as usize, next_usecs as usize, period_usecs as f64 ) } - pub fn audio_out (&self, index: usize) -> Option>> { - self.audio_outs.get(index).map(|x|x.clone()) - } - pub fn client (&self) -> &Client { - self.jack.as_ref().unwrap().client() - } pub fn toggle_play (&mut self) -> Usually<()> { self.playing = match self.playing.expect("1st frame has not been processed yet") { TransportState::Stopped => { @@ -235,178 +217,11 @@ impl App { }; Ok(()) } - pub fn new_track_name (&self) -> String { - format!("Track {}", self.tracks.len() + 1) - } - pub fn add_track ( - &mut self, - name: Option<&str>, - ) -> Usually<&mut Track> { - let name = name.ok_or_else(||self.new_track_name())?; - self.tracks.push(Track::new(&name, None, None)?); - self.track_cursor = self.tracks.len(); - Ok(&mut self.tracks[self.track_cursor - 1]) - } - pub fn add_track_with_cb ( - &mut self, - name: Option<&str>, - init: impl FnOnce(&Client, &mut Track)->Usually<()>, - ) -> Usually<&mut Track> { - let name = name.ok_or_else(||self.new_track_name())?; - let mut track = Track::new(&name, None, None)?; - init(self.client(), &mut track)?; - self.tracks.push(track); - self.track_cursor = self.tracks.len(); - Ok(&mut self.tracks[self.track_cursor - 1]) - } - pub fn track (&self) -> Option<(usize, &Track)> { - match self.track_cursor { 0 => None, _ => { - let id = self.track_cursor as usize - 1; - self.tracks.get(id).map(|t|(id, t)) - } } - } - pub fn track_mut (&mut self) -> Option<(usize, &mut Track)> { - match self.track_cursor { 0 => None, _ => { - let id = self.track_cursor as usize - 1; - self.tracks.get_mut(id).map(|t|(id, t)) - } } - } - pub fn new_scene_name (&self) -> String { - format!("Scene {}", self.scenes.len() + 1) - } - pub fn add_scene (&mut self, name: Option<&str>) -> Usually<&mut Scene> { - let name = name.ok_or_else(||self.new_scene_name())?; - self.scenes.push(Scene::new(&name, vec![])); - self.scene_cursor = self.scenes.len(); - Ok(&mut self.scenes[self.scene_cursor - 1]) - } - pub fn add_scene_with_clips ( - &mut self, - name: Option<&str>, - clips: &[Option] - ) -> Usually<&mut Scene> { - let name = name.ok_or_else(||self.new_scene_name())?; - self.scenes.push(Scene::new(&name, Vec::from(clips))); - self.scene_cursor = self.scenes.len(); - Ok(&mut self.scenes[self.scene_cursor - 1]) - } - pub fn scene (&self) -> Option<(usize, &Scene)> { - match self.scene_cursor { 0 => None, _ => { - let id = self.scene_cursor as usize - 1; - self.scenes.get(id).map(|t|(id, t)) - } } - } - pub fn scene_mut (&mut self) -> Option<(usize, &mut Scene)> { - match self.scene_cursor { 0 => None, _ => { - let id = self.scene_cursor as usize - 1; - self.scenes.get_mut(id).map(|t|(id, t)) - } } - } - pub fn phrase (&self) -> Option<&Phrase> { - let (track_id, track) = self.track()?; - let (_, scene) = self.scene()?; - track.phrases.get((*scene.clips.get(track_id)?)?) - } - pub fn phrase_mut (&mut self) -> Option<&mut Phrase> { - let (track_id, _) = self.track()?; - let (_, scene) = self.scene()?; - let clip = (*scene.clips.get(track_id)?)?; - self.track_mut()?.1.phrases.get_mut(clip) - } - pub fn phrase_id (&self) -> Option { - let (track_id, _) = self.track()?; - let (_, scene) = self.scene()?; - *scene.clips.get(track_id)? - } - - pub fn selection <'a> (&'a self) -> Selection<'a> { - let track_id = if self.track_cursor == 0 { None } else { Some(self.track_cursor - 1) }; - let track = (&track_id).map(|id|self.tracks.get(id)).flatten(); - let scene_id = if self.scene_cursor == 0 { None } else { Some(self.scene_cursor - 1) }; - let scene = (&scene_id).map(|id|self.scenes.get(id)).flatten(); - let phrase_id = if let (Some(scene), Some(id)) = (scene, track_id) { - if let Some(Some(id)) = scene.clips.get(id) { - Some(*id) - } else { - None - } - } else { - None - }; - let phrase = if let (Some(id), Some(track)) = (phrase_id, track) { - track.phrases.get(id) - } else { - None - }; - Selection { - track_id, - track, - scene_id, - scene, - phrase_id, - phrase - } - } - - //pub fn selection_mut <'a> (&'a mut self) -> SelectionMut<'a> { - //let track_id = if self.track_cursor == 0 { None } else { Some(self.track_cursor - 1) }; - //let track = (&track_id).map(|id|self.tracks.get_mut(id)).flatten(); - //let scene_id = if self.scene_cursor == 0 { None } else { Some(self.scene_cursor - 1) }; - //let scene = (&scene_id).map(|id|self.scenes.get_mut(id)).flatten(); - //let phrase_id = if let (Some(scene), Some(id)) = (scene, track_id) { - //if let Some(Some(id)) = scene.clips.get_mut(id) { - //Some(*id) - //} else { - //None - //} - //} else { - //None - //}; - //let phrase = if let (Some(id), Some(track)) = (phrase_id, track) { - //track.phrases.get_mut(id) - //} else { - //None - //}; - //SelectionMut { - //track_id, - //track, - //scene_id, - //scene, - //phrase_id, - //phrase - //} - //} -} - -struct Selection<'a> { - pub track_id: Option, - pub track: Option<&'a Track>, - pub scene_id: Option, - pub scene: Option<&'a Scene>, - pub phrase_id: Option, - pub phrase: Option<&'a Phrase>, -} - -struct SelectionMut<'a> { - pub track_id: Option, - pub track: Option<&'a mut Track>, - pub scene_id: Option, - pub scene: Option<&'a mut Scene>, - pub phrase_id: Option, - pub phrase: Option<&'a mut Phrase>, } #[derive(PartialEq, Clone, Copy)] -pub enum AppSection { - Arranger, - Sequencer, - Chain, -} -impl Default for AppSection { - fn default () -> Self { - Self::Arranger - } -} +pub enum AppSection { Arranger, Sequencer, Chain, } +impl Default for AppSection { fn default () -> Self { Self::Arranger } } impl AppSection { pub fn prev (&mut self) { *self = match self { diff --git a/src/model/phrase.rs b/src/model/phrase.rs index 294b8385..b75679c5 100644 --- a/src/model/phrase.rs +++ b/src/model/phrase.rs @@ -1,4 +1,4 @@ -use crate::core::*; +use crate::{core::*, model::App}; /// Define a MIDI phrase. #[macro_export] macro_rules! phrase { @@ -89,3 +89,22 @@ impl Phrase { } } } + +impl App { + pub fn phrase (&self) -> Option<&Phrase> { + let (track_id, track) = self.track()?; + let (_, scene) = self.scene()?; + track.phrases.get((*scene.clips.get(track_id)?)?) + } + pub fn phrase_mut (&mut self) -> Option<&mut Phrase> { + let (track_id, _) = self.track()?; + let (_, scene) = self.scene()?; + let clip = (*scene.clips.get(track_id)?)?; + self.track_mut()?.1.phrases.get_mut(clip) + } + pub fn phrase_id (&self) -> Option { + let (track_id, _) = self.track()?; + let (_, scene) = self.scene()?; + *scene.clips.get(track_id)? + } +} diff --git a/src/model/scene.rs b/src/model/scene.rs index bbb65582..9f194aca 100644 --- a/src/model/scene.rs +++ b/src/model/scene.rs @@ -1,3 +1,5 @@ +use crate::{core::*, model::App}; + pub struct Scene { pub name: String, pub clips: Vec>, @@ -11,3 +13,37 @@ impl Scene { } } } + +impl App { + pub fn new_scene_name (&self) -> String { + format!("Scene {}", self.scenes.len() + 1) + } + pub fn add_scene (&mut self, name: Option<&str>) -> Usually<&mut Scene> { + let name = name.ok_or_else(||self.new_scene_name())?; + self.scenes.push(Scene::new(&name, vec![])); + self.scene_cursor = self.scenes.len(); + Ok(&mut self.scenes[self.scene_cursor - 1]) + } + pub fn add_scene_with_clips ( + &mut self, + name: Option<&str>, + clips: &[Option] + ) -> Usually<&mut Scene> { + let name = name.ok_or_else(||self.new_scene_name())?; + self.scenes.push(Scene::new(&name, Vec::from(clips))); + self.scene_cursor = self.scenes.len(); + Ok(&mut self.scenes[self.scene_cursor - 1]) + } + pub fn scene (&self) -> Option<(usize, &Scene)> { + match self.scene_cursor { 0 => None, _ => { + let id = self.scene_cursor as usize - 1; + self.scenes.get(id).map(|t|(id, t)) + } } + } + pub fn scene_mut (&mut self) -> Option<(usize, &mut Scene)> { + match self.scene_cursor { 0 => None, _ => { + let id = self.scene_cursor as usize - 1; + self.scenes.get_mut(id).map(|t|(id, t)) + } } + } +} diff --git a/src/model/track.rs b/src/model/track.rs index 66649834..9a56a8af 100644 --- a/src/model/track.rs +++ b/src/model/track.rs @@ -239,3 +239,42 @@ impl Track { } } } + +impl App { + pub fn new_track_name (&self) -> String { + format!("Track {}", self.tracks.len() + 1) + } + pub fn add_track ( + &mut self, + name: Option<&str>, + ) -> Usually<&mut Track> { + let name = name.ok_or_else(||self.new_track_name())?; + self.tracks.push(Track::new(&name, None, None)?); + self.track_cursor = self.tracks.len(); + Ok(&mut self.tracks[self.track_cursor - 1]) + } + pub fn add_track_with_cb ( + &mut self, + name: Option<&str>, + init: impl FnOnce(&Client, &mut Track)->Usually<()>, + ) -> Usually<&mut Track> { + let name = name.ok_or_else(||self.new_track_name())?; + let mut track = Track::new(&name, None, None)?; + init(self.client(), &mut track)?; + self.tracks.push(track); + self.track_cursor = self.tracks.len(); + Ok(&mut self.tracks[self.track_cursor - 1]) + } + pub fn track (&self) -> Option<(usize, &Track)> { + match self.track_cursor { 0 => None, _ => { + let id = self.track_cursor as usize - 1; + self.tracks.get(id).map(|t|(id, t)) + } } + } + pub fn track_mut (&mut self) -> Option<(usize, &mut Track)> { + match self.track_cursor { 0 => None, _ => { + let id = self.track_cursor as usize - 1; + self.tracks.get_mut(id).map(|t|(id, t)) + } } + } +}