wip: running interface in separate or combined mode

also disassociating render functions from state structs
This commit is contained in:
🪞👃🪞 2024-05-28 22:13:20 +03:00
parent f9218e887a
commit d6bf840a1f
31 changed files with 905 additions and 532 deletions

View file

@ -5,43 +5,146 @@ extern crate crossterm;
use clap::{Parser, Subcommand};
use std::error::Error;
//pub mod sequence;
pub mod cli;
pub mod prelude;
pub mod engine;
pub mod transport;
pub mod mixer;
pub mod looper;
pub mod sampler;
pub mod sequencer;
pub mod render;
use crate::prelude::*;
fn main () -> Result<(), Box<dyn Error>> {
let cli = Cli::parse();
match cli.command {
Command::Transport =>
crate::transport::Transport::run_tui(),
Command::Mixer =>
crate::mixer::Mixer::run_tui(),
Command::Looper =>
crate::looper::Looper::run_tui(),
Command::Sampler =>
crate::sampler::Sampler::run_tui(),
let cli = cli::Cli::parse();
if let Some(command) = cli.command {
match command {
cli::Command::Transport => main_loop(
&mut transport::Transport::new()?,
transport::render
),
cli::Command::Mixer => main_loop(
&mut mixer::Mixer::new()?,
mixer::render
),
cli::Command::Looper => main_loop(
&mut looper::Looper::new()?,
looper::render
),
cli::Command::Sampler => main_loop(
&mut sampler::Sampler::new()?,
sampler::render
),
cli::Command::Sequencer => main_loop(
&mut sequencer::Sequencer::new()?,
sequencer::render
),
}
} else {
main_loop(&mut (
transport::Transport::new()?,
mixer::Mixer::new()?,
looper::Looper::new()?,
sampler::Sampler::new()?,
sequencer::Sequencer::new()?,
), |(transport, mixer, looper, sampler, sequencer), stdout, offset| {
transport::render(transport, stdout, (1, 1))?;
render::render_box(stdout, 28, 0, 60, 6, false)?;
mixer::render(mixer, stdout, (1, 10))?;
render::render_box(stdout, 18, 9, 62, 9, false)?;
looper::render(looper, stdout, (1, 20))?;
render::render_box(stdout, 17, 19, 50, 6, false)?;
//sampler::render(sampler, stdout, (1, 46))?;
//sequencer::render(sequencer, stdout, (1, 66))?;
Ok(())
})
}
}
#[derive(Debug, Parser)]
#[command(version, about, long_about = None)]
pub struct Cli {
#[command(subcommand)]
command: Command
pub fn main_loop <T> (
state: &mut T,
mut render: impl FnMut(&mut T, &mut Stdout, (u16, u16)) -> Result<(), Box<dyn Error>>
) -> Result<(), Box<dyn Error>> {
let sleep = std::time::Duration::from_millis(16);
let mut stdout = std::io::stdout();
loop {
stdout.queue(Clear(ClearType::All))?.queue(Hide)?;
render(state, &mut stdout, (0, 0))?;
stdout.flush()?;
std::thread::sleep(sleep);
}
}
#[derive(Debug, Clone, Subcommand)]
pub enum Command {
/// Control the master transport
Transport,
/// Control the mixer
Mixer,
/// Control the looper
Looper,
/// Control the sampler
Sampler,
}
//pub fn run_tui () -> Result<(), Box<dyn Error>> {
//let mut stdout = stdout();
//let mut app = Mixer::new()?;
//let sleep = std::time::Duration::from_millis(16);
//crossterm::terminal::enable_raw_mode()?;
//let (tx, input) = channel::<crossterm::event::Event>();
//let exited = Arc::new(AtomicBool::new(false));
//let exit_input_thread = exited.clone();
//spawn(move || {
//loop {
//// Exit if flag is set
//if exit_input_thread.fetch_and(true, Ordering::Relaxed) {
//break
//}
//// Listen for events and send them to the main thread
//if crossterm::event::poll(Duration::from_millis(100)).is_ok() {
//if tx.send(crossterm::event::read().unwrap()).is_err() {
//break
//}
//}
//}
//});
//loop {
//render(&mut app, &mut stdout, (0, 0))?;
//handle(&mut app, input.recv()?)?;
//if app.exit {
//app.stdout.queue(cursor::Show)?.flush()?;
//crossterm::terminal::disable_raw_mode()?;
//break
//}
//}
//Ok(())
//}
//pub fn run_tui () -> Result<(), Box<dyn Error>> {
//let mut app = Self::new()?;
//let mut stdout = std::io::stdout();
//let sleep = std::time::Duration::from_millis(16);
//crossterm::terminal::enable_raw_mode()?;
//let (tx, input) = channel::<crossterm::event::Event>();
//let exited = Arc::new(AtomicBool::new(false));
//// Spawn the input thread
//let exit_input_thread = exited.clone();
//spawn(move || {
//loop {
//// Exit if flag is set
//if exit_input_thread.fetch_and(true, Ordering::Relaxed) {
//break
//}
//// Listen for events and send them to the main thread
//if crossterm::event::poll(Duration::from_millis(100)).is_ok() {
//if tx.send(crossterm::event::read().unwrap()).is_err() {
//break
//}
//}
//}
//});
//loop {
//use crossterm::{*, terminal::{Clear, ClearType}, cursor::Hide};
//stdout.queue(Clear(ClearType::All))?.queue(Hide)?;
//render(&mut app, &mut stdout, (0, 0))?;
//stdout.flush()?;
//handle(&mut app, input.recv()?)?;
//if app.exit {
//stdout.queue(cursor::Hide)?.flush()?;
//crossterm::terminal::disable_raw_mode()?;
//break
//}
//}
//Ok(())
//}