use crate::*; pub trait HasPlayPhrase: HasClock { fn reset (&self) -> bool; fn reset_mut (&mut self) -> &mut bool; fn play_phrase (&self) -> &Option<(Moment, Option>>)>; fn play_phrase_mut (&mut self) -> &mut Option<(Moment, Option>>)>; fn next_phrase (&self) -> &Option<(Moment, Option>>)>; fn next_phrase_mut (&mut self) -> &mut Option<(Moment, Option>>)>; fn pulses_since_start (&self) -> Option { if let Some((started, Some(_))) = self.play_phrase().as_ref() { let elapsed = self.clock().playhead.pulse.get() - started.pulse.get(); Some(elapsed) } else { None } } fn pulses_since_start_looped (&self) -> Option { if let Some((started, Some(phrase))) = self.play_phrase().as_ref() { let elapsed = self.clock().playhead.pulse.get() - started.pulse.get(); let length = phrase.read().unwrap().length.max(1); // prevent div0 on empty phrase let elapsed = (elapsed as usize % length) as f64; Some(elapsed) } else { None } } fn enqueue_next (&mut self, phrase: Option<&Arc>>) { let start = self.clock().next_launch_pulse() as f64; let instant = Moment::from_pulse(self.clock().timebase(), start); *self.next_phrase_mut() = Some((instant, phrase.cloned())); *self.reset_mut() = true; } }