use impl_default, remove some feature annotations
Some checks failed
/ build (push) Has been cancelled

This commit is contained in:
okay stopped screaming 2026-02-23 23:10:57 +02:00
parent ab90129f4c
commit 4f5c332f48
3 changed files with 373 additions and 426 deletions

View file

@ -1,4 +1,50 @@
//pub fn track_counter (cache: &Arc<RwLock<Self>>, track: usize, tracks: usize)
//-> Arc<RwLock<String>>
//{
//let data = (track, tracks);
//cache.write().unwrap().trks.update(Some(data), rewrite!(buf, "{}/{}", data.0, data.1));
//cache.read().unwrap().trks.view.clone()
//}
//pub fn scene_add (cache: &Arc<RwLock<Self>>, scene: usize, scenes: usize, is_editing: bool)
//-> impl Content<TuiOut>
//{
//let data = (scene, scenes);
//cache.write().unwrap().scns.update(Some(data), rewrite!(buf, "({}/{})", data.0, data.1));
//button_3("S", "add scene", cache.read().unwrap().scns.view.clone(), is_editing)
//}
//pub fn view_h2 (&self) -> impl Content<TuiOut> {
//let cache = self.project.clock.view_cache.clone();
//let cache = cache.read().unwrap();
//add(&Fixed::x(15, Align::w(Bsp::s(
//FieldH(theme, "Beat", cache.beat.view.clone()),
//FieldH(theme, "Time", cache.time.view.clone()),
//))));
//add(&Fixed::x(13, Align::w(Bsp::s(
//Fill::X(Align::w(FieldH(theme, "BPM", cache.bpm.view.clone()))),
//Fill::X(Align::w(FieldH(theme, "SR ", cache.sr.view.clone()))),
//))));
//add(&Fixed::x(12, Align::w(Bsp::s(
//Fill::X(Align::w(FieldH(theme, "Buf", cache.buf.view.clone()))),
//Fill::X(Align::w(FieldH(theme, "Lat", cache.lat.view.clone()))),
//))));
//add(&Bsp::s(
//Fill::X(Align::w(FieldH(theme, "Selected", Align::w(self.selection().describe(
//self.tracks(),
//self.scenes()
//))))),
//Fill::X(Align::w(FieldH(theme, format!("History ({})", self.history.len()),
//self.history.last().map(|last|Fill::X(Align::w(format!("{:?}", last.0)))))))
//));
////if let Some(last) = self.history.last() {
////add(&FieldV(theme, format!("History ({})", self.history.len()),
////Fill::X(Align::w(format!("{:?}", last.0)))));
////}
//}
/////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////
//pub fn view_nil (_: &App) -> TuiCb { //pub fn view_nil (_: &App) -> TuiCb {
@ -1137,3 +1183,6 @@
//cols //cols
//Thunk::new(|to: &mut TuiOut|{ //Thunk::new(|to: &mut TuiOut|{
//}) //})
//take!(ClipCommand |state: Arrangement, iter|state.selected_clip().as_ref()
//.map(|t|Take::take(t, iter)).transpose().map(|x|x.flatten()));

View file

@ -19,17 +19,23 @@ mod app {
impl_has!(Clock: |self: App|self.project.clock); impl_has!(Clock: |self: App|self.project.clock);
impl_has!(Vec<MidiInput>: |self: App|self.project.midi_ins); impl_has!(Vec<MidiInput>: |self: App|self.project.midi_ins);
impl_has!(Vec<MidiOutput>: |self: App|self.project.midi_outs); impl_has!(Vec<MidiOutput>: |self: App|self.project.midi_outs);
impl_as_ref_opt!(MidiEditor: |self: App|self.project.as_ref_opt());
impl_as_mut_opt!(MidiEditor: |self: App|self.project.as_mut_opt());
impl_has!(Dialog: |self: App|self.dialog); impl_has!(Dialog: |self: App|self.dialog);
impl_has!(Jack<'static>: |self: App|self.jack); impl_has!(Jack<'static>: |self: App|self.jack);
impl_has!(Measure<TuiOut>: |self: App|self.size); impl_has!(Measure<TuiOut>: |self: App|self.size);
impl_has!(Pool: |self: App|self.pool); impl_has!(Pool: |self: App|self.pool);
impl_has!(Selection: |self: App|self.project.selection); impl_has!(Selection: |self: App|self.project.selection);
has_clips!( |self: App|self.pool.clips);
impl_audio!(App: tek_jack_process, tek_jack_event);
impl_as_ref!(Vec<Scene>: |self: App|self.project.as_ref()); impl_as_ref!(Vec<Scene>: |self: App|self.project.as_ref());
impl_as_mut!(Vec<Scene>: |self: App|self.project.as_mut()); impl_as_mut!(Vec<Scene>: |self: App|self.project.as_mut());
impl_as_ref_opt!(MidiEditor: |self: App|self.project.as_ref_opt());
impl_as_mut_opt!(MidiEditor: |self: App|self.project.as_mut_opt());
has_clips!( |self: App|self.pool.clips);
impl_audio!(App: tek_jack_process, tek_jack_event);
handle!(TuiIn: |self: App, input|{
let commands = collect_commands(self, input)?;
let history = execute_commands(self, commands)?;
self.history.extend(history.into_iter());
Ok(None)
});
impl Draw<TuiOut> for App { impl Draw<TuiOut> for App {
fn draw (&self, to: &mut TuiOut) { fn draw (&self, to: &mut TuiOut) {
@ -45,12 +51,6 @@ mod app {
} }
} }
handle!(TuiIn: |self: App, input|{
let commands = collect_commands(self, input)?;
let history = execute_commands(self, commands)?;
self.history.extend(history.into_iter());
Ok(None)
});
impl<'a> Namespace<'a, AppCommand> for App { impl<'a> Namespace<'a, AppCommand> for App {
symbols!('a |app| -> AppCommand { symbols!('a |app| -> AppCommand {
@ -312,27 +312,18 @@ mod app {
mod arrange { mod arrange {
use crate::*; use crate::*;
impl_has!(Jack<'static>: |self: Arrangement| self.jack); impl_has!(Jack<'static>: |self: Arrangement| self.jack);
impl_has!(Measure<TuiOut>: |self: Arrangement| self.size); impl_has!(Measure<TuiOut>: |self: Arrangement| self.size);
impl_has!(Vec<Track>: |self: Arrangement| self.tracks); impl_has!(Vec<Track>: |self: Arrangement| self.tracks);
impl_has!(Vec<Scene>: |self: Arrangement| self.scenes); impl_has!(Vec<Scene>: |self: Arrangement| self.scenes);
#[cfg(feature = "port")] impl_has!(Vec<MidiInput>: |self: Arrangement| self.midi_ins); impl_has!(Vec<MidiInput>: |self: Arrangement| self.midi_ins);
#[cfg(feature = "port")] impl_has!(Vec<MidiOutput>: |self: Arrangement| self.midi_outs); impl_has!(Vec<MidiOutput>: |self: Arrangement| self.midi_outs);
#[cfg(feature = "clock")] impl_has!(Clock: |self: Arrangement| self.clock); impl_has!(Clock: |self: Arrangement| self.clock);
#[cfg(feature = "select")] impl_has!(Selection: |self: Arrangement| self.selection); impl_has!(Selection: |self: Arrangement| self.selection);
#[cfg(feature = "select")] impl_as_ref_opt!(MidiEditor: |self: Arrangement| self.editor.as_ref()); impl_as_ref_opt!(MidiEditor: |self: Arrangement| self.editor.as_ref());
#[cfg(feature = "select")] impl_as_mut_opt!(MidiEditor: |self: Arrangement| self.editor.as_mut()); impl_as_mut_opt!(MidiEditor: |self: Arrangement| self.editor.as_mut());
#[cfg(feature = "select")] impl_as_ref_opt!(Track: |self: Arrangement| self.selected_track()); impl_as_ref_opt!(Track: |self: Arrangement| self.selected_track());
#[cfg(feature = "select")] impl_as_mut_opt!(Track: |self: Arrangement| self.selected_track_mut()); impl_as_mut_opt!(Track: |self: Arrangement| self.selected_track_mut());
#[cfg(feature = "select")] impl Arrangement {
#[cfg(feature = "port")] fn selected_midi_in (&self) -> Option<MidiInput> { todo!() }
#[cfg(feature = "port")] fn selected_midi_out (&self) -> Option<MidiOutput> { todo!() }
fn selected_device (&self) -> Option<Device> { todo!() }
fn unselect (&self) -> Selection { Selection::Nothing }
}
impl Arrangement { impl Arrangement {
/// Create a new arrangement. /// Create a new arrangement.
pub fn new ( pub fn new (
@ -551,8 +542,7 @@ mod arrange {
self.selected_track_mut()?.sampler_mut(0) self.selected_track_mut()?.sampler_mut(0)
} }
} }
impl ScenesView for Arrangement {
#[cfg(feature = "scene")] impl ScenesView for Arrangement {
fn h_scenes (&self) -> u16 { fn h_scenes (&self) -> u16 {
(self.measure_height() as u16).saturating_sub(20) (self.measure_height() as u16).saturating_sub(20)
} }
@ -563,7 +553,6 @@ mod arrange {
(self.measure_width() as u16).saturating_sub(2 * self.w_side()).max(40) (self.measure_width() as u16).saturating_sub(2 * self.w_side()).max(40)
} }
} }
impl HasClipsSize for Arrangement { impl HasClipsSize for Arrangement {
fn clips_size (&self) -> &Measure<TuiOut> { &self.size_inner } fn clips_size (&self) -> &Measure<TuiOut> { &self.size_inner }
} }
@ -571,21 +560,7 @@ mod arrange {
mod browse { mod browse {
use crate::*; use crate::*;
impl PartialEq for BrowseTarget {
fn eq (&self, other: &Self) -> bool {
match self {
Self::ImportSample(_) => false,
Self::ExportSample(_) => false,
Self::ImportClip(_) => false,
Self::ExportClip(_) => false,
#[allow(unused)] t => matches!(other, t)
}
}
}
impl Browse { impl Browse {
pub fn new (cwd: Option<PathBuf>) -> Usually<Self> { pub fn new (cwd: Option<PathBuf>) -> Usually<Self> {
let cwd = if let Some(cwd) = cwd { cwd } else { std::env::current_dir()? }; let cwd = if let Some(cwd) = cwd { cwd } else { std::env::current_dir()? };
let mut dirs = vec![]; let mut dirs = vec![];
@ -603,19 +578,10 @@ mod browse {
} }
Ok(Self { cwd, dirs, files, ..Default::default() }) Ok(Self { cwd, dirs, files, ..Default::default() })
} }
pub fn chdir (&self) -> Usually<Self> { Self::new(Some(self.path())) }
pub fn len (&self) -> usize { pub fn len (&self) -> usize { self.dirs.len() + self.files.len() }
self.dirs.len() + self.files.len() pub fn is_dir (&self) -> bool { self.index < self.dirs.len() }
} pub fn is_file (&self) -> bool { self.index >= self.dirs.len() }
pub fn is_dir (&self) -> bool {
self.index < self.dirs.len()
}
pub fn is_file (&self) -> bool {
self.index >= self.dirs.len()
}
pub fn path (&self) -> PathBuf { pub fn path (&self) -> PathBuf {
self.cwd.join(if self.is_dir() { self.cwd.join(if self.is_dir() {
&self.dirs[self.index].0 &self.dirs[self.index].0
@ -625,22 +591,10 @@ mod browse {
unreachable!() unreachable!()
}) })
} }
fn _todo_stub_path_buf (&self) -> PathBuf { todo!() }
pub fn chdir (&self) -> Usually<Self> { fn _todo_stub_usize (&self) -> usize { todo!() }
Self::new(Some(self.path())) fn _todo_stub_arc_str (&self) -> Arc<str> { todo!() }
} }
fn _todo_stub_path_buf (&self) -> PathBuf {
todo!()
}
fn _todo_stub_usize (&self) -> usize {
todo!()
}
fn _todo_stub_arc_str (&self) -> Arc<str> {
todo!()
}
}
impl HasContent<TuiOut> for Browse { impl HasContent<TuiOut> for Browse {
fn content (&self) -> impl Content<TuiOut> { fn content (&self) -> impl Content<TuiOut> {
Map::south(1, ||EntriesIterator { Map::south(1, ||EntriesIterator {
@ -651,7 +605,6 @@ mod browse {
}, |entry, _index|Fill::X(Align::w(entry))) }, |entry, _index|Fill::X(Align::w(entry)))
} }
} }
impl<'a> Iterator for EntriesIterator<'a> { impl<'a> Iterator for EntriesIterator<'a> {
type Item = Modify<&'a str>; type Item = Modify<&'a str>;
fn next (&mut self) -> Option<Self::Item> { fn next (&mut self) -> Option<Self::Item> {
@ -669,11 +622,21 @@ mod browse {
} }
} }
} }
impl PartialEq for BrowseTarget {
fn eq (&self, other: &Self) -> bool {
match self {
Self::ImportSample(_) => false,
Self::ExportSample(_) => false,
Self::ImportClip(_) => false,
Self::ExportClip(_) => false,
#[allow(unused)] t => matches!(other, t)
}
}
}
} }
//take!(ClipCommand |state: Arrangement, iter|state.selected_clip().as_ref()
//.map(|t|Take::take(t, iter)).transpose().map(|x|x.flatten()));
mod clock {
use crate::*;
impl std::fmt::Debug for Clock { impl std::fmt::Debug for Clock {
fn fmt (&self, f: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> { fn fmt (&self, f: &mut Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
f.debug_struct("Clock") f.debug_struct("Clock")
@ -687,7 +650,6 @@ impl std::fmt::Debug for Clock {
.finish() .finish()
} }
} }
impl Clock { impl Clock {
pub fn new (jack: &Jack<'static>, bpm: Option<f64>) -> Usually<Self> { pub fn new (jack: &Jack<'static>, bpm: Option<f64>) -> Usually<Self> {
let (chunk, transport) = jack.with_client(|c|(c.buffer_size(), c.transport())); let (chunk, transport) = jack.with_client(|c|(c.buffer_size(), c.transport()));
@ -846,7 +808,6 @@ impl Clock {
self.timebase().pulses_between_samples(offset, offset + scope.n_frames() as usize) self.timebase().pulses_between_samples(offset, offset + scope.n_frames() as usize)
} }
} }
impl Clock { impl Clock {
fn _todo_provide_u32 (&self) -> u32 { fn _todo_provide_u32 (&self) -> u32 {
todo!() todo!()
@ -858,35 +819,15 @@ impl Clock {
todo!() todo!()
} }
} }
impl<T: HasClock> Command<T> for ClockCommand { impl<T: HasClock> Command<T> for ClockCommand {
fn execute (&self, state: &mut T) -> Perhaps<Self> { fn execute (&self, state: &mut T) -> Perhaps<Self> {
self.execute(state.clock_mut()) // awesome self.execute(state.clock_mut()) // awesome
} }
} }
impl ClockView { impl ClockView {
pub const BEAT_EMPTY: &'static str = "-.-.--"; pub const BEAT_EMPTY: &'static str = "-.-.--";
pub const TIME_EMPTY: &'static str = "-.---s"; pub const TIME_EMPTY: &'static str = "-.---s";
pub const BPM_EMPTY: &'static str = "---.---"; pub const BPM_EMPTY: &'static str = "---.---";
//pub fn track_counter (cache: &Arc<RwLock<Self>>, track: usize, tracks: usize)
//-> Arc<RwLock<String>>
//{
//let data = (track, tracks);
//cache.write().unwrap().trks.update(Some(data), rewrite!(buf, "{}/{}", data.0, data.1));
//cache.read().unwrap().trks.view.clone()
//}
//pub fn scene_add (cache: &Arc<RwLock<Self>>, scene: usize, scenes: usize, is_editing: bool)
//-> impl Content<TuiOut>
//{
//let data = (scene, scenes);
//cache.write().unwrap().scns.update(Some(data), rewrite!(buf, "({}/{})", data.0, data.1));
//button_3("S", "add scene", cache.read().unwrap().scns.view.clone(), is_editing)
//}
pub fn update_clock (cache: &Arc<RwLock<Self>>, clock: &Clock, compact: bool) { pub fn update_clock (cache: &Arc<RwLock<Self>>, clock: &Clock, compact: bool) {
let rate = clock.timebase.sr.get(); let rate = clock.timebase.sr.get();
let chunk = clock.chunk.load(Relaxed) as f64; let chunk = clock.chunk.load(Relaxed) as f64;
@ -919,35 +860,23 @@ impl ClockView {
cache.bpm.update(None, rewrite!(buf, "{}", ClockView::BPM_EMPTY)); cache.bpm.update(None, rewrite!(buf, "{}", ClockView::BPM_EMPTY));
} }
} }
}
//pub fn view_h2 (&self) -> impl Content<TuiOut> { impl_default!(ClockView: {
//let cache = self.project.clock.view_cache.clone(); let mut beat = String::with_capacity(16);
//let cache = cache.read().unwrap(); let _ = write!(beat, "{}", Self::BEAT_EMPTY);
//add(&Fixed::x(15, Align::w(Bsp::s( let mut time = String::with_capacity(16);
//FieldH(theme, "Beat", cache.beat.view.clone()), let _ = write!(time, "{}", Self::TIME_EMPTY);
//FieldH(theme, "Time", cache.time.view.clone()), let mut bpm = String::with_capacity(16);
//)))); let _ = write!(bpm, "{}", Self::BPM_EMPTY);
//add(&Fixed::x(13, Align::w(Bsp::s( Self {
//Fill::X(Align::w(FieldH(theme, "BPM", cache.bpm.view.clone()))), beat: Memo::new(None, beat),
//Fill::X(Align::w(FieldH(theme, "SR ", cache.sr.view.clone()))), time: Memo::new(None, time),
//)))); bpm: Memo::new(None, bpm),
//add(&Fixed::x(12, Align::w(Bsp::s( sr: Memo::new(None, String::with_capacity(16)),
//Fill::X(Align::w(FieldH(theme, "Buf", cache.buf.view.clone()))), buf: Memo::new(None, String::with_capacity(16)),
//Fill::X(Align::w(FieldH(theme, "Lat", cache.lat.view.clone()))), lat: Memo::new(None, String::with_capacity(16)),
//)))); }
//add(&Bsp::s( });
//Fill::X(Align::w(FieldH(theme, "Selected", Align::w(self.selection().describe(
//self.tracks(),
//self.scenes()
//))))),
//Fill::X(Align::w(FieldH(theme, format!("History ({})", self.history.len()),
//self.history.last().map(|last|Fill::X(Align::w(format!("{:?}", last.0)))))))
//));
////if let Some(last) = self.history.last() {
////add(&FieldV(theme, format!("History ({})", self.history.len()),
////Fill::X(Align::w(format!("{:?}", last.0)))));
////}
//}
} }
impl Connect { impl Connect {
@ -1114,55 +1043,10 @@ impl<C: Default> Default for Binding<C> {
} }
} }
} }
impl Default for AppCommand { fn default () -> Self { Self::Nop } }
impl Default for MenuItem { fn default () -> Self { Self("".into(), Arc::new(Box::new(|_|Ok(())))) } } impl_default!(AppCommand: Self::Nop);
impl Default for Timebase { fn default () -> Self { Self::new(48000f64, 150f64, DEFAULT_PPQ) } } impl_default!(MenuItem: Self("".into(), Arc::new(Box::new(|_|Ok(())))));
impl Default for MidiEditor { fn default () -> Self { Self { size: Measure::new(0, 0), mode: PianoHorizontal::new(None) } } } impl_default!(Timebase: Self::new(48000f64, 150f64, DEFAULT_PPQ));
impl Default for OctaveVertical {
fn default () -> Self {
Self { on: [false; 12], colors: [Rgb(255,255,255), Rgb(0,0,0), Rgb(255,0,0)] }
}
}
impl Default for MidiCursor {
fn default () -> Self {
Self {
time_pos: Arc::new(0.into()),
note_pos: Arc::new(36.into()),
note_len: Arc::new(24.into()),
}
}
}
impl Default for ClockView {
fn default () -> Self {
let mut beat = String::with_capacity(16);
let _ = write!(beat, "{}", Self::BEAT_EMPTY);
let mut time = String::with_capacity(16);
let _ = write!(time, "{}", Self::TIME_EMPTY);
let mut bpm = String::with_capacity(16);
let _ = write!(bpm, "{}", Self::BPM_EMPTY);
Self {
beat: Memo::new(None, beat),
time: Memo::new(None, time),
bpm: Memo::new(None, bpm),
sr: Memo::new(None, String::with_capacity(16)),
buf: Memo::new(None, String::with_capacity(16)),
lat: Memo::new(None, String::with_capacity(16)),
}
}
}
impl Default for Pool {
fn default () -> Self {
//use PoolMode::*;
Self {
clip: 0.into(),
mode: None,
visible: true,
#[cfg(feature = "clip")] clips: Arc::from(RwLock::from(vec![])),
#[cfg(feature = "sampler")] samples: Arc::from(RwLock::from(vec![])),
#[cfg(feature = "browse")] browse: None,
}
}
}
impl Gettable<bool> for AtomicBool { fn get (&self) -> bool { self.load(Relaxed) } } impl Gettable<bool> for AtomicBool { fn get (&self) -> bool { self.load(Relaxed) } }
impl InteriorMutable<bool> for AtomicBool { fn set (&self, value: bool) -> bool { self.swap(value, Relaxed) } } impl InteriorMutable<bool> for AtomicBool { fn set (&self, value: bool) -> bool { self.swap(value, Relaxed) } }
@ -1549,6 +1433,11 @@ mod midi {
time_zoom: Arc::new(data.0.into()), time_zoom: Arc::new(data.0.into()),
time_lock: Arc::new(data.1.into()), time_lock: Arc::new(data.1.into()),
}); });
impl_default!(MidiCursor: Self {
time_pos: Arc::new(0.into()),
note_pos: Arc::new(36.into()),
note_len: Arc::new(24.into()),
});
impl NotePoint for MidiCursor { impl NotePoint for MidiCursor {
fn note_len (&self) -> &AtomicUsize { fn note_len (&self) -> &AtomicUsize {
@ -2104,20 +1993,17 @@ mod audio {
#[cfg(feature = "sequencer")] mod sequencer { #[cfg(feature = "sequencer")] mod sequencer {
use crate::*; use crate::*;
impl_has!(Sequencer: |self: Track| self.sequencer); impl_has!(Sequencer: |self: Track| self.sequencer);
#[cfg(feature = "clock")] impl_has!(Clock: |self: Sequencer|self.clock); impl_has!(Clock: |self: Sequencer| self.clock);
#[cfg(feature = "port")] impl_has!(Vec<MidiInput>: |self: Sequencer|self.midi_ins); impl_has!(Vec<MidiInput>: |self: Sequencer| self.midi_ins);
#[cfg(feature = "port")] impl_has!(Vec<MidiOutput>: |self: Sequencer|self.midi_outs); impl_has!(Vec<MidiOutput>: |self: Sequencer| self.midi_outs);
impl_has!(Measure<TuiOut>: |self: MidiEditor| self.size); impl_has!(Measure<TuiOut>: |self: MidiEditor| self.size);
impl_has!(Measure<TuiOut>: |self: PianoHorizontal| self.size); impl_has!(Measure<TuiOut>: |self: PianoHorizontal| self.size);
impl Default for Sequencer { impl_default!(Sequencer: Self {
fn default () -> Self { clock: Clock::default(),
Self { play_clip: None,
#[cfg(feature = "clock")] clock: Clock::default(), next_clip: None,
#[cfg(feature = "clip")] play_clip: None, midi_ins: vec![],
#[cfg(feature = "clip")] next_clip: None, midi_outs: vec![],
#[cfg(feature = "port")] midi_ins: vec![],
#[cfg(feature = "port")] midi_outs: vec![],
recording: false, recording: false,
monitoring: true, monitoring: true,
overdub: false, overdub: false,
@ -2126,9 +2012,7 @@ mod audio {
note_buf: vec![0;8], note_buf: vec![0;8],
midi_buf: vec![], midi_buf: vec![],
reset: true, reset: true,
} });
}
}
impl Sequencer { impl Sequencer {
pub fn new ( pub fn new (
name: impl AsRef<str>, name: impl AsRef<str>,
@ -2355,6 +2239,12 @@ mod audio {
model.redraw(); model.redraw();
model model
}); });
impl_default!(MidiEditor: Self {
size: Measure::new(0, 0), mode: PianoHorizontal::new(None)
});
impl_default!(OctaveVertical: Self {
on: [false; 12], colors: [Rgb(255,255,255), Rgb(0,0,0), Rgb(255,0,0)]
});
impl MidiEditor { impl MidiEditor {
/// Put note at current position /// Put note at current position
pub fn put_note (&mut self, advance: bool) { pub fn put_note (&mut self, advance: bool) {
@ -3494,6 +3384,14 @@ mod pool {
model.clip.store(1, Relaxed); model.clip.store(1, Relaxed);
model model
}); });
impl_default!(Pool: Self {
browse: None,
clip: 0.into(),
clips: Arc::from(RwLock::from(vec![])),
mode: None,
samples: Arc::from(RwLock::from(vec![])),
visible: true,
});
impl Pool { impl Pool {
pub fn clip_index (&self) -> usize { pub fn clip_index (&self) -> usize {
self.clip.load(Relaxed) self.clip.load(Relaxed)

2
tengri

@ -1 +1 @@
Subproject commit d1c08df5351ce8c3913723602a05268d593c9a45 Subproject commit f1dda6af07b94928481d062c3d3fda5b9e969633