wip: update core for generic Render

This commit is contained in:
🪞👃🪞 2024-09-03 18:13:10 +03:00
parent fcd2d16de9
commit bf165c6be1
5 changed files with 68 additions and 62 deletions

View file

@ -144,7 +144,9 @@ impl Jack {
}) })
} }
pub fn run <D, T, U> (self, state: impl FnOnce(JackPorts)->Box<D>) -> Usually<JackDevice<T, U>> pub fn run <D, T, U> (self, state: impl FnOnce(JackPorts)->Box<D>) -> Usually<JackDevice<T, U>>
where D: Device<T, U> + Process + Sized + 'static where D: Device<T, U> + Process + Sized + 'static,
T: 'static,
U: 'static
{ {
let owned_ports = JackPorts { let owned_ports = JackPorts {
audio_ins: register_ports(&self.client, self.audio_ins, AudioIn)?, audio_ins: register_ports(&self.client, self.audio_ins, AudioIn)?,

View file

@ -59,3 +59,14 @@ impl<R, T, U> Render<T, U> for RwLock<R> where R: Render<T, U> {
self.read().unwrap().render(to) self.read().unwrap().render(to)
} }
} }
/// Boxed closures can be rendered.
///
/// Rendering unboxed closures should also be possible;
/// but in practice implementing the trait for an unboxed
/// `Fn` closure causes an impl conflict.
impl<'a, T, U> Render<T, U> for Box<dyn Fn(&mut T) -> Perhaps<U> + Send + Sync + 'a> {
fn render (&self, to: &mut T) -> Perhaps<U> {
(*self)(to)
}
}

View file

@ -28,11 +28,11 @@ pub trait BorderStyle {
Ok(area) Ok(area)
} }
#[inline] #[inline]
fn draw_north (&self, buf: &mut Buffer, x: u16, y: u16, style: Option<Style>) -> Usually<Rect> { fn draw_north (&self, buf: &mut Buffer, x: u16, y: u16, style: Option<Style>) -> Perhaps<Rect> {
Self::N.blit(buf, x, y, style) Self::N.blit(buf, x, y, style)
} }
#[inline] #[inline]
fn draw_south (&self, buf: &mut Buffer, x: u16, y: u16, style: Option<Style>) -> Usually<Rect> { fn draw_south (&self, buf: &mut Buffer, x: u16, y: u16, style: Option<Style>) -> Perhaps<Rect> {
Self::S.blit(buf, x, y, style) Self::S.blit(buf, x, y, style)
} }

View file

@ -60,34 +60,37 @@ impl<'a> Render<TuiOutput<'a>, Rect> for Split<'a, TuiOutput<'a>, Rect> {
} }
} }
impl<'a> Split<'a, TuiOutput<'a>, Rect> { impl<'a, 'b: 'a> Split<'a, TuiOutput<'a>, Rect> {
pub fn render_areas (&self, to: &mut TuiOutput<'a>) -> Usually<(Rect, Vec<Rect>)> { pub fn render_areas (&'a self, to: &mut TuiOutput<'a>) -> Usually<(Rect, Vec<Rect>)> {
let Rect { mut x, mut y, mut width, mut height } = to.area; Ok((Rect::default(), vec![]))
let mut areas = vec![]; //let Rect { mut x, mut y, mut width, mut height } = to.area;
let buffer = &mut to.buffer; //let TuiOutput { buffer, area } = to;
for (index, item) in self.items.0.iter().enumerate() { //let mut areas = vec![];
if width == 0 || height == 0 { //for (index, item) in self.items.0.iter().enumerate() {
break //if width == 0 || height == 0 {
} //break
let target = TuiOutput { buffer, area: Rect { x, y, width, height } }; //}
if let Some(result) = item.render(&mut target)? { //if let Some(result) = item.render(&mut TuiOutput {
match self.direction { //buffer: to.buffer,
Direction::Down => { //area: Rect { x, y, width, height }
y += result.height; //})? {
height = height.saturating_sub(result.height); //match self.direction {
}, //Direction::Down => {
Direction::Right => { //y += result.height;
x += result.width; //height = height.saturating_sub(result.height);
width = width.saturating_sub(result.width); //},
}, //Direction::Right => {
_ => unimplemented!() //x += result.width;
}; //width = width.saturating_sub(result.width);
areas.push(result); //},
if self.focus == Some(index) { //_ => unimplemented!()
Corners(Style::default().green().not_dim()).draw(buffer, result)?; //};
} //areas.push(result);
} //if self.focus == Some(index) {
} //Corners(Style::default().green().not_dim()).draw(to.buffer, result)?;
Ok((to.area, areas)) //}
//}
//}
//Ok((to.area, areas))
} }
} }

View file

@ -8,29 +8,30 @@ pub struct TuiOutput<'a> {
} }
/// Main thread render loop /// Main thread render loop
pub fn tui_render_thread <'a, T: Render<TuiOutput<'a>, Rect> + 'static> ( pub fn tui_render_thread <'a: 'static, T> (
exited: &Arc<AtomicBool>, device: &Arc<RwLock<T>>, exited: &Arc<AtomicBool>, device: &Arc<RwLock<T>>,
) -> Usually<JoinHandle<()>> { ) -> Usually<JoinHandle<()>> where
T: Render<TuiOutput<'a>, Rect> + 'static
{
let exited = exited.clone(); let exited = exited.clone();
let device = device.clone(); let device = device.clone();
let mut terminal = ratatui::Terminal::new(CrosstermBackend::new(stdout()))?; let mut terminal = ratatui::Terminal::new(CrosstermBackend::new(stdout()))?;
let sleep = Duration::from_millis(20); let sleep = Duration::from_millis(20);
Ok(spawn(move || loop { Ok(spawn(move || {
let draw = |frame: &'a mut ratatui::Frame|{
if let Ok(device) = device.try_read() { let area = frame.size();
terminal.draw(|frame|{ let buffer = frame.buffer_mut();
let area = frame.size(); device.render(&mut TuiOutput { buffer, area }).expect("Failed to render content");
let buffer = frame.buffer_mut(); };
let mut output = TuiOutput { buffer, area }; loop {
device.render(&mut output).expect("Failed to render content"); if let Ok(_) = device.try_read() {
}) terminal.draw(draw).expect("Failed to render frame");
.expect("Failed to render frame"); }
if exited.fetch_and(true, Ordering::Relaxed) {
break
}
std::thread::sleep(sleep);
} }
if exited.fetch_and(true, Ordering::Relaxed) {
break
}
std::thread::sleep(sleep);
})) }))
} }
@ -76,19 +77,8 @@ impl<T: AsRef<str>> Blit for T {
/// Rendering unit struct to Ratatui returns zero-sized [Rect] at render coordinates. /// Rendering unit struct to Ratatui returns zero-sized [Rect] at render coordinates.
impl<'a> Render<TuiOutput<'a>, Rect> for () { impl<'a> Render<TuiOutput<'a>, Rect> for () {
fn render (&self, (_, area): (&mut Buffer, Rect)) -> Perhaps<Rect> { fn render (&self, to: &mut TuiOutput<'a>) -> Perhaps<Rect> {
Ok(Some(Rect { x: area.x, y: area.y, width: 0, height: 0 })) Ok(Some(Rect { x: to.area.x, y: to.area.y, width: 0, height: 0 }))
}
}
/// Boxed closures can be rendered.
///
/// Rendering unboxed closures should also be possible;
/// but in practice implementing the trait for an unboxed
/// `Fn` closure causes an impl conflict.
impl<'a, T, U> Render<T, U> for Box<dyn Fn(T) -> Usually<U> + Send + Sync + 'a> {
fn render (&self, to: T) -> Usually<U> {
(*self)(to)
} }
} }