tek/crates/device/src/pool/pool_api.rs
unspeaker fc038dbd97
Some checks failed
/ build (push) Has been cancelled
wip: use only Dsl trait
2025-05-19 00:06:31 +03:00

252 lines
8.2 KiB
Rust

use crate::*;
#[tengri_proc::expose]
impl Pool {
fn _todo_usize_ (&self) -> usize { todo!() }
fn _todo_bool_ (&self) -> bool { todo!() }
fn _todo_clip_ (&self) -> MidiClip { todo!() }
fn _todo_path_ (&self) -> PathBuf { todo!() }
fn _todo_color_ (&self) -> ItemColor { todo!() }
fn _todo_str_ (&self) -> Arc<str> { todo!() }
fn clip_new (&self) -> MidiClip {
self.new_clip()
}
fn clip_cloned (&self) -> MidiClip {
self.cloned_clip()
}
fn clip_index_current (&self) -> usize {
0
}
fn clip_index_after (&self) -> usize {
0
}
fn clip_index_previous (&self) -> usize {
0
}
fn clip_index_next (&self) -> usize {
0
}
fn color_random (&self) -> ItemColor {
ItemColor::random()
}
}
#[tengri_proc::command(Pool)]
impl PoolCommand {
/// Toggle visibility of pool
fn show (pool: &mut Pool, visible: bool) -> Perhaps<Self> {
pool.visible = visible;
Ok(Some(Self::Show { visible: !visible }))
}
/// Select a clip from the clip pool
fn select (pool: &mut Pool, index: usize) -> Perhaps<Self> {
pool.set_clip_index(index);
Ok(None)
}
/// Rename a clip
fn rename (pool: &mut Pool, command: RenameCommand) -> Perhaps<Self> {
Ok(command.delegate(pool, |command|Self::Rename{command})?)
}
/// Change the length of a clip
fn length (pool: &mut Pool, command: CropCommand) -> Perhaps<Self> {
Ok(command.delegate(pool, |command|Self::Length{command})?)
}
/// Import from file
fn import (pool: &mut Pool, command: BrowserCommand) -> Perhaps<Self> {
Ok(if let Some(browser) = pool.browser.as_mut() {
command.delegate(browser, |command|Self::Import{command})?
} else {
None
})
}
/// Export to file
fn export (pool: &mut Pool, command: BrowserCommand) -> Perhaps<Self> {
Ok(if let Some(browser) = pool.browser.as_mut() {
command.delegate(browser, |command|Self::Export{command})?
} else {
None
})
}
/// Update the contents of the clip pool
fn clip (pool: &mut Pool, command: PoolClipCommand) -> Perhaps<Self> {
Ok(command.execute(pool)?.map(|command|Self::Clip{command}))
}
}
dsl!(BrowserCommand: |self: Pool, iter|Ok(self.browser
.as_ref().map(|p|p.take(iter)).transpose()?.flatten()));
#[tengri_proc::command(Pool)]
impl PoolClipCommand {
fn add (pool: &mut Pool, index: usize, clip: MidiClip) -> Perhaps<Self> {
let mut index = index;
let clip = Arc::new(RwLock::new(clip));
let mut clips = pool.clips_mut();
if index >= clips.len() {
index = clips.len();
clips.push(clip)
} else {
clips.insert(index, clip);
}
Ok(Some(Self::Delete { index }))
}
fn delete (pool: &mut Pool, index: usize) -> Perhaps<Self> {
let clip = pool.clips_mut().remove(index).read().unwrap().clone();
Ok(Some(Self::Add { index, clip }))
}
fn swap (pool: &mut Pool, index: usize, other: usize) -> Perhaps<Self> {
pool.clips_mut().swap(index, other);
Ok(Some(Self::Swap { index, other }))
}
fn import (pool: &mut Pool, index: usize, path: PathBuf) -> Perhaps<Self> {
let bytes = std::fs::read(&path)?;
let smf = Smf::parse(bytes.as_slice())?;
let mut t = 0u32;
let mut events = vec![];
for track in smf.tracks.iter() {
for event in track.iter() {
t += event.delta.as_int();
if let TrackEventKind::Midi { channel, message } = event.kind {
events.push((t, channel.as_int(), message));
}
}
}
let mut clip = MidiClip::new("imported", true, t as usize + 1, None, None);
for event in events.iter() {
clip.notes[event.0 as usize].push(event.2);
}
Ok(Self::Add { index, clip }.execute(pool)?)
}
fn export (pool: &mut Pool, index: usize, path: PathBuf) -> Perhaps<Self> {
todo!("export clip to midi file");
}
fn set_name (pool: &mut Pool, index: usize, name: Arc<str>) -> Perhaps<Self> {
let clip = &mut pool.clips_mut()[index];
let old_name = clip.read().unwrap().name.clone();
clip.write().unwrap().name = name;
Ok(Some(Self::SetName { index, name: old_name }))
}
fn set_length (pool: &mut Pool, index: usize, length: usize) -> Perhaps<Self> {
let clip = &mut pool.clips_mut()[index];
let old_len = clip.read().unwrap().length;
clip.write().unwrap().length = length;
Ok(Some(Self::SetLength { index, length: old_len }))
}
fn set_color (pool: &mut Pool, index: usize, color: ItemColor) -> Perhaps<Self> {
let mut color = ItemTheme::from(color);
std::mem::swap(&mut color, &mut pool.clips()[index].write().unwrap().color);
Ok(Some(Self::SetColor { index, color: color.base }))
}
}
#[tengri_proc::command(Pool)]
impl RenameCommand {
fn begin (pool: &mut Pool) -> Perhaps<Self> {
unreachable!();
}
fn cancel (pool: &mut Pool) -> Perhaps<Self> {
if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() {
pool.clips()[clip].write().unwrap().name = old_name.clone().into();
}
return Ok(None)
}
fn confirm (pool: &mut Pool) -> Perhaps<Self> {
if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() {
let old_name = old_name.clone();
*pool.mode_mut() = None;
return Ok(Some(Self::Set { value: old_name }))
}
return Ok(None)
}
fn set (pool: &mut Pool, value: Arc<str>) -> Perhaps<Self> {
if let Some(PoolMode::Rename(clip, ref mut old_name)) = pool.mode_mut().clone() {
pool.clips()[clip].write().unwrap().name = value;
}
return Ok(None)
}
}
#[tengri_proc::command(Pool)]
impl CropCommand {
fn begin (pool: &mut Pool) -> Perhaps<Self> {
unreachable!()
}
fn cancel (pool: &mut Pool) -> Perhaps<Self> {
if let Some(PoolMode::Length(..)) = pool.mode_mut().clone() {
*pool.mode_mut() = None;
}
Ok(None)
}
fn set (pool: &mut Pool, length: usize) -> Perhaps<Self> {
if let Some(PoolMode::Length(clip, ref mut length, ref mut focus))
= pool.mode_mut().clone()
{
let old_length;
{
let clip = pool.clips()[clip].clone();//.write().unwrap();
old_length = Some(clip.read().unwrap().length);
clip.write().unwrap().length = *length;
}
*pool.mode_mut() = None;
return Ok(old_length.map(|length|Self::Set { length }))
}
Ok(None)
}
fn next (pool: &mut Pool) -> Perhaps<Self> {
if let Some(PoolMode::Length(clip, ref mut length, ref mut focus))
= pool.mode_mut().clone()
{
focus.next()
}
Ok(None)
}
fn prev (pool: &mut Pool) -> Perhaps<Self> {
if let Some(PoolMode::Length(clip, ref mut length, ref mut focus))
= pool.mode_mut().clone()
{
focus.prev()
}
Ok(None)
}
fn inc (pool: &mut Pool) -> Perhaps<Self> {
if let Some(PoolMode::Length(clip, ref mut length, ref mut focus))
= pool.mode_mut().clone()
{
match focus {
ClipLengthFocus::Bar => { *length += 4 * PPQ },
ClipLengthFocus::Beat => { *length += PPQ },
ClipLengthFocus::Tick => { *length += 1 },
}
}
Ok(None)
}
fn dec (pool: &mut Pool) -> Perhaps<Self> {
if let Some(PoolMode::Length(clip, ref mut length, ref mut focus))
= pool.mode_mut().clone()
{
match focus {
ClipLengthFocus::Bar => { *length = length.saturating_sub(4 * PPQ) },
ClipLengthFocus::Beat => { *length = length.saturating_sub(PPQ) },
ClipLengthFocus::Tick => { *length = length.saturating_sub(1) },
}
}
Ok(None)
}
}