diff --git a/app/src/model.rs b/app/src/model.rs index 7b48039e..ac92c452 100644 --- a/app/src/model.rs +++ b/app/src/model.rs @@ -60,7 +60,7 @@ mod model_select; pub use self::model_select::*; // Input definitions when the mix is focused pub keys_mix: SourceIter<'static>, // Cache of formatted strings - pub fmtd: Arc>, + pub view_cache: Arc>, } has_size!(|self: Tek|&self.size); has_clock!(|self: Tek|self.clock); diff --git a/app/src/view/view_clock.rs b/app/src/view/view_clock.rs index 03a5e1c4..585c07fc 100644 --- a/app/src/view/view_clock.rs +++ b/app/src/view/view_clock.rs @@ -7,10 +7,10 @@ impl Tek { let chunk = clock.chunk.load(Relaxed) as f64; let lat = chunk / rate * 1000.; let delta = |start: &Moment|clock.global.usec.get() - start.usec.get(); - let mut fmtd = self.fmtd.write().unwrap(); - fmtd.buf.update(Some(chunk), rewrite!(buf, "{chunk}")); - fmtd.lat.update(Some(lat), rewrite!(buf, "{lat:.1}ms")); - fmtd.sr.update(Some((compact, rate)), |buf,_,_|if compact { + let mut view_cache = self.view_cache.write().unwrap(); + view_cache.buf.update(Some(chunk), rewrite!(buf, "{chunk}")); + view_cache.lat.update(Some(lat), rewrite!(buf, "{lat:.1}ms")); + view_cache.sr.update(Some((compact, rate)), |buf,_,_|if compact { buf.clear(); write!(buf, "{:.1}kHz", rate / 1000.) } else { buf.clear(); write!(buf, "{:.0}Hz", rate) @@ -19,41 +19,41 @@ impl Tek { let pulse = clock.timebase.usecs_to_pulse(now); let time = now/1000000.; let bpm = clock.timebase.bpm.get(); - fmtd.beat.update(Some(pulse), + view_cache.beat.update(Some(pulse), |buf, _, _|{buf.clear();clock.timebase.format_beats_1_to(buf, pulse)}); - fmtd.time.update(Some(time), rewrite!(buf, "{:.3}s", time)); - fmtd.bpm.update(Some(bpm), rewrite!(buf, "{:.3}", bpm)); + view_cache.time.update(Some(time), rewrite!(buf, "{:.3}s", time)); + view_cache.bpm.update(Some(bpm), rewrite!(buf, "{:.3}", bpm)); } else { - fmtd.beat.update(None, rewrite!(buf, "-.-.--")); - fmtd.time.update(None, rewrite!(buf, "-.---s")); - fmtd.bpm.update(None, rewrite!(buf, "---.---")); + view_cache.beat.update(None, rewrite!(buf, "{}", ViewCache::BEAT_EMPTY)); + view_cache.time.update(None, rewrite!(buf, "{}", ViewCache::TIME_EMPTY)); + view_cache.bpm.update(None, rewrite!(buf, "{}", ViewCache::BPM_EMPTY)); } } pub(crate) fn view_transport (&self) -> impl Content + use<'_> { self.update_clock(); let theme = ItemPalette::G[96]; - let fmtd = self.fmtd.read().unwrap(); + let view_cache = self.view_cache.read().unwrap(); Fixed::y(1, Tui::bg(Black, row!(Bsp::a( Fill::xy(Align::w(button_play_pause(self.clock.is_rolling()))), Fill::xy(Align::e(row!( - FieldH(theme, "BPM", fmtd.bpm.view.clone()), - FieldH(theme, "Beat", fmtd.beat.view.clone()), - FieldH(theme, "Time", fmtd.time.view.clone()) + FieldH(theme, "BPM", view_cache.bpm.view.clone()), + FieldH(theme, "Beat", view_cache.beat.view.clone()), + FieldH(theme, "Time", view_cache.time.view.clone()) ))) )))) } pub(crate) fn view_status (&self) -> impl Content + use<'_> { self.update_clock(); let theme = ItemPalette::G[96]; - let fmtd = self.fmtd.read().unwrap(); + let view_cache = self.view_cache.read().unwrap(); Tui::bg(Black, row!(Bsp::a( Fill::xy(Align::w( FieldH(theme, "Selected", self.selected.describe(&self.tracks, &self.scenes)) )), Fill::xy(Align::e(row!( - FieldH(theme, "SR", fmtd.sr.view.clone()), - FieldH(theme, "Buf", fmtd.buf.view.clone()), - FieldH(theme, "Lat", fmtd.lat.view.clone()), + FieldH(theme, "SR", view_cache.sr.view.clone()), + FieldH(theme, "Buf", view_cache.buf.view.clone()), + FieldH(theme, "Lat", view_cache.lat.view.clone()), ))) ))) } diff --git a/app/src/view/view_memo.rs b/app/src/view/view_memo.rs index 66942ba2..9deccf29 100644 --- a/app/src/view/view_memo.rs +++ b/app/src/view/view_memo.rs @@ -19,7 +19,11 @@ impl ViewMemo { fn new (value: T, view: U) -> Self { Self { value, view: Arc::new(view.into()) } } - pub(crate) fn update (&mut self, newval: T, render: impl Fn(&mut U, &T, &T)->R) -> Option { + pub(crate) fn update ( + &mut self, + newval: T, + render: impl Fn(&mut U, &T, &T)->R + ) -> Option { if newval != self.value { let result = render(&mut*self.view.write().unwrap(), &newval, &self.value); self.value = newval; @@ -42,12 +46,24 @@ impl ViewMemo { pub(crate) edit: Arc, } +impl ViewCache { + pub const BEAT_EMPTY: &'static str = "-.-.--"; + pub const TIME_EMPTY: &'static str = "-.---s"; + pub const BPM_EMPTY: &'static str = "---.---"; +} + impl Default for ViewCache { fn default () -> Self { + let mut beat = String::with_capacity(16); + write!(beat, "{}", Self::BEAT_EMPTY); + let mut time = String::with_capacity(16); + write!(time, "{}", Self::TIME_EMPTY); + let mut bpm = String::with_capacity(16); + write!(bpm, "{}", Self::BPM_EMPTY); Self { - beat: ViewMemo::new(None, String::with_capacity(16)), - time: ViewMemo::new(None, String::with_capacity(16)), - bpm: ViewMemo::new(None, String::with_capacity(16)), + beat: ViewMemo::new(None, beat), + time: ViewMemo::new(None, time), + bpm: ViewMemo::new(None, bpm), sr: ViewMemo::new(None, String::with_capacity(16)), buf: ViewMemo::new(None, String::with_capacity(16)), lat: ViewMemo::new(None, String::with_capacity(16)), diff --git a/app/src/view/view_track.rs b/app/src/view/view_track.rs index 61f06d9c..8ae81868 100644 --- a/app/src/view/view_track.rs +++ b/app/src/view/view_track.rs @@ -54,17 +54,17 @@ impl<'a> ArrangerView<'a> { fn scene_add (&'a self) -> impl Content + 'a { let data = (self.scene_selected.unwrap_or(0), self.scene_count); - self.app.fmtd.write().unwrap().scns.update(Some(data), rewrite!(buf, "({}/{})", data.0, data.1)); - button_3("S", "add scene", self.app.fmtd.read().unwrap().scns.view.clone(), self.is_editing) + self.app.view_cache.write().unwrap().scns.update(Some(data), rewrite!(buf, "({}/{})", data.0, data.1)); + button_3("S", "add scene", self.app.view_cache.read().unwrap().scns.view.clone(), self.is_editing) } fn track_counter (&'a self) -> Arc> { let track_counter_data = (self.track_selected.unwrap_or(0), self.track_count); - self.app.fmtd.write().unwrap().trks.update( + self.app.view_cache.write().unwrap().trks.update( Some(track_counter_data), rewrite!(buf, "{}/{}", track_counter_data.0, track_counter_data.1) ); - self.app.fmtd.read().unwrap().trks.view.clone() + self.app.view_cache.read().unwrap().trks.view.clone() } }