SlotExt::map_inner(_mut); HasClip::clip_mut

This commit is contained in:
i do not exist 2026-09-22 22:53:38 +03:00
parent ca774cca41
commit fdee3fbfc8
7 changed files with 214 additions and 168 deletions

View file

@ -1,6 +1,4 @@
use crate::*;
impl_as_ref!(Option<Project>: |self: App|todo!());
impl_as_mut!(Option<Project>: |self: App|todo!());
pub trait HasProject: AsRef<Option<Project>> + AsMut<Option<Project>> {}
impl<T: AsRef<Option<Project>> + AsMut<Option<Project>>> HasProject for T {}
/// Arranger.
@ -117,21 +115,18 @@ impl_as_ref_opt!(Scene: |self: Project| self.selected_scene());
impl_as_mut_opt!(Scene: |self: Project| self.selected_scene_mut());
impl_as_ref!(Option<MidiEditor>: |self: Project| &self.editor);
impl_as_mut!(Option<MidiEditor>: |self: Project| &mut self.editor);
//impl HasClip for Project {
//fn clip (&self) -> Option<RwLockReadGuard<'_, Option<Arc<RwLock<MidiClip>>>>> {
//match self.selection {
//Selection::Pool(index) =>
//self.clips.read(index),
//Selection::TrackClip { track, scene } if let Some(scene) = self.scenes.get(scene) =>
//scene.clips.read(track),
//_ =>
//None
//}
//}
//fn clip_mut (&self) -> RwLockWriteGuard<'_, Option<Arc<RwLock<MidiClip>>>> {
//self.as_ref().0.write()
//}
//}
impl HasClip for Project {
fn clip_slot (&self) -> Option<Slot<MidiClip>> {
match self.selection {
Selection::Clip(index) =>
Some(self.clips.slot(index)),
Selection::TrackClip { track, scene } if let Some(scene) = self.scenes.get(scene) =>
Some(scene.clips.slot(track)),
_ =>
None
}
}
}
pub fn swap_value <T: Clone + PartialEq, U> (
target: &mut T, value: &T, returned: impl Fn(T)->U
) -> Perhaps<U> {
@ -154,118 +149,6 @@ pub fn toggle_bool <U> (
Ok(Some(returned(Some(value))))
}
}
#[derive(Default, Debug)] pub struct Slot<T>(pub Arc<RwLock<Option<Arc<RwLock<T>>>>>);
pub type SampleSlot = Slot<Sample>;
pub type ClipSlot = Slot<MidiClip>;
impl<T> Clone for Slot<T> { fn clone (&self) -> Self { Slot(self.0.clone()) } }
impl<T> Slot<T> {
pub fn new (value: impl Into<Option<T>>) -> Self {
Self(Arc::new(RwLock::new(value.into().map(|value|Arc::new(RwLock::new(value))))))
}
pub fn read (&self) -> ArcRwLockReadGuard<RawRwLock, Option<Arc<RwLock<T>>>> {
self.0.read_arc()
}
pub fn write (&self) -> ArcRwLockWriteGuard<RawRwLock, Option<Arc<RwLock<T>>>> {
self.0.write_arc()
}
pub fn set_to (&mut self, value: Self) {
self.0 = value.0;
}
pub fn set (&self, value: Option<T>) -> Option<Arc<RwLock<T>>> {
let mut value = value.map(|value|Arc::new(RwLock::new(value)));
std::mem::swap(&mut*self.0.write(), &mut value);
value
}
pub fn map_inner <U> (&self, cb: impl FnOnce(&T)->U) -> Option<U> {
self.read().as_ref().map(|x|cb(&*x.read()))
}
}
impl Slot<MidiClip> {
pub fn eval <'a> (state: &App, src: impl Language) -> Perhaps<ClipSlot> {
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<RwLock<MidiClip>> = Arc::new(RwLock::new(Default::default()));
//state.scenes()[*scene].clips[*track] = Some(clip.clone());
//clip
//}),
_ => return err!("not a clip: {word}")
}))
}
}
impl Slot<Sample> {
pub fn eval <'a> (_: &App, _: impl Language) -> Perhaps<SampleSlot> {
todo!()
}
}
#[derive(Default, Debug)] pub struct Pool<T>(pub Arc<RwLock<Vec<Slot<T>>>>);
impl<T> Clone for Pool<T> { fn clone (&self) -> Self { Pool(self.0.clone()) } }
pub type SamplePool = Pool<Sample>;
pub type ClipPool = Pool<MidiClip>;
impl<T> Pool<T> {
pub fn slot (&self, index: usize) -> Slot<T> {
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<Arc<RwLock<T>>> {
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<ArcRwLockReadGuard<RawRwLock, Option<Arc<RwLock<T>>>>> {
self.0.read_arc().get(index).map(|clip|clip.read())
}
pub fn set (&self, index: usize, value: Option<T>) {
self.write()[index] = Slot::new(value);
}
pub fn read (&self) -> ArcRwLockReadGuard<RawRwLock, Vec<Slot<T>>> {
self.0.read_arc()
}
pub fn write (&self) -> ArcRwLockWriteGuard<RawRwLock, Vec<Slot<T>>> {
self.0.write_arc()
}
pub fn append (&self, value: Option<T>) -> Slot<T> {
let slot = Slot::new(value);
self.0.write().push(slot.clone());
slot
}
}
impl Pool<MidiClip> {
pub fn eval <'a> (_: &App, _: impl Language) -> Perhaps<ClipPool> {
todo!()
}
pub fn remove (&self, filter: &MidiClip) {
let iter = self.0.write();
iter.retain(|x|if let Some(x) = &*x.0.read() { x!=filter } else { true })
}
}
impl Pool<Sample> {
pub fn eval <'a> (_: &App, _: impl Language) -> Perhaps<SamplePool> {
todo!()
}
}
impl<T> From<Vec<Option<T>>> for Pool<T> {
fn from (values: Vec<Option<T>>) -> Self {
Self(Arc::new(RwLock::new(values.into_iter().map(Slot::new).collect())))
}
}
/// Modes for clip pool
#[derive(Debug, Clone)] pub enum PoolMode {
/// Renaming a pattern