remove PhrasesControl trait

This commit is contained in:
🪞👃🪞 2024-11-26 17:46:14 +01:00
parent d1fdc7f8b6
commit 4fdc3911e4
10 changed files with 64 additions and 68 deletions

View file

@ -54,7 +54,11 @@ pub trait ClockApi: Send + Sync {
fn next_launch_pulse (&self) -> usize {
let sync = self.sync().get() as usize;
let pulse = self.current().pulse.get() as usize;
if pulse % sync == 0 { pulse } else { (pulse / sync + 1) * sync }
if pulse % sync == 0 {
pulse
} else {
(pulse / sync + 1) * sync
}
}
fn play_from (&mut self, start: Option<u32>) -> Usually<()> {

View file

@ -54,6 +54,15 @@ impl TryFrom<&Arc<RwLock<JackClient>>> for ArrangerTui {
}
}
impl HasPhrases for ArrangerTui {
fn phrases (&self) -> &Vec<Arc<RwLock<Phrase>>> {
&self.phrases.phrases
}
fn phrases_mut (&mut self) -> &mut Vec<Arc<RwLock<Phrase>>> {
&mut self.phrases.phrases
}
}
/// Sections in the arranger app that may be focused
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum ArrangerFocus {

View file

@ -39,6 +39,15 @@ impl TryFrom<&Arc<RwLock<JackClient>>> for SequencerTui {
}
}
impl HasPhrases for SequencerTui {
fn phrases (&self) -> &Vec<Arc<RwLock<Phrase>>> {
&self.phrases.phrases
}
fn phrases_mut (&mut self) -> &mut Vec<Arc<RwLock<Phrase>>> {
&mut self.phrases.phrases
}
}
/// Sections in the sequencer app that may be focused
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub enum SequencerFocus {

View file

@ -31,7 +31,7 @@ impl Command<ArrangerTui> for ArrangerCommand {
Scene(cmd) => cmd.execute(state)?.map(Scene),
Track(cmd) => cmd.execute(state)?.map(Track),
Clip(cmd) => cmd.execute(state)?.map(Clip),
Phrases(cmd) => cmd.execute(state)?.map(Phrases),
Phrases(cmd) => cmd.execute(&mut state.phrases)?.map(Phrases),
Editor(cmd) => cmd.execute(state)?.map(Editor),
Clock(cmd) => cmd.execute(state)?.map(Clock),
Zoom(zoom) => { todo!(); },
@ -152,7 +152,7 @@ fn to_arranger_command (state: &ArrangerTui, input: &TuiInput) -> Option<Arrange
Cmd::Editor(PhraseCommand::input_to_command(state, input)?)
},
ArrangerFocus::Phrases => {
Cmd::Phrases(PhrasesCommand::input_to_command(state, input)?)
Cmd::Phrases(PhrasesCommand::input_to_command(&state.phrases, input)?)
},
ArrangerFocus::Arranger => {
use ArrangerSelection::*;

View file

@ -11,8 +11,8 @@ pub enum FileBrowserCommand {
Filter(String),
}
impl<T: PhrasesControl> Command<T> for FileBrowserCommand {
fn execute (self, state: &mut T) -> Perhaps<Self> {
impl Command<PhraseListModel> for FileBrowserCommand {
fn execute (self, state: &mut PhraseListModel) -> Perhaps<Self> {
use FileBrowserCommand::*;
use PhrasesMode::{Import, Export};
let mode = state.phrases_mode_mut();
@ -58,8 +58,8 @@ impl<T: PhrasesControl> Command<T> for FileBrowserCommand {
}
}
impl<T: PhrasesControl> InputToCommand<Tui, T> for FileBrowserCommand {
fn input_to_command (state: &T, from: &TuiInput) -> Option<Self> {
impl InputToCommand<Tui, PhraseListModel> for FileBrowserCommand {
fn input_to_command (state: &PhraseListModel, from: &TuiInput) -> Option<Self> {
use KeyCode::{Up, Down, Right, Left, Enter, Esc, Char, Backspace};
use FileBrowserCommand::*;
if let Some(PhrasesMode::Import(index, browser)) = state.phrases_mode() {
@ -96,8 +96,8 @@ impl<T: PhrasesControl> InputToCommand<Tui, T> for FileBrowserCommand {
}
}
impl<T: PhrasesControl> InputToCommand<Tui, T> for PhraseLengthCommand {
fn input_to_command (state: &T, from: &TuiInput) -> Option<Self> {
impl InputToCommand<Tui, PhraseListModel> for PhraseLengthCommand {
fn input_to_command (state: &PhraseListModel, from: &TuiInput) -> Option<Self> {
use KeyCode::{Up, Down, Right, Left, Enter, Esc};
if let Some(PhrasesMode::Length(_, length, _)) = state.phrases_mode() {
Some(match from.event() {

View file

@ -11,8 +11,8 @@ pub enum PhraseLengthCommand {
Dec,
}
impl<T: PhrasesControl> Command<T> for PhraseLengthCommand {
fn execute (self, state: &mut T) -> Perhaps<Self> {
impl Command<PhraseListModel> for PhraseLengthCommand {
fn execute (self, state: &mut PhraseListModel) -> Perhaps<Self> {
use PhraseLengthFocus::*;
use PhraseLengthCommand::*;
match state.phrases_mode_mut().clone() {

View file

@ -10,8 +10,8 @@ pub enum PhrasesCommand {
Export(FileBrowserCommand),
}
impl<T: PhrasesControl> Command<T> for PhrasesCommand {
fn execute (self, state: &mut T) -> Perhaps<Self> {
impl Command<PhraseListModel> for PhrasesCommand {
fn execute (self, state: &mut PhraseListModel) -> Perhaps<Self> {
use PhrasesCommand::*;
Ok(match self {
Phrase(command) => command.execute(state)?.map(Phrase),
@ -61,58 +61,17 @@ impl<T: PhrasesControl> Command<T> for PhrasesCommand {
}
}
pub trait PhrasesControl: HasPhrases {
fn phrase_index (&self) -> usize;
fn set_phrase_index (&self, index: usize);
fn phrases_mode (&self) -> &Option<PhrasesMode>;
fn phrases_mode_mut (&mut self) -> &mut Option<PhrasesMode>;
fn index_of (&self, phrase: &Phrase) -> Option<usize> {
for i in 0..self.phrases().len() {
if *self.phrases()[i].read().unwrap() == *phrase { return Some(i) }
}
return None
}
}
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<PhrasesMode> {
&self.phrases.mode
}
fn phrases_mode_mut (&mut self) -> &mut Option<PhrasesMode> {
&mut self.phrases.mode
}
}
}
}
impl_phrases_control!(SequencerTui);
impl_phrases_control!(ArrangerTui);
macro_rules! impl_has_phrases {
($Struct:ident $(:: $field:ident)*) => {
impl HasPhrases for $Struct {
impl HasPhrases for PhraseListModel {
fn phrases (&self) -> &Vec<Arc<RwLock<Phrase>>> {
&self$(.$field)*.phrases
&self.phrases
}
fn phrases_mut (&mut self) -> &mut Vec<Arc<RwLock<Phrase>>> {
&mut self$(.$field)*.phrases
}
}
&mut self.phrases
}
}
impl_has_phrases!(PhraseListModel);
impl_has_phrases!(SequencerTui::phrases);
impl_has_phrases!(ArrangerTui::phrases);
impl<T: PhrasesControl> InputToCommand<Tui, T> for PhrasesCommand {
fn input_to_command (state: &T, input: &TuiInput) -> Option<Self> {
impl InputToCommand<Tui, PhraseListModel> for PhrasesCommand {
fn input_to_command (state: &PhraseListModel, input: &TuiInput) -> Option<Self> {
use PhraseRenameCommand as Rename;
use PhraseLengthCommand as Length;
use FileBrowserCommand as Browse;
@ -126,7 +85,7 @@ impl<T: PhrasesControl> InputToCommand<Tui, T> for PhrasesCommand {
}
}
fn to_phrases_command <T: PhrasesControl> (state: &T, input: &TuiInput) -> Option<PhrasesCommand> {
fn to_phrases_command (state: &PhraseListModel, input: &TuiInput) -> Option<PhrasesCommand> {
use KeyCode::{Up, Down, Delete, Char};
use PhrasesCommand as Cmd;
use PhrasePoolCommand as Pool;

View file

@ -8,8 +8,8 @@ pub enum PhraseRenameCommand {
Set(String),
}
impl<T: PhrasesControl> Command<T> for PhraseRenameCommand {
fn execute (self, state: &mut T) -> Perhaps<Self> {
impl Command<PhraseListModel> for PhraseRenameCommand {
fn execute (self, state: &mut PhraseListModel) -> Perhaps<Self> {
use PhraseRenameCommand::*;
match state.phrases_mode_mut().clone() {
Some(PhrasesMode::Rename(phrase, ref mut old_name)) => match self {
@ -33,8 +33,8 @@ impl<T: PhrasesControl> Command<T> for PhraseRenameCommand {
}
}
impl<T: PhrasesControl> InputToCommand<Tui, T> for PhraseRenameCommand {
fn input_to_command (state: &T, from: &TuiInput) -> Option<Self> {
impl InputToCommand<Tui, PhraseListModel> for PhraseRenameCommand {
fn input_to_command (state: &PhraseListModel, from: &TuiInput) -> Option<Self> {
use KeyCode::{Char, Backspace, Enter, Esc};
if let Some(PhrasesMode::Rename(_, ref old_name)) = state.phrases_mode() {
Some(match from.event() {

View file

@ -23,7 +23,7 @@ impl Command<SequencerTui> for SequencerCommand {
use SequencerCommand::*;
Ok(match self {
Focus(cmd) => cmd.execute(state)?.map(Focus),
Phrases(cmd) => cmd.execute(state)?.map(Phrases),
Phrases(cmd) => cmd.execute(&mut state.phrases)?.map(Phrases),
Editor(cmd) => cmd.execute(state)?.map(Editor),
Clock(cmd) => cmd.execute(state)?.map(Clock),
Enqueue(phrase) => {
@ -85,7 +85,7 @@ pub fn to_sequencer_command (state: &SequencerTui, input: &TuiInput) -> Option<S
state.phrases.phrases[state.phrases.phrase.load(Ordering::Relaxed)].clone()
)),
_ => Phrases(
PhrasesCommand::input_to_command(state, input)?
PhrasesCommand::input_to_command(&state.phrases, input)?
),
}
_ => return None

View file

@ -23,6 +23,21 @@ impl Default for PhraseListModel {
}
}
impl PhraseListModel {
pub(crate) fn phrase_index (&self) -> usize {
self.phrase.load(Ordering::Relaxed)
}
pub(crate) fn set_phrase_index (&self, value: usize) {
self.phrase.store(value, Ordering::Relaxed);
}
pub(crate) fn phrases_mode (&self) -> &Option<PhrasesMode> {
&self.mode
}
pub(crate) fn phrases_mode_mut (&mut self) -> &mut Option<PhrasesMode> {
&mut self.mode
}
}
/// Modes for phrase pool
#[derive(Debug, Clone)]
pub enum PhrasesMode {