use crate::*; impl Tek { pub fn scenes_add (&mut self, n: usize) -> Usually<()> { let scene_color_1 = ItemColor::random(); let scene_color_2 = ItemColor::random(); for i in 0..n { let _ = self.scene_add(None, Some( scene_color_1.mix(scene_color_2, i as f32 / n as f32).into() ))?; } Ok(()) } pub fn scene_add (&mut self, name: Option<&str>, color: Option) -> Usually<(usize, &mut Scene)> { let scene = Scene { name: name.map_or_else(||self.scene_default_name(), |x|x.to_string().into()), clips: vec![None;self.tracks().len()], color: color.unwrap_or_else(ItemPalette::random), }; self.scenes_mut().push(scene); let index = self.scenes().len() - 1; Ok((index, &mut self.scenes_mut()[index])) } pub fn scene_default_name (&self) -> Arc { format!("Sc{:3>}", self.scenes().len() + 1).into() } } pub trait HasScenes: HasSelection + HasEditor + Send + Sync { fn scenes (&self) -> &Vec; fn scenes_mut (&mut self) -> &mut Vec; fn scene_longest (&self) -> usize { self.scenes().iter().map(|s|s.name.len()).fold(0, usize::max) } fn scene (&self) -> Option<&Scene> { self.selected().scene().and_then(|s|self.scenes().get(s)) } fn scene_mut (&mut self) -> Option<&mut Scene> { self.selected().scene().and_then(|s|self.scenes_mut().get_mut(s)) } fn scene_del (&mut self, index: usize) { self.selected().scene().and_then(|s|Some(self.scenes_mut().remove(index))); } } #[derive(Debug, Default)] pub struct Scene { /// Name of scene pub name: Arc, /// Clips in scene, one per track pub clips: Vec>>>, /// Identifying color of scene pub color: ItemPalette, } impl Scene { /// Returns the pulse length of the longest clip in the scene fn pulses (&self) -> usize { self.clips.iter().fold(0, |a, p|{ a.max(p.as_ref().map(|q|q.read().unwrap().length).unwrap_or(0)) }) } /// Returns true if all clips in the scene are /// currently playing on the given collection of tracks. fn is_playing (&self, tracks: &[Track]) -> bool { self.clips.iter().any(|clip|clip.is_some()) && self.clips.iter().enumerate() .all(|(track_index, clip)|match clip { Some(c) => tracks .get(track_index) .map(|track|{ if let Some((_, Some(clip))) = track.player().play_clip() { *clip.read().unwrap() == *c.read().unwrap() } else { false } }) .unwrap_or(false), None => true }) } pub fn clip (&self, index: usize) -> Option<&Arc>> { match self.clips.get(index) { Some(Some(clip)) => Some(clip), _ => None } } } impl HasScenes for Tek { fn scenes (&self) -> &Vec { &self.scenes } fn scenes_mut (&mut self) -> &mut Vec { &mut self.scenes } } #[cfg(test)] #[test] fn test_model_scene () { let mut app = Tek::default(); let _ = app.scene_longest(); let _ = app.scene(); let _ = app.scene_mut(); let _ = app.scene_add(None, None); app.scene_del(0); let scene = Scene::default(); let _ = scene.pulses(); let _ = scene.is_playing(&[]); }