mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 11:46:41 +01:00
extract api with expose/impose macros
This commit is contained in:
parent
d893ae0309
commit
664cd8942f
9 changed files with 241 additions and 141 deletions
200
app/src/api.rs
Normal file
200
app/src/api.rs
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
use crate::*;
|
||||
|
||||
macro_rules! expose {
|
||||
($([$self:ident:$State:ty] { $($Type:ty => { $($pat:pat => $expr:expr),* $(,)? })* })*) => {
|
||||
$(expose!(@impl [$self: $State] { $($Type => { $($pat => $expr),* })* });)*
|
||||
};
|
||||
(@impl [$self:ident:$State:ty] { $($Type:ty => { $($pat:pat => $expr:expr),* $(,)? })* }) => {
|
||||
$(expose!(@type $Type [$self: $State] => { $($pat => $expr),* });)*
|
||||
};
|
||||
(@type bool [$self:ident: $State:ty] => { $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
provide_bool!(bool: |$self: $State| { $($pat => $expr),* });
|
||||
};
|
||||
(@type isize [$self:ident: $State:ty] => { $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
provide_num!(isize: |$self: $State| { $($pat => $expr),* });
|
||||
};
|
||||
(@type usize [$self:ident: $State:ty] => { $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
provide_num!(usize: |$self: $State| { $($pat => $expr),* });
|
||||
};
|
||||
(@type $Type:ty [$self:ident: $State:ty] => { $($pat:pat => $expr:expr),* $(,)? }) => {
|
||||
provide!($Type: |$self: $State| { $($pat => $expr),* });
|
||||
};
|
||||
}
|
||||
|
||||
expose!([self: Tek] {
|
||||
bool => {}
|
||||
isize => {}
|
||||
usize => {
|
||||
":scene-last" => self.scenes.len(),
|
||||
":track-last" => self.tracks.len(),
|
||||
}
|
||||
Option<usize> => {
|
||||
":scene" => self.selected.scene(),
|
||||
":track" => self.selected.track(),
|
||||
}
|
||||
Color => {}
|
||||
Arc<RwLock<MidiClip>> => {}
|
||||
Option<Arc<RwLock<MidiClip>>> => {
|
||||
":clip" => match self.selected {
|
||||
Selection::Clip(t, s) => self.scenes[s].clips[t].clone(),
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
Selection => {
|
||||
":scene-next" => match self.selected {
|
||||
Selection::Mix => Selection::Scene(0),
|
||||
Selection::Track(t) => Selection::Clip(t, 0),
|
||||
Selection::Scene(s) if s + 1 < self.scenes.len() => Selection::Scene(s + 1),
|
||||
Selection::Scene(s) => Selection::Mix,
|
||||
Selection::Clip(t, s) if s + 1 < self.scenes.len() => Selection::Clip(t, s + 1),
|
||||
Selection::Clip(t, s) => Selection::Track(t),
|
||||
},
|
||||
":scene-prev" => match self.selected {
|
||||
Selection::Mix => Selection::Mix,
|
||||
Selection::Track(t) => Selection::Track(t),
|
||||
Selection::Scene(0) => Selection::Mix,
|
||||
Selection::Scene(s) => Selection::Scene(s - 1),
|
||||
Selection::Clip(t, 0) => Selection::Track(t),
|
||||
Selection::Clip(t, s) => Selection::Clip(t, s - 1),
|
||||
},
|
||||
":track-next" => match self.selected {
|
||||
Selection::Mix => Selection::Track(0),
|
||||
Selection::Track(t) if t + 1 < self.tracks.len() => Selection::Track(t + 1),
|
||||
Selection::Track(t) => Selection::Mix,
|
||||
Selection::Scene(s) => Selection::Clip(0, s),
|
||||
Selection::Clip(t, s) if t + 1 < self.tracks.len() => Selection::Clip(t + 1, s),
|
||||
Selection::Clip(t, s) => Selection::Scene(s),
|
||||
},
|
||||
":track-prev" => match self.selected {
|
||||
Selection::Mix => Selection::Mix,
|
||||
Selection::Scene(s) => Selection::Scene(s),
|
||||
Selection::Track(0) => Selection::Mix,
|
||||
Selection::Track(t) => Selection::Track(t - 1),
|
||||
Selection::Clip(0, s) => Selection::Scene(s),
|
||||
Selection::Clip(t, s) => Selection::Clip(t - 1, s),
|
||||
},
|
||||
}
|
||||
});
|
||||
|
||||
macro_rules! impose {
|
||||
([$self:ident:$Struct:ty] { $($Command:ty => $variants:tt)* }) => {
|
||||
$(atom_command!($Command: |$self: $Struct| $variants);)*
|
||||
};
|
||||
}
|
||||
|
||||
impose!([app: Tek] {
|
||||
|
||||
TekCommand => {
|
||||
("stop" []
|
||||
Some(Self::StopAll))
|
||||
("undo" [d: usize]
|
||||
Some(Self::History(-(d.unwrap_or(0)as isize))))
|
||||
("redo" [d: usize]
|
||||
Some(Self::History(d.unwrap_or(0) as isize)))
|
||||
("zoom" [z: usize]
|
||||
Some(Self::Zoom(z)))
|
||||
("edit" []
|
||||
Some(Self::Edit(None)))
|
||||
("edit" [c: bool]
|
||||
Some(Self::Edit(c)))
|
||||
("color" [c: Color]
|
||||
Some(Self::Color(ItemPalette::random())))
|
||||
("color" [c: Color]
|
||||
Some(Self::Color(c.map(ItemPalette::from).expect("no color"))))
|
||||
("enqueue" [c: Arc<RwLock<MidiClip>>]
|
||||
Some(Self::Enqueue(c)))
|
||||
("launch" []
|
||||
Some(Self::Launch))
|
||||
("clip" [,..a]
|
||||
ClipCommand::try_from_expr(app, a).map(Self::Clip))
|
||||
("clock" [,..a]
|
||||
ClockCommand::try_from_expr(app.clock(), a).map(Self::Clock))
|
||||
("editor" [,..a]
|
||||
MidiEditCommand::try_from_expr(app.editor.as_ref().expect("no editor"), a).map(Self::Editor))
|
||||
("pool" [,..a]
|
||||
PoolCommand::try_from_expr(app.pool.as_ref().expect("no pool"), a).map(Self::Pool))
|
||||
//("sampler" [,..a]
|
||||
// Self::Sampler( //SamplerCommand::try_from_expr(app.sampler().as_ref().expect("no sampler"), a).expect("invalid command")))
|
||||
("scene" [,..a]
|
||||
SceneCommand::try_from_expr(app, a).map(Self::Scene))
|
||||
("track" [,..a]
|
||||
TrackCommand::try_from_expr(app, a).map(Self::Track))
|
||||
("input" [,..a]
|
||||
InputCommand::try_from_expr(app, a).map(Self::Input))
|
||||
("output" [,..a]
|
||||
OutputCommand::try_from_expr(app, a).map(Self::Output))
|
||||
("select" [t: Selection]
|
||||
Some(t.map(Self::Select).expect("no selection")))
|
||||
("select" [t: usize, s: usize]
|
||||
Some(match (t.expect("no track"), s.expect("no scene")) {
|
||||
(0, 0) => Self::Select(Selection::Mix),
|
||||
(t, 0) => Self::Select(Selection::Track(t)),
|
||||
(0, s) => Self::Select(Selection::Scene(s)),
|
||||
(t, s) => Self::Select(Selection::Clip(t, s)),
|
||||
}))
|
||||
}
|
||||
|
||||
ClipCommand => {
|
||||
("get" [a: usize, b: usize]
|
||||
Some(Self::Get(a.unwrap(), b.unwrap())))
|
||||
("put" [a: usize, b: usize, c: Option<Arc<RwLock<MidiClip>>>]
|
||||
Some(Self::Put(a.unwrap(), b.unwrap(), c.unwrap())))
|
||||
("enqueue" [a: usize, b: usize]
|
||||
Some(Self::Enqueue(a.unwrap(), b.unwrap())))
|
||||
("edit" [a: Option<Arc<RwLock<MidiClip>>>]
|
||||
Some(Self::Edit(a.unwrap())))
|
||||
("loop" [a: usize, b: usize, c: bool]
|
||||
Some(Self::SetLoop(a.unwrap(), b.unwrap(), c.unwrap())))
|
||||
("color" [a: usize, b: usize]
|
||||
Some(Self::SetColor(a.unwrap(), b.unwrap(), ItemPalette::random())))
|
||||
}
|
||||
|
||||
InputCommand => {
|
||||
("add" [] Some(Self::Add))
|
||||
}
|
||||
|
||||
OutputCommand => {
|
||||
("add" [] Some(Self::Add))
|
||||
}
|
||||
|
||||
SceneCommand => {
|
||||
("add" []
|
||||
Some(Self::Add))
|
||||
("del" [a: usize]
|
||||
Some(Self::Del(0)))
|
||||
("zoom" [a: usize]
|
||||
Some(Self::SetZoom(a.unwrap())))
|
||||
("color" [a: usize]
|
||||
Some(Self::SetColor(a.unwrap(), ItemPalette::G[128])))
|
||||
("enqueue" [a: usize]
|
||||
Some(Self::Enqueue(a.unwrap())))
|
||||
("swap" [a: usize, b: usize]
|
||||
Some(Self::Swap(a.unwrap(), b.unwrap())))
|
||||
}
|
||||
|
||||
TrackCommand => {
|
||||
("add" []
|
||||
Some(Self::Add))
|
||||
("size" [a: usize]
|
||||
Some(Self::SetSize(a.unwrap())))
|
||||
("zoom" [a: usize]
|
||||
Some(Self::SetZoom(a.unwrap())))
|
||||
("color" [a: usize]
|
||||
Some(Self::SetColor(a.unwrap(), ItemPalette::random())))
|
||||
("del" [a: usize]
|
||||
Some(Self::Del(a.unwrap())))
|
||||
("stop" [a: usize]
|
||||
Some(Self::Stop(a.unwrap())))
|
||||
("swap" [a: usize, b: usize]
|
||||
Some(Self::Swap(a.unwrap(), b.unwrap())))
|
||||
("play" []
|
||||
Some(Self::TogglePlay))
|
||||
("solo" []
|
||||
Some(Self::ToggleSolo))
|
||||
("rec" []
|
||||
Some(Self::ToggleRecord))
|
||||
("mon" []
|
||||
Some(Self::ToggleMonitor))
|
||||
}
|
||||
|
||||
});
|
||||
|
|
@ -52,34 +52,6 @@ handle!(TuiIn: |self: Tek, input|Ok({
|
|||
Track(TrackCommand),
|
||||
Zoom(Option<usize>),
|
||||
}
|
||||
atom_command!(TekCommand: |app: Tek| {
|
||||
("stop" [] Some(Self::StopAll))
|
||||
("undo" [d: usize] Some(Self::History(-(d.unwrap_or(0)as isize))))
|
||||
("redo" [d: usize] Some(Self::History(d.unwrap_or(0) as isize)))
|
||||
("zoom" [z: usize] Some(Self::Zoom(z)))
|
||||
("edit" [] Some(Self::Edit(None)))
|
||||
("edit" [c: bool] Some(Self::Edit(c)))
|
||||
("color" [c: Color] Some(Self::Color(ItemPalette::random())))
|
||||
("color" [c: Color] Some(Self::Color(c.map(ItemPalette::from).expect("no color"))))
|
||||
("enqueue" [c: Arc<RwLock<MidiClip>>] Some(Self::Enqueue(c)))
|
||||
("launch" [] Some(Self::Launch))
|
||||
("clip" [,..a] ClipCommand::try_from_expr(app, a).map(Self::Clip))
|
||||
("clock" [,..a] ClockCommand::try_from_expr(app.clock(), a).map(Self::Clock))
|
||||
("editor" [,..a] MidiEditCommand::try_from_expr(app.editor.as_ref().expect("no editor"), a).map(Self::Editor))
|
||||
("pool" [,..a] PoolCommand::try_from_expr(app.pool.as_ref().expect("no pool"), a).map(Self::Pool))
|
||||
//("sampler" [,..a] Self::Sampler( //SamplerCommand::try_from_expr(app.sampler().as_ref().expect("no sampler"), a).expect("invalid command")))
|
||||
("scene" [,..a] SceneCommand::try_from_expr(app, a).map(Self::Scene))
|
||||
("track" [,..a] TrackCommand::try_from_expr(app, a).map(Self::Track))
|
||||
("input" [,..a] InputCommand::try_from_expr(app, a).map(Self::Input))
|
||||
("output" [,..a] OutputCommand::try_from_expr(app, a).map(Self::Output))
|
||||
("select" [t: Selection] Some(t.map(Self::Select).expect("no selection")))
|
||||
("select" [t: usize, s: usize] Some(match (t.expect("no track"), s.expect("no scene")) {
|
||||
(0, 0) => Self::Select(Selection::Mix),
|
||||
(t, 0) => Self::Select(Selection::Track(t)),
|
||||
(0, s) => Self::Select(Selection::Scene(s)),
|
||||
(t, s) => Self::Select(Selection::Clip(t, s)),
|
||||
}))
|
||||
});
|
||||
command!(|self: TekCommand, app: Tek|match self {
|
||||
Self::Zoom(_) => { println!("\n\rtodo: global zoom"); None },
|
||||
Self::History(delta) => { println!("\n\rtodo: undo/redo"); None },
|
||||
|
|
|
|||
|
|
@ -7,14 +7,6 @@ use crate::*;
|
|||
SetLoop(usize, usize, bool),
|
||||
SetColor(usize, usize, ItemPalette),
|
||||
}
|
||||
atom_command!(ClipCommand: |app: Tek| {
|
||||
("get" [a: usize, b: usize] Some(Self::Get(a.unwrap(), b.unwrap())))
|
||||
("put" [a: usize, b: usize, c: Option<Arc<RwLock<MidiClip>>>] Some(Self::Put(a.unwrap(), b.unwrap(), c.unwrap())))
|
||||
("enqueue" [a: usize, b: usize] Some(Self::Enqueue(a.unwrap(), b.unwrap())))
|
||||
("edit" [a: Option<Arc<RwLock<MidiClip>>>] Some(Self::Edit(a.unwrap())))
|
||||
("loop" [a: usize, b: usize, c: bool] Some(Self::SetLoop(a.unwrap(), b.unwrap(), c.unwrap())))
|
||||
("color" [a: usize, b: usize] Some(Self::SetColor(a.unwrap(), b.unwrap(), ItemPalette::random())))
|
||||
});
|
||||
command!(|self: ClipCommand, app: Tek|match self {
|
||||
Self::Get(track, scene) => { todo!() },
|
||||
Self::Put(track, scene, clip) => {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
use crate::*;
|
||||
#[derive(Clone, Debug)] pub enum InputCommand { Add }
|
||||
atom_command!(InputCommand: |app: Tek| {
|
||||
("add" [] Some(Self::Add))
|
||||
});
|
||||
command!(|self: InputCommand, app: Tek|match self {
|
||||
Self::Add => {
|
||||
app.midi_ins.push(JackMidiIn::new(&app.jack, &format!("M/{}", app.midi_ins.len()), &[])?);
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
use crate::*;
|
||||
#[derive(Clone, Debug)] pub enum OutputCommand { Add }
|
||||
atom_command!(OutputCommand: |app: Tek| {
|
||||
("add" [] Some(Self::Add))
|
||||
});
|
||||
command!(|self: OutputCommand, app: Tek|match self {
|
||||
Self::Add => {
|
||||
app.midi_outs.push(JackMidiOut::new(&app.jack, &format!("{}/M", app.midi_outs.len()), &[])?);
|
||||
|
|
|
|||
|
|
@ -8,14 +8,6 @@ use crate::*;
|
|||
SetColor(usize, ItemPalette),
|
||||
Enqueue(usize),
|
||||
}
|
||||
atom_command!(SceneCommand: |app: Tek| {
|
||||
("add" [] Some(Self::Add))
|
||||
("del" [a: usize] Some(Self::Del(0)))
|
||||
("zoom" [a: usize] Some(Self::SetZoom(a.unwrap())))
|
||||
("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemPalette::G[128])))
|
||||
("enqueue" [a: usize] Some(Self::Enqueue(a.unwrap())))
|
||||
("swap" [a: usize, b: usize] Some(Self::Swap(a.unwrap(), b.unwrap())))
|
||||
});
|
||||
command!(|self: SceneCommand, app: Tek|match self {
|
||||
Self::Add => {
|
||||
use Selection::*;
|
||||
|
|
|
|||
|
|
@ -12,19 +12,6 @@ use crate::*;
|
|||
ToggleRecord,
|
||||
ToggleMonitor,
|
||||
}
|
||||
atom_command!(TrackCommand: |app: Tek| {
|
||||
("add" [] Some(Self::Add))
|
||||
("size" [a: usize] Some(Self::SetSize(a.unwrap())))
|
||||
("zoom" [a: usize] Some(Self::SetZoom(a.unwrap())))
|
||||
("color" [a: usize] Some(Self::SetColor(a.unwrap(), ItemPalette::random())))
|
||||
("del" [a: usize] Some(Self::Del(a.unwrap())))
|
||||
("stop" [a: usize] Some(Self::Stop(a.unwrap())))
|
||||
("swap" [a: usize, b: usize] Some(Self::Swap(a.unwrap(), b.unwrap())))
|
||||
("play" [] Some(Self::TogglePlay))
|
||||
("solo" [] Some(Self::ToggleSolo))
|
||||
("rec" [] Some(Self::ToggleRecord))
|
||||
("mon" [] Some(Self::ToggleMonitor))
|
||||
});
|
||||
command!(|self: TrackCommand, app: Tek|match self {
|
||||
Self::Add => {
|
||||
use Selection::*;
|
||||
|
|
|
|||
|
|
@ -14,11 +14,6 @@
|
|||
#![feature(type_alias_impl_trait)]
|
||||
#![feature(trait_alias)]
|
||||
#![feature(type_changing_struct_update)]
|
||||
mod audio; pub use self::audio::*;
|
||||
mod device; pub use self::device::*;
|
||||
mod keys; pub use self::keys::*;
|
||||
mod model; pub use self::model::*;
|
||||
mod view; pub use self::view::*;
|
||||
/// Standard result type.
|
||||
pub type Usually<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||
/// Standard optional result type.
|
||||
|
|
@ -39,3 +34,17 @@ pub use ::tengri::tui::ratatui::prelude::{Style, Stylize, Buffer, Modifier};
|
|||
pub use ::tengri::tui::crossterm;
|
||||
pub use ::tengri::tui::crossterm::event::{Event, KeyCode::{self, *}};
|
||||
pub(crate) use std::sync::{Arc, RwLock, atomic::{AtomicBool, Ordering::Relaxed}};
|
||||
|
||||
mod api; pub use self::api::*;
|
||||
mod audio; pub use self::audio::*;
|
||||
mod device; pub use self::device::*;
|
||||
mod keys; pub use self::keys::*;
|
||||
mod model; pub use self::model::*;
|
||||
mod view; pub use self::view::*;
|
||||
|
||||
#[cfg(test)] #[test] fn test_model () {
|
||||
let mut tek = Tek::default();
|
||||
let _ = tek.clip();
|
||||
let _ = tek.toggle_loop();
|
||||
let _ = tek.activate();
|
||||
}
|
||||
|
|
|
|||
100
app/src/model.rs
100
app/src/model.rs
|
|
@ -1,7 +1,9 @@
|
|||
use crate::*;
|
||||
|
||||
mod model_track; pub use self::model_track::*;
|
||||
mod model_scene; pub use self::model_scene::*;
|
||||
mod model_select; pub use self::model_select::*;
|
||||
|
||||
#[derive(Default, Debug)] pub struct Tek {
|
||||
/// Must not be dropped for the duration of the process
|
||||
pub jack: Jack,
|
||||
|
|
@ -62,73 +64,7 @@ mod model_select; pub use self::model_select::*;
|
|||
// Cache of formatted strings
|
||||
pub view_cache: Arc<RwLock<ViewCache>>,
|
||||
}
|
||||
has_size!(<TuiOut>|self: Tek|&self.size);
|
||||
has_clock!(|self: Tek|self.clock);
|
||||
has_clips!(|self: Tek|self.pool.as_ref().expect("no clip pool").clips);
|
||||
//has_sampler!(|self: Tek|{
|
||||
//sampler = self.sampler;
|
||||
//index = self.editor.as_ref().map(|e|e.note_pos()).unwrap_or(0); });
|
||||
has_editor!(|self: Tek|{
|
||||
editor = self.editor;
|
||||
editor_w = {
|
||||
let size = self.size.w();
|
||||
let editor = self.editor.as_ref().expect("missing editor");
|
||||
let time_len = editor.time_len().get();
|
||||
let time_zoom = editor.time_zoom().get().max(1);
|
||||
(5 + (time_len / time_zoom)).min(size.saturating_sub(20)).max(16)
|
||||
};
|
||||
editor_h = 15;
|
||||
is_editing = self.editing.load(Relaxed); });
|
||||
provide!(Color: |self: Tek| {});
|
||||
provide!(Arc<RwLock<MidiClip>>: |self: Tek| {});
|
||||
provide!(Option<Arc<RwLock<MidiClip>>>: |self: Tek| {
|
||||
":clip" => match self.selected {
|
||||
Selection::Clip(t, s) => self.scenes[s].clips[t].clone(),
|
||||
_ => None
|
||||
}
|
||||
});
|
||||
provide_bool!(bool: |self: Tek| {});
|
||||
provide_num!(isize: |self: Tek| {});
|
||||
provide_num!(usize: |self: Tek| {
|
||||
":scene-last" => self.scenes.len(),
|
||||
":track-last" => self.tracks.len() });
|
||||
provide!(Option<usize>: |self: Tek| {
|
||||
":scene" => self.selected.scene(),
|
||||
":track" => self.selected.track() });
|
||||
provide!(Selection: |self: Tek| {
|
||||
":scene-next" => match self.selected {
|
||||
Selection::Mix => Selection::Scene(0),
|
||||
Selection::Track(t) => Selection::Clip(t, 0),
|
||||
Selection::Scene(s) if s + 1 < self.scenes.len() => Selection::Scene(s + 1),
|
||||
Selection::Scene(s) => Selection::Mix,
|
||||
Selection::Clip(t, s) if s + 1 < self.scenes.len() => Selection::Clip(t, s + 1),
|
||||
Selection::Clip(t, s) => Selection::Track(t),
|
||||
},
|
||||
":scene-prev" => match self.selected {
|
||||
Selection::Mix => Selection::Mix,
|
||||
Selection::Track(t) => Selection::Track(t),
|
||||
Selection::Scene(0) => Selection::Mix,
|
||||
Selection::Scene(s) => Selection::Scene(s - 1),
|
||||
Selection::Clip(t, 0) => Selection::Track(t),
|
||||
Selection::Clip(t, s) => Selection::Clip(t, s - 1),
|
||||
},
|
||||
":track-next" => match self.selected {
|
||||
Selection::Mix => Selection::Track(0),
|
||||
Selection::Track(t) if t + 1 < self.tracks.len() => Selection::Track(t + 1),
|
||||
Selection::Track(t) => Selection::Mix,
|
||||
Selection::Scene(s) => Selection::Clip(0, s),
|
||||
Selection::Clip(t, s) if t + 1 < self.tracks.len() => Selection::Clip(t + 1, s),
|
||||
Selection::Clip(t, s) => Selection::Scene(s),
|
||||
},
|
||||
":track-prev" => match self.selected {
|
||||
Selection::Mix => Selection::Mix,
|
||||
Selection::Scene(s) => Selection::Scene(s),
|
||||
Selection::Track(0) => Selection::Mix,
|
||||
Selection::Track(t) => Selection::Track(t - 1),
|
||||
Selection::Clip(0, s) => Selection::Scene(s),
|
||||
Selection::Clip(t, s) => Selection::Clip(t - 1, s),
|
||||
},
|
||||
});
|
||||
|
||||
impl Tek {
|
||||
fn clip (&self) -> Option<Arc<RwLock<MidiClip>>> {
|
||||
self.scene()?.clips.get(self.selected().track()?)?.clone()
|
||||
|
|
@ -164,9 +100,27 @@ impl Tek {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
#[cfg(test)] #[test] fn test_model () {
|
||||
let mut tek = Tek::default();
|
||||
let _ = tek.clip();
|
||||
let _ = tek.toggle_loop();
|
||||
let _ = tek.activate();
|
||||
}
|
||||
|
||||
has_size!(<TuiOut>|self: Tek|&self.size);
|
||||
|
||||
has_clock!(|self: Tek|self.clock);
|
||||
|
||||
has_clips!(|self: Tek|self.pool.as_ref().expect("no clip pool").clips);
|
||||
|
||||
has_editor!(|self: Tek|{
|
||||
editor = self.editor;
|
||||
editor_w = {
|
||||
let size = self.size.w();
|
||||
let editor = self.editor.as_ref().expect("missing editor");
|
||||
let time_len = editor.time_len().get();
|
||||
let time_zoom = editor.time_zoom().get().max(1);
|
||||
(5 + (time_len / time_zoom)).min(size.saturating_sub(20)).max(16)
|
||||
};
|
||||
editor_h = 15;
|
||||
is_editing = self.editing.load(Relaxed);
|
||||
});
|
||||
|
||||
//has_sampler!(|self: Tek|{
|
||||
//sampler = self.sampler;
|
||||
//index = self.editor.as_ref().map(|e|e.note_pos()).unwrap_or(0);
|
||||
//});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue