5 compile errors left

This commit is contained in:
🪞👃🪞 2024-09-07 16:44:49 +03:00
parent 7bcd40b425
commit b3f0f60400
13 changed files with 462 additions and 180 deletions

View file

@ -1,6 +1,4 @@
use crate::*;
use std::ops::{Add, Sub};
use std::cmp::{Ord, Eq, PartialEq};
/// Entry point for main loop
pub trait App<T: Engine> {
@ -29,18 +27,6 @@ pub trait Engine: Sized {
-> &mut Self;
}
pub trait Number: Send + Sync + Copy
+ Add<Self, Output=Self>
+ Sub<Self, Output=Self>
+ Ord + PartialEq + Eq {}
impl<T> Number for T where
T: Send + Sync + Copy
+ Add<Self, Output=Self>
+ Sub<Self, Output=Self>
+ Ord + PartialEq + Eq
{}
submod! {
collect
component

View file

@ -54,6 +54,13 @@ impl<'a, E: Engine> Collect<'a, E> for Collection<'a, E> {
}
}
pub struct Layers<'a, E: Engine>(pub &'a [&'a dyn Render<E>]);
// this actually works, except for the type inference
//pub struct Layers<'a, E: Engine + 'a, I: std::iter::IntoIterator<Item = &'a dyn Render<E>>>(
//pub &'a I
//);
pub struct Layered<'a, E: Engine>(pub Collection<'a, E>);
impl<'a, E: Engine> Layered<'a, E> {

View file

@ -57,13 +57,15 @@ impl<R, E: Engine> Render<E> for RwLock<R> where R: Render<E> {
}
}
/// 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, E: Engine> Render<E> for Box<dyn Fn(&mut E) -> Perhaps<E::Rendered> + Send + Sync + 'a> {
fn render (&self, to: &mut E) -> Perhaps<E::Rendered> {
(*self)(to)
}
}
// FIXME: components are now 2 thunks (layout and render).
// maybe this resolves the conflict describe below?
///// 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, E: Engine> Render<E> for Box<dyn Fn(&mut E) -> Perhaps<E::Rendered> + Send + Sync + 'a> {
//fn render (&self, to: &mut E) -> Perhaps<E::Rendered> {
//(*self)(to)
//}
//}

View file

@ -15,6 +15,9 @@ pub(crate) use std::thread::{spawn, JoinHandle};
pub(crate) use std::time::Duration;
pub(crate) use atomic_float::*;
use better_panic::{Settings, Verbosity};
use std::ops::{Add, Sub};
use std::cmp::{Ord, Eq, PartialEq};
use std::fmt::{Debug, Display};
/// Define and reexport submodules.
#[macro_export] macro_rules! submod {
@ -40,3 +43,18 @@ pub type Usually<T> = Result<T, Box<dyn Error>>;
/// Standard optional result type.
pub type Perhaps<T> = Result<Option<T>, Box<dyn Error>>;
/// Standard numeric type.
pub trait Number: Send + Sync + Copy
+ Add<Self, Output=Self>
+ Sub<Self, Output=Self>
+ Ord + PartialEq + Eq
+ Debug + Display {}
impl<T> Number for T where
T: Send + Sync + Copy
+ Add<Self, Output=Self>
+ Sub<Self, Output=Self>
+ Ord + PartialEq + Eq
+ Debug + Display
{}

View file

@ -30,6 +30,13 @@ pub trait Area<N: Number>: Copy {
fn lrtb (&self) -> [N;4] {
[self.x(), self.x2(), self.y(), self.y2()]
}
fn expect_min (&self, w: N, h: N) -> Usually<&Self> {
if self.w() < w || self.h() < h {
Err(format!("min {w}x{h}").into())
} else {
Ok(self)
}
}
}
impl<N: Number> Area<N> for (N, N, N, N) {

View file

@ -201,7 +201,14 @@ pub enum TuiEvent {
/// Rendering unit struct to Ratatui returns zero-sized [Area] at render coordinates.
impl Render<Tui> for () {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
Ok(Some([to.area.x(), to.area.y(), 0, 0]))
self.layout(to.area())
}
}
/// Layout of unit struct in Ratatui is zero-sized [Area] at render coordinates.
impl Layout<Tui> for () {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
Ok(Some([area.x(), area.y(), 0, 0]))
}
}

View file

@ -86,8 +86,8 @@ macro_rules! border {
($($T:ty {
$nw:literal $n:literal $ne:literal $w:literal $e:literal $sw:literal $s:literal $se:literal
$($x:tt)*
}),+) => {
$(impl BorderStyle for $T {
}),+) => {$(
impl BorderStyle for $T {
const NW: &'static str = $nw;
const N: &'static str = $n;
const NE: &'static str = $ne;
@ -97,8 +97,13 @@ macro_rules! border {
const S: &'static str = $s;
const SE: &'static str = $se;
$($x)*
})+
}
}
impl Render<Tui> for $T {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
self.draw(to)
}
}
)+}
}
pub struct Lozenge(pub Style);

View file

@ -1,5 +1,36 @@
use crate::*;
impl Layout<Tui> for &str {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
let [x, y, ..] = area;
// TODO: line breaks
Ok(Some([x, y, self.len() as u16, 1]))
}
}
impl Render<Tui> for &str {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = self.layout(to.area())?.unwrap();
to.blit(&self, area.x(), area.y(), None)?;
Ok(Some(area))
}
}
pub struct Styled<T: Layout<Tui>>(pub Option<Style>, pub T);
impl Layout<Tui> for Styled<&str> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
Ok(Some([area.x(), area.y(), self.1.len() as u16, 1]))
}
}
impl Render<Tui> for Styled<&str> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = self.layout(to.area())?.unwrap();
Ok(Some([area.x(), area.y(), self.1.len() as u16, 1]))
}
}
pub struct FillBg(pub Color);
impl Render<Tui> for FillBg {

View file

@ -1,5 +1,24 @@
use crate::*;
impl<T: Layout<Tui>> Layout<Tui> for Option<T> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
match self {
Some(layout) => layout.layout(area),
None => ().layout(area)
}
}
}
impl<'a> Render<Tui> for Layers<'a, Tui> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area();
for layer in self.0.iter() {
layer.render(to)?;
}
Ok(Some(area))
}
}
impl<'a> Render<Tui> for Layered<'a, Tui> {
fn render (&self, to: &mut Tui) -> Perhaps<[u16;4]> {
let area = to.area();
@ -16,6 +35,12 @@ impl<'a> Render<Tui> for Split<'a, Tui> {
}
}
impl<'a> Layout<Tui> for Split<'a, Tui> {
fn layout (&self, area: [u16;4]) -> Perhaps<[u16;4]> {
todo!()
}
}
// TODO
impl<'a> Split<'a, Tui> {
pub fn render_areas (&self, to: &mut Tui) -> Usually<([u16;4], Vec<Option<[u16;4]>>)> {