mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-10 21:56:42 +01:00
render chain with SplitFocus
This commit is contained in:
parent
a39e694a3e
commit
c3040cef1c
12 changed files with 247 additions and 147 deletions
|
|
@ -1,5 +1,56 @@
|
|||
use crate::{core::*, model::App};
|
||||
|
||||
impl App {
|
||||
pub fn next_phrase (&mut self) {
|
||||
if let Some((track_index, track)) = self.track_mut() {
|
||||
let phrases = track.phrases.len();
|
||||
if let Some((_, scene)) = self.scene_mut() {
|
||||
if let Some(phrase_index) = scene.clips[track_index] {
|
||||
if phrase_index >= phrases - 1 {
|
||||
scene.clips[track_index] = None;
|
||||
} else {
|
||||
scene.clips[track_index] = Some(phrase_index + 1);
|
||||
}
|
||||
} else if phrases > 0 {
|
||||
scene.clips[track_index] = Some(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn prev_phrase (&mut self) {
|
||||
if let Some((track_index, track)) = self.track_mut() {
|
||||
let phrases = track.phrases.len();
|
||||
if let Some((_, scene)) = self.scene_mut() {
|
||||
if let Some(phrase_index) = scene.clips[track_index] {
|
||||
scene.clips[track_index] = if phrase_index == 0 {
|
||||
None
|
||||
} else {
|
||||
Some(phrase_index - 1)
|
||||
};
|
||||
} else if phrases > 0 {
|
||||
scene.clips[track_index] = Some(phrases - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn phrase (&self) -> Option<&Phrase> {
|
||||
let (track_id, track) = self.track()?;
|
||||
let (_, scene) = self.scene()?;
|
||||
track.phrases.get((*scene.clips.get(track_id)?)?)
|
||||
}
|
||||
pub fn phrase_mut (&mut self) -> Option<&mut Phrase> {
|
||||
let (track_id, _) = self.track()?;
|
||||
let (_, scene) = self.scene()?;
|
||||
let clip = (*scene.clips.get(track_id)?)?;
|
||||
self.track_mut()?.1.phrases.get_mut(clip)
|
||||
}
|
||||
fn phrase_id (&self) -> Option<usize> {
|
||||
let (track_id, _) = self.track()?;
|
||||
let (_, scene) = self.scene()?;
|
||||
*scene.clips.get(track_id)?
|
||||
}
|
||||
}
|
||||
|
||||
/// Define a MIDI phrase.
|
||||
#[macro_export] macro_rules! phrase {
|
||||
($($t:expr => $msg:expr),* $(,)?) => {{
|
||||
|
|
@ -87,22 +138,3 @@ impl Phrase {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn phrase (&self) -> Option<&Phrase> {
|
||||
let (track_id, track) = self.track()?;
|
||||
let (_, scene) = self.scene()?;
|
||||
track.phrases.get((*scene.clips.get(track_id)?)?)
|
||||
}
|
||||
pub fn phrase_mut (&mut self) -> Option<&mut Phrase> {
|
||||
let (track_id, _) = self.track()?;
|
||||
let (_, scene) = self.scene()?;
|
||||
let clip = (*scene.clips.get(track_id)?)?;
|
||||
self.track_mut()?.1.phrases.get_mut(clip)
|
||||
}
|
||||
pub fn phrase_id (&self) -> Option<usize> {
|
||||
let (track_id, _) = self.track()?;
|
||||
let (_, scene) = self.scene()?;
|
||||
*scene.clips.get(track_id)?
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,13 @@
|
|||
use crate::{core::*, model::App};
|
||||
|
||||
pub struct Scene {
|
||||
pub name: String,
|
||||
pub clips: Vec<Option<usize>>,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
pub fn new (name: impl AsRef<str>, clips: impl AsRef<[Option<usize>]>) -> Self {
|
||||
Self {
|
||||
name: name.as_ref().into(),
|
||||
clips: clips.as_ref().iter().map(|x|x.clone()).collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn new_scene_name (&self) -> String {
|
||||
pub fn next_scene (&mut self) {
|
||||
self.scene_cursor = self.scenes.len().min(self.scene_cursor + 1);
|
||||
}
|
||||
pub fn prev_scene (&mut self) {
|
||||
self.scene_cursor = self.scene_cursor.saturating_sub(1);
|
||||
}
|
||||
fn new_scene_name (&self) -> String {
|
||||
format!("Scene {}", self.scenes.len() + 1)
|
||||
}
|
||||
pub fn add_scene (&mut self, name: Option<&str>) -> Usually<&mut Scene> {
|
||||
|
|
@ -47,3 +39,17 @@ impl App {
|
|||
} }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Scene {
|
||||
pub name: String,
|
||||
pub clips: Vec<Option<usize>>,
|
||||
}
|
||||
|
||||
impl Scene {
|
||||
fn new (name: impl AsRef<str>, clips: impl AsRef<[Option<usize>]>) -> Self {
|
||||
Self {
|
||||
name: name.as_ref().into(),
|
||||
clips: clips.as_ref().iter().map(|x|x.clone()).collect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,52 @@
|
|||
use crate::core::*;
|
||||
use crate::model::*;
|
||||
|
||||
impl App {
|
||||
pub fn next_track (&mut self) {
|
||||
self.track_cursor = self.tracks.len().min(self.track_cursor + 1);
|
||||
}
|
||||
pub fn prev_track (&mut self) {
|
||||
self.track_cursor = self.track_cursor.saturating_sub(1);
|
||||
}
|
||||
|
||||
pub fn new_track_name (&self) -> String {
|
||||
format!("Track {}", self.tracks.len() + 1)
|
||||
}
|
||||
|
||||
pub fn add_track (&mut self, name: Option<&str>) -> Usually<&mut Track> {
|
||||
let name = name.ok_or_else(||self.new_track_name())?;
|
||||
self.tracks.push(Track::new(&name, None, None)?);
|
||||
self.track_cursor = self.tracks.len();
|
||||
Ok(&mut self.tracks[self.track_cursor - 1])
|
||||
}
|
||||
|
||||
fn add_track_with_cb (
|
||||
&mut self, name: Option<&str>, init: impl FnOnce(&Client, &mut Track)->Usually<()>,
|
||||
) -> Usually<&mut Track> {
|
||||
let name = name.ok_or_else(||self.new_track_name())?;
|
||||
let mut track = Track::new(&name, None, None)?;
|
||||
init(self.client(), &mut track)?;
|
||||
self.tracks.push(track);
|
||||
self.track_cursor = self.tracks.len();
|
||||
Ok(&mut self.tracks[self.track_cursor - 1])
|
||||
}
|
||||
|
||||
pub fn track (&self) -> Option<(usize, &Track)> {
|
||||
match self.track_cursor { 0 => None, _ => {
|
||||
let id = self.track_cursor as usize - 1;
|
||||
self.tracks.get(id).map(|t|(id, t))
|
||||
} }
|
||||
}
|
||||
|
||||
pub fn track_mut (&mut self) -> Option<(usize, &mut Track)> {
|
||||
match self.track_cursor { 0 => None, _ => {
|
||||
let id = self.track_cursor as usize - 1;
|
||||
self.tracks.get_mut(id).map(|t|(id, t))
|
||||
} }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub struct Track {
|
||||
pub name: String,
|
||||
/// Play input through output.
|
||||
|
|
@ -29,7 +75,7 @@ pub struct Track {
|
|||
pub notes_out: [bool;128],
|
||||
}
|
||||
impl Track {
|
||||
pub fn new (
|
||||
fn new (
|
||||
name: &str,
|
||||
phrases: Option<Vec<Phrase>>,
|
||||
devices: Option<Vec<JackDevice>>,
|
||||
|
|
@ -50,19 +96,19 @@ impl Track {
|
|||
reset: true,
|
||||
})
|
||||
}
|
||||
pub fn get_device (&self, i: usize) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
fn get_device (&self, i: usize) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
self.devices.get(i).map(|d|d.state.read().unwrap())
|
||||
}
|
||||
pub fn get_device_mut (&self, i: usize) -> Option<RwLockWriteGuard<Box<dyn Device>>> {
|
||||
fn get_device_mut (&self, i: usize) -> Option<RwLockWriteGuard<Box<dyn Device>>> {
|
||||
self.devices.get(i).map(|d|d.state.write().unwrap())
|
||||
}
|
||||
pub fn device (&self) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
fn device (&self) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
self.get_device(self.device)
|
||||
}
|
||||
pub fn device_mut (&self) -> Option<RwLockWriteGuard<Box<dyn Device>>> {
|
||||
self.get_device_mut(self.device)
|
||||
}
|
||||
pub fn first_device (&self) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
fn first_device (&self) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
self.get_device(0)
|
||||
}
|
||||
pub fn connect_first_device (&self) -> Usually<()> {
|
||||
|
|
@ -71,7 +117,7 @@ impl Track {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn last_device (&self) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
fn last_device (&self) -> Option<RwLockReadGuard<Box<dyn Device>>> {
|
||||
self.get_device(self.devices.len().saturating_sub(1))
|
||||
}
|
||||
pub fn connect_last_device (&self, app: &App) -> Usually<()> {
|
||||
|
|
@ -89,7 +135,7 @@ impl Track {
|
|||
let index = self.devices.len() - 1;
|
||||
Ok(&mut self.devices[index])
|
||||
}
|
||||
pub fn add_device_with_cb (
|
||||
fn add_device_with_cb (
|
||||
&mut self,
|
||||
mut device: JackDevice,
|
||||
init: impl Fn(&Self, &mut JackDevice)->Usually<()>
|
||||
|
|
@ -99,21 +145,21 @@ impl Track {
|
|||
let index = self.devices.len() - 1;
|
||||
Ok(&mut self.devices[index])
|
||||
}
|
||||
pub fn phrase (&self) -> Option<&Phrase> {
|
||||
fn phrase (&self) -> Option<&Phrase> {
|
||||
if let Some(phrase) = self.sequence {
|
||||
return self.phrases.get(phrase)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn phrase_mut (&mut self) -> Option<&mut Phrase> {
|
||||
fn phrase_mut (&mut self) -> Option<&mut Phrase> {
|
||||
if let Some(phrase) = self.sequence {
|
||||
return self.phrases.get_mut(phrase)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
pub fn add_phrase (
|
||||
fn add_phrase (
|
||||
&mut self, name: &str, length: usize, data: Option<PhraseData>
|
||||
) -> &mut Phrase {
|
||||
self.phrases.push(Phrase::new(name, length, data));
|
||||
|
|
@ -243,43 +289,3 @@ impl Track {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl App {
|
||||
|
||||
pub fn new_track_name (&self) -> String {
|
||||
format!("Track {}", self.tracks.len() + 1)
|
||||
}
|
||||
|
||||
pub fn add_track (&mut self, name: Option<&str>) -> Usually<&mut Track> {
|
||||
let name = name.ok_or_else(||self.new_track_name())?;
|
||||
self.tracks.push(Track::new(&name, None, None)?);
|
||||
self.track_cursor = self.tracks.len();
|
||||
Ok(&mut self.tracks[self.track_cursor - 1])
|
||||
}
|
||||
|
||||
pub fn add_track_with_cb (
|
||||
&mut self, name: Option<&str>, init: impl FnOnce(&Client, &mut Track)->Usually<()>,
|
||||
) -> Usually<&mut Track> {
|
||||
let name = name.ok_or_else(||self.new_track_name())?;
|
||||
let mut track = Track::new(&name, None, None)?;
|
||||
init(self.client(), &mut track)?;
|
||||
self.tracks.push(track);
|
||||
self.track_cursor = self.tracks.len();
|
||||
Ok(&mut self.tracks[self.track_cursor - 1])
|
||||
}
|
||||
|
||||
pub fn track (&self) -> Option<(usize, &Track)> {
|
||||
match self.track_cursor { 0 => None, _ => {
|
||||
let id = self.track_cursor as usize - 1;
|
||||
self.tracks.get(id).map(|t|(id, t))
|
||||
} }
|
||||
}
|
||||
|
||||
pub fn track_mut (&mut self) -> Option<(usize, &mut Track)> {
|
||||
match self.track_cursor { 0 => None, _ => {
|
||||
let id = self.track_cursor as usize - 1;
|
||||
self.tracks.get_mut(id).map(|t|(id, t))
|
||||
} }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue