chore: tidy

This commit is contained in:
🪞👃🪞 2024-06-29 05:39:52 +03:00
parent 1b7892d11f
commit f48f17e9a4
8 changed files with 66 additions and 73 deletions

View file

@ -4,8 +4,6 @@ mod chain;
mod launcher;
mod looper;
mod mixer;
mod plugin;
mod sampler;
mod sequencer;
mod track;
mod transport;
@ -13,26 +11,31 @@ mod transport;
pub use self::track::Track;
pub use self::launcher::{Launcher, Scene};
pub use self::sequencer::{Sequencer, Phrase};
pub use self::chain::Chain;
pub use self::plugin::Plugin;
pub use self::chain::{Chain, Sampler, Plugin};
pub use self::looper::Looper;
pub use self::mixer::Mixer;
pub use self::sampler::Sampler;
pub use self::transport::Transport;
use crossterm::event;
use ::jack::{Port, PortSpec, Client};
/// A UI component that may have presence on the JACK grap.
pub trait Device: Render + Handle + PortList + Send + Sync {
fn boxed (self) -> Box<dyn Device> where Self: Sized + 'static {
Box::new(self)
}
}
/// All things that implement the required traits can be treated as `Device`.
impl<T: Render + Handle + PortList + Send + Sync> Device for T {}
/// Run a device as the root of the app.
pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box<dyn Error>> {
let device = Arc::new(Mutex::new(device));
let exited = Arc::new(AtomicBool::new(false));
// Spawn input (handle) thread
let _input_thread = {
let poll = std::time::Duration::from_millis(100);
let exited = exited.clone();
@ -60,25 +63,23 @@ pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box<dyn E
}
})
};
// Set up terminal
stdout().execute(EnterAlternateScreen)?;
enable_raw_mode()?;
let mut terminal = ratatui::Terminal::new(CrosstermBackend::new(stdout()))?;
//better_panic::install();
// Set up panic hook
let better_panic_handler = better_panic::Settings::auto()
.verbosity(better_panic::Verbosity::Full)
.create_panic_handler();
std::panic::set_hook(Box::new(move |info: &std::panic::PanicInfo|{
stdout()
.execute(crossterm::terminal::LeaveAlternateScreen)
.unwrap();
crossterm::terminal::disable_raw_mode()
.unwrap();
stdout().execute(LeaveAlternateScreen).unwrap();
crossterm::terminal::disable_raw_mode().unwrap();
better_panic_handler(info);
//writeln!(std::io::stderr(), "{}", info)
//.unwrap();
//writeln!(std::io::stderr(), "{:?}", ::backtrace::Backtrace::new())
//.unwrap();
}));
// Main (render) loop
let sleep = std::time::Duration::from_millis(16);
loop {
terminal.draw(|frame|{
@ -91,28 +92,41 @@ pub fn run (device: impl Device + Send + Sync + 'static) -> Result<(), Box<dyn E
}
std::thread::sleep(sleep);
};
//render_thread.join().expect("Failed to join render thread");
stdout()
.queue(crossterm::terminal::LeaveAlternateScreen)?
.flush()?;
// Cleanup
stdout().execute(LeaveAlternateScreen)?;
crossterm::terminal::disable_raw_mode()?;
Ok(())
}
impl<T: Render + Handle + PortList + Send + Sync> Device for T {}
pub trait Named {
}
/// Trait for things that handle input events.
pub trait Handle {
// Handle an input event.
// Returns Ok(true) if the device handled the event.
// This is the mechanism which allows nesting of components;.
/// Handle an input event.
/// Returns Ok(true) if the device handled the event.
/// This is the mechanism which allows nesting of components;.
fn handle (&mut self, _e: &AppEvent) -> Usually<bool> {
Ok(false)
}
}
#[derive(Debug)]
pub enum AppEvent {
/// Terminal input
Input(::crossterm::event::Event),
/// Update values but not the whole form.
Update,
/// Update the whole form.
Redraw,
/// Device gains focus
Focus,
/// Device loses focus
Blur,
/// JACK notification
Jack(JackEvent)
}
/// Trait for things that render to the display.
pub trait Render {
// Render something to an area of the buffer.
// Returns area used by component.
@ -122,6 +136,24 @@ pub trait Render {
}
}
impl Render for Box<dyn Device> {
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
(**self).render(b, a)
}
}
impl WidgetRef for &dyn Render {
fn render_ref (&self, area: Rect, buf: &mut Buffer) {
Render::render(*self, buf, area).expect("Failed to render device.");
}
}
impl WidgetRef for dyn Render {
fn render_ref (&self, area: Rect, buf: &mut Buffer) {
Render::render(self, buf, area).expect("Failed to render device.");
}
}
pub trait Blit {
// Render something to X, Y coordinates in a buffer, ignoring width/height.
fn blit (&self, buf: &mut Buffer, x: u16, y: u16, style: Option<Style>);
@ -135,6 +167,7 @@ impl<T: AsRef<str>> Blit for T {
}
}
/// Trait for things that may expose JACK ports.
pub trait PortList {
fn audio_ins (&self) -> Usually<Vec<String>> {
Ok(vec![])
@ -163,12 +196,6 @@ pub trait PortList {
}
}
impl Render for Box<dyn Device> {
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
(**self).render(b, a)
}
}
pub struct DevicePort<T: PortSpec> {
pub name: String,
pub port: Port<T>,
@ -189,18 +216,7 @@ impl<T: PortSpec + Default> DevicePort<T> {
}
}
impl WidgetRef for &dyn Render {
fn render_ref (&self, area: Rect, buf: &mut Buffer) {
Render::render(*self, buf, area).expect("Failed to render device.");
}
}
impl WidgetRef for dyn Render {
fn render_ref (&self, area: Rect, buf: &mut Buffer) {
Render::render(self, buf, area).expect("Failed to render device.");
}
}
/// A device dynamicammy composed of state and handlers.
pub struct DynamicDevice<T> {
pub state: Arc<Mutex<T>>,
pub render: Mutex<Box<dyn FnMut(&T, &mut Buffer, Rect)->Usually<Rect> + Send>>,
@ -279,34 +295,6 @@ impl<T: Send + Sync + 'static> DynamicDevice<T> {
}
}
#[derive(Debug)]
pub enum AppEvent {
/// Terminal input
Input(::crossterm::event::Event),
/// Update values but not the whole form.
Update,
/// Update the whole form.
Redraw,
/// Device gains focus
Focus,
/// Device loses focus
Blur,
/// JACK notification
Jack(JackEvent)
}
fn panic_hook (info: &std::panic::PanicInfo) {
stdout()
.execute(crossterm::terminal::LeaveAlternateScreen)
.unwrap();
crossterm::terminal::disable_raw_mode()
.unwrap();
writeln!(std::io::stderr(), "{}", info)
.unwrap();
writeln!(std::io::stderr(), "{:?}", ::backtrace::Backtrace::new())
.unwrap();
}
#[derive(Debug)]
pub enum JackEvent {
ThreadInit,

View file

@ -1,3 +1,8 @@
mod plugin;
pub use self::plugin::*;
mod sampler;
pub use self::sampler::*;
use crate::prelude::*;
pub struct Chain {

View file