use crate::*; macro_rules! impl_jack_api { ($Struct:ident $(:: $field:ident)*) => { impl JackApi for $Struct { fn jack (&self) -> &Arc> { &self$(.$field)* } } } } macro_rules! impl_clock_api { ($Struct:ident $(:: $field:ident)*) => { impl ClockApi for $Struct { fn quant (&self) -> &Arc { &self$(.$field)*.quant } fn sync (&self) -> &Arc { &self$(.$field)*.sync } fn current (&self) -> &Arc { &self$(.$field)*.current } fn transport_handle (&self) -> &Arc { &self$(.$field)*.transport } fn transport_state (&self) -> &Arc>> { &self$(.$field)*.playing } fn transport_offset (&self) -> &Arc>> { &self$(.$field)*.started } } } } macro_rules! impl_has_phrases { ($Struct:ident $(:: $field:ident)*) => { impl HasPhrases for $Struct { fn phrases (&self) -> &Vec>> { &self$(.$field)*.phrases } fn phrases_mut (&mut self) -> &mut Vec>> { &mut self$(.$field)*.phrases } } } } macro_rules! impl_midi_player { ($Struct:ident $(:: $field:ident)*) => { impl HasPhrase for $Struct { fn reset (&self) -> bool { self$(.$field)*.reset } fn reset_mut (&mut self) -> &mut bool { &mut self$(.$field)*.reset } fn play_phrase (&self) -> &Option<(Instant, Option>>)> { &self$(.$field)*.play_phrase } fn play_phrase_mut (&mut self) -> &mut Option<(Instant, Option>>)> { &mut self$(.$field)*.play_phrase } fn next_phrase (&self) -> &Option<(Instant, Option>>)> { &self$(.$field)*.next_phrase } fn next_phrase_mut (&mut self) -> &mut Option<(Instant, Option>>)> { &mut self$(.$field)*.next_phrase } } impl MidiInputApi for $Struct { fn midi_ins (&self) -> &Vec> { &self$(.$field)*.midi_ins } fn midi_ins_mut (&mut self) -> &mut Vec> { &mut self$(.$field)*.midi_ins } fn recording (&self) -> bool { self$(.$field)*.recording } fn recording_mut (&mut self) -> &mut bool { &mut self$(.$field)*.recording } fn monitoring (&self) -> bool { self$(.$field)*.monitoring } fn monitoring_mut (&mut self) -> &mut bool { &mut self$(.$field)*.monitoring } fn overdub (&self) -> bool { self$(.$field)*.overdub } fn overdub_mut (&mut self) -> &mut bool { &mut self$(.$field)*.overdub } fn notes_in (&self) -> &Arc> { &self$(.$field)*.notes_in } } impl MidiOutputApi for $Struct { fn midi_outs (&self) -> &Vec> { &self$(.$field)*.midi_outs } fn midi_outs_mut (&mut self) -> &mut Vec> { &mut self$(.$field)*.midi_outs } fn midi_note (&mut self) -> &mut Vec { &mut self$(.$field)*.note_buf } fn notes_out (&self) -> &Arc> { &self$(.$field)*.notes_in } } impl MidiPlayerApi for $Struct {} } } macro_rules! impl_phrases_control { ($Struct:ident $(:: $field:ident)*) => { impl PhrasesControl for $Struct { fn phrase_index (&self) -> usize { self.phrases.phrase.load(Ordering::Relaxed) } fn set_phrase_index (&self, value: usize) { self.phrases.phrase.store(value, Ordering::Relaxed); } fn phrases_mode (&self) -> &Option { &self.phrases.mode } fn phrases_mode_mut (&mut self) -> &mut Option { &mut self.phrases.mode } } } } macro_rules! impl_phrase_editor_control { ( $Struct:ident $(:: $field:ident)* [$Focus:expr] [$self1:ident: $phrase_to_edit:expr] [$self2:ident, $phrase:ident: $edit_phrase:expr] ) => { impl PhraseEditorControl for $Struct { fn phrase_to_edit (&$self1) -> Option>> { $phrase_to_edit } fn edit_phrase (&mut $self2, $phrase: Option>>) { $edit_phrase //self.editor.show(self.selected_phrase().as_ref()); //state.editor.phrase = phrase.clone(); //state.focus(ArrangerFocus::PhraseEditor); //state.focus_enter(); //todo!("edit_phrase") } fn phrase_editing (&self) -> &Option>> { todo!("phrase_editing") } fn phrase_editor_entered (&self) -> bool { self.entered && self.focused() == $Focus } fn time_axis (&self) -> &RwLock> { &self.editor.time_axis } fn note_axis (&self) -> &RwLock> { &self.editor.note_axis } fn note_len (&self) -> usize { self.editor.note_len } fn note_len_mut (&mut self) -> &mut usize { &mut self.editor.note_len } fn put_note (&mut self) { todo!("put_note") } } } } impl_jack_api!(TransportTui::jack); impl_jack_api!(SequencerTui::jack); impl_jack_api!(ArrangerTui::jack); impl_clock_api!(TransportTui::clock); impl_clock_api!(SequencerTui::clock); impl_clock_api!(ArrangerTui::clock); impl_clock_api!(PhrasePlayerModel::clock); impl_clock_api!(ArrangerTrack::player::clock); impl_has_phrases!(PhrasesModel); impl_has_phrases!(SequencerTui::phrases); impl_has_phrases!(ArrangerTui::phrases); impl_midi_player!(SequencerTui::player); impl_midi_player!(ArrangerTrack::player); impl_midi_player!(PhrasePlayerModel); impl_phrases_control!(SequencerTui); impl_phrases_control!(ArrangerTui); impl_phrase_editor_control!(SequencerTui [AppFocus::Content(SequencerFocus::PhraseEditor)] [self: Some(self.phrases.phrases[self.phrases.phrase.load(Ordering::Relaxed)].clone())] [self, phrase: self.editor.show(phrase)] ); impl_phrase_editor_control!(ArrangerTui [AppFocus::Content(ArrangerFocus::PhraseEditor)] [self: todo!()] [self, phrase: todo!()] );