use crate::*; #[derive(Default, Debug)] pub struct Pool(pub Arc>>>); pub type SamplePool = Pool; pub type ClipPool = Pool; impl Clone for Pool { fn clone (&self) -> Self { Pool(self.0.clone()) } } impl Pool { pub fn slot (&self, index: usize) -> Slot { let mut state = self.0.write(); while index >= state.len() { state.push(Slot::new(None)); } state[index].clone() } pub fn delete (&self, index: usize) -> Option>> { let mut none = None; let mut slot = self.slot(index).write(); std::mem::swap(&mut none, &mut slot); none } pub fn len (&self) -> usize { self.0.read().len() } pub fn get (&self, index: usize) -> Option>>>> { self.0.read_arc().get(index).map(|clip|clip.read()) } pub fn set (&self, index: usize, value: Option) { self.write()[index] = Slot::new(value); } pub fn read (&self) -> ArcRwLockReadGuard>> { self.0.read_arc() } pub fn write (&self) -> ArcRwLockWriteGuard>> { self.0.write_arc() } pub fn append (&self, value: Option) -> Slot { let slot = Slot::new(value); self.0.write().push(slot.clone()); slot } } impl Pool { pub fn eval <'a, T> (_: &T, _: impl Language) -> Perhaps { todo!() } pub fn remove (&self, filter: &MidiClip) { let mut iter = self.0.write(); iter.retain(|x|if let Some(x) = &*x.0.read() { &*x.read() != filter } else { true }) } } impl Pool { pub fn eval <'a> (_: &App, _: impl Language) -> Perhaps { todo!() } } impl From>> for Pool { fn from (values: Vec>) -> Self { Self(Arc::new(RwLock::new(values.into_iter().map(Slot::new).collect()))) } } #[derive(Default, Debug)] pub struct Slot(pub Arc>>>>); pub type SampleSlot = Slot; pub type ClipSlot = Slot; impl Clone for Slot { fn clone (&self) -> Self { Slot(self.0.clone()) } } impl Slot { pub fn new (value: impl Into>) -> Self { Self(Arc::new(RwLock::new(value.into().map(|value|Arc::new(RwLock::new(value)))))) } pub fn read (&self) -> ArcRwLockReadGuard>>> { self.0.read_arc() } pub fn write (&self) -> ArcRwLockWriteGuard>>> { self.0.write_arc() } pub fn set_to (&mut self, value: Self) { self.0 = value.0; } pub fn set (&self, value: Option) -> Option>> { let mut value = value.map(|value|Arc::new(RwLock::new(value))); std::mem::swap(&mut*self.0.write(), &mut value); value } } pub trait SlotExt { fn map_inner (&self, cb: impl FnOnce(&T)->U) -> Option; fn map_inner_mut (&self, cb: impl FnOnce(&mut T)->U) -> Option; } impl SlotExt for Slot { fn map_inner (&self, cb: impl FnOnce(&T)->U) -> Option { self.read().as_ref().map(|x|cb(&*x.read())) } fn map_inner_mut (&self, cb: impl FnOnce(&mut T)->U) -> Option { self.read().as_ref().map(|x|cb(&mut*x.write())) } } impl SlotExt for Option> { fn map_inner (&self, cb: impl FnOnce(&T)->U) -> Option { self.as_ref().map(|x|x.map_inner(cb))? } fn map_inner_mut (&self, cb: impl FnOnce(&mut T)->U) -> Option { self.as_ref().map(|x|x.map_inner_mut(cb))? } } impl Slot { pub fn eval <'a> (state: &App, src: impl Language) -> Perhaps { eval_word(src, |word|Ok(match word { ":selected" if let Selection::TrackClip { track, scene } = state.selection() => { state.scenes()[*scene].clips.slot(*track) }, //":selected-or-create" if let Selection::TrackClip { //track, scene //} = state.selection() => Some(if let Some(Some(clip)) = state.scenes()[*scene].clips.get(*track) { //clip.clone() //} else { //let clip: Arc> = Arc::new(RwLock::new(Default::default())); //state.scenes()[*scene].clips[*track] = Some(clip.clone()); //clip //}), _ => return err!("not a clip: {word}") })) } } impl Slot { pub fn eval <'a> (_: &App, _: impl Language) -> Perhaps { todo!() } }