mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-09 13:16:44 +01:00
placebo
This commit is contained in:
parent
3ae2467acc
commit
94c1f83ef2
13 changed files with 277 additions and 124 deletions
|
|
@ -16,7 +16,7 @@ pub struct DynamicDevice<T> {
|
|||
pub render: Mutex<Box<dyn FnMut(&T, &mut Buffer, Rect)->Usually<Rect> + Send>>,
|
||||
pub handle: Arc<Mutex<Box<dyn FnMut(&mut T, &AppEvent)->Usually<bool> + Send>>>,
|
||||
pub process: Arc<Mutex<Box<dyn FnMut(&mut T, &Client, &ProcessScope)->Control + Send>>>,
|
||||
pub client: Option<DynamicAsyncClient>
|
||||
pub client: Option<DynamicAsyncClient>
|
||||
}
|
||||
|
||||
impl<T> Handle for DynamicDevice<T> {
|
||||
|
|
@ -46,10 +46,6 @@ impl<T: PortList + Send + Sync + 'static> PortList for DynamicDevice<T> {
|
|||
}
|
||||
}
|
||||
|
||||
type DynamicAsyncClient = AsyncClient<DynamicNotifications, DynamicProcessHandler>;
|
||||
type DynamicNotifications = Notifications<Box<dyn Fn(AppEvent) + Send + Sync>>;
|
||||
type DynamicProcessHandler = ClosureProcessHandler<BoxedProcessHandler>;
|
||||
|
||||
impl<T: Send + Sync + 'static> DynamicDevice<T> {
|
||||
pub fn new <'a, R, H, P> (render: R, handle: H, process: P, state: T) -> Self where
|
||||
R: FnMut(&T, &mut Buffer, Rect) -> Usually<Rect> + Send + 'static,
|
||||
|
|
|
|||
|
|
@ -1,13 +1,37 @@
|
|||
use crate::core::*;
|
||||
|
||||
pub type BoxedNotificationHandler =
|
||||
Box<dyn Fn(AppEvent) + Send>;
|
||||
pub trait Process {
|
||||
fn process (&mut self, c: &Client, s: &ProcessScope) -> Control;
|
||||
}
|
||||
|
||||
pub type DynamicAsyncClient =
|
||||
AsyncClient<DynamicNotifications, DynamicProcessHandler>;
|
||||
|
||||
pub type DynamicNotifications =
|
||||
Notifications<Box<dyn Fn(AppEvent) + Send + Sync>>;
|
||||
|
||||
pub type DynamicProcessHandler =
|
||||
ClosureProcessHandler<BoxedProcessHandler>;
|
||||
|
||||
pub type BoxedProcessHandler =
|
||||
Box<dyn FnMut(&Client, &ProcessScope)-> Control + Send>;
|
||||
|
||||
pub type Jack<N> =
|
||||
AsyncClient<N, ClosureProcessHandler<BoxedProcessHandler>>;
|
||||
pub fn jack_run <T> (name: &str, app: &Arc<Mutex<T>>) -> Usually<DynamicAsyncClient>
|
||||
where T: Handle + Process + Send + 'static
|
||||
{
|
||||
let options = ClientOptions::NO_START_SERVER;
|
||||
let (client, _status) = Client::new(name, options)?;
|
||||
Ok(client.activate_async(
|
||||
Notifications(Box::new({
|
||||
let app = app.clone();
|
||||
move|event|{app.lock().unwrap().handle(&event).unwrap();}
|
||||
}) as Box<dyn Fn(AppEvent) + Send + Sync>),
|
||||
ClosureProcessHandler::new(Box::new({
|
||||
let app = app.clone();
|
||||
move|c: &Client, s: &ProcessScope|{app.lock().unwrap().process(c, s)}
|
||||
}) as BoxedProcessHandler)
|
||||
)?)
|
||||
}
|
||||
|
||||
pub use ::jack::{
|
||||
AsyncClient,
|
||||
|
|
|
|||
|
|
@ -1,33 +1,20 @@
|
|||
pub type Usually<T> = Result<T, Box<dyn Error>>;
|
||||
|
||||
macro_rules! submod {
|
||||
($($name:ident)*) => { $(mod $name; pub use self::$name::*;)* };
|
||||
}
|
||||
|
||||
submod!( device handle jack keymap port render run time );
|
||||
|
||||
pub use std::error::Error;
|
||||
pub use std::io::{stdout, Stdout, Write};
|
||||
pub use std::thread::{spawn, JoinHandle};
|
||||
pub use std::time::Duration;
|
||||
pub use std::collections::BTreeMap;
|
||||
pub use std::sync::{
|
||||
Arc, Mutex, MutexGuard,
|
||||
atomic::{Ordering, AtomicBool, AtomicUsize},
|
||||
mpsc::{self, channel, Sender, Receiver}
|
||||
};
|
||||
pub use std::sync::{Arc, Mutex, MutexGuard};
|
||||
pub use std::sync::atomic::{Ordering, AtomicBool, AtomicUsize};
|
||||
pub use std::sync::mpsc::{channel, Sender, Receiver};
|
||||
pub use ratatui::prelude::*;
|
||||
pub use midly::{MidiMessage, live::LiveEvent, num::u7};
|
||||
pub use crossterm::{ExecutableCommand, QueueableCommand};
|
||||
pub use crossterm::event::{Event, KeyEvent, KeyCode, KeyModifiers};
|
||||
|
||||
pub use ::crossterm::{
|
||||
ExecutableCommand, QueueableCommand,
|
||||
event::{Event, KeyEvent, KeyCode, KeyModifiers},
|
||||
terminal::{
|
||||
self,
|
||||
Clear, ClearType,
|
||||
EnterAlternateScreen, LeaveAlternateScreen,
|
||||
enable_raw_mode, disable_raw_mode
|
||||
},
|
||||
};
|
||||
macro_rules! submod { ($($name:ident)*) => { $(mod $name; pub use self::$name::*;)* }; }
|
||||
|
||||
submod!( device handle jack keymap port render run time );
|
||||
|
||||
pub type Usually<T> = Result<T, Box<dyn Error>>;
|
||||
|
||||
pub use ::ratatui::prelude::*;
|
||||
pub use ::midly::{MidiMessage, live::LiveEvent, num::u7};
|
||||
pub use crate::{key, keymap};
|
||||
|
|
|
|||
|
|
@ -21,6 +21,16 @@ pub trait Render {
|
|||
fn max_height (&self) -> u16 {
|
||||
u16::MAX
|
||||
}
|
||||
|
||||
//fn boxed (self) -> Box<dyn Render> where Self: Sized + 'static {
|
||||
//Box::new(self)
|
||||
//}
|
||||
}
|
||||
|
||||
impl<T: Fn(&mut Buffer, Rect) -> Usually<Rect>> Render for T {
|
||||
fn render (&self, b: &mut Buffer, a: Rect) -> Usually<Rect> {
|
||||
(*self).render(b, a)
|
||||
}
|
||||
}
|
||||
|
||||
impl Render for Box<dyn Device> {
|
||||
|
|
|
|||
|
|
@ -1,13 +1,21 @@
|
|||
use crate::core::*;
|
||||
use crossterm::terminal::{
|
||||
EnterAlternateScreen, LeaveAlternateScreen,
|
||||
enable_raw_mode, disable_raw_mode
|
||||
};
|
||||
|
||||
pub trait Run: Render + Handle + Send + Sized + 'static {
|
||||
fn run (self) -> Usually<()> {
|
||||
fn run (self, callback: Option<impl FnOnce(Arc<Mutex<Self>>)->Usually<()>>) -> Usually<()> {
|
||||
let device = Arc::new(Mutex::new(self));
|
||||
let exited = Arc::new(AtomicBool::new(false));
|
||||
let _input_thread = input_thread(&exited, &device);
|
||||
terminal_setup()?;
|
||||
panic_hook_setup();
|
||||
main_thread(&exited, &device)?;
|
||||
let main_thread = main_thread(&exited, &device)?;
|
||||
if let Some(callback) = callback {
|
||||
callback(device);
|
||||
}
|
||||
main_thread.join();
|
||||
terminal_teardown()?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -67,12 +75,13 @@ pub fn panic_hook_setup () {
|
|||
/// Main thread render loop
|
||||
pub fn main_thread (
|
||||
exited: &Arc<AtomicBool>,
|
||||
device: &Arc<Mutex<impl Render>>
|
||||
) -> Usually<()> {
|
||||
device: &Arc<Mutex<impl Render + Send + 'static>>
|
||||
) -> Usually<JoinHandle<()>> {
|
||||
let exited = exited.clone();
|
||||
let device = device.clone();
|
||||
let mut terminal = ratatui::Terminal::new(CrosstermBackend::new(stdout()))?;
|
||||
let sleep = std::time::Duration::from_millis(16);
|
||||
loop {
|
||||
Ok(spawn(move || loop {
|
||||
|
||||
terminal.draw(|frame|{
|
||||
let area = frame.size();
|
||||
|
|
@ -86,8 +95,7 @@ pub fn main_thread (
|
|||
|
||||
std::thread::sleep(sleep);
|
||||
|
||||
}
|
||||
Ok(())
|
||||
}))
|
||||
}
|
||||
/// Cleanup
|
||||
pub fn terminal_teardown () -> Usually<()> {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::core::*;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Timebase {
|
||||
/// Frames per second
|
||||
pub rate: ::atomic_float::AtomicF64,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue