mirror of
https://codeberg.org/unspeaker/tek.git
synced 2025-12-06 19:56:42 +01:00
wip: update core for generic Render
This commit is contained in:
parent
fcd2d16de9
commit
bf165c6be1
5 changed files with 68 additions and 62 deletions
|
|
@ -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)?,
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue