use alloc::vec::Vec;
use embedded_graphics::Drawable;
use embedded_graphics::mono_font::MonoTextStyle;
use embedded_graphics::mono_font::iso_8859_1::FONT_7X13_BOLD;
use embedded_graphics::prelude::{PixelColor, Point};
use embedded_graphics::text::{Baseline, Text};
use all_is_cubes::character::Cursor;
use crate::camera::{ImageSize, Layers};
use crate::{Flaws, RenderError};
pub trait HeadlessRenderer {
fn update(
&mut self,
read_tickets: Layers<all_is_cubes::universe::ReadTicket<'_>>,
cursor: Option<&Cursor>,
) -> Result<(), RenderError>;
fn draw<'a>(
&'a mut self,
info_text: &'a str,
) -> futures_core::future::BoxFuture<'a, Result<Rendering, RenderError>>;
}
#[derive(Clone, Debug)]
#[expect(clippy::exhaustive_structs)]
pub struct Rendering {
pub size: ImageSize,
pub data: Vec<[u8; 4]>,
pub flaws: Flaws,
}
impl From<Rendering> for imgref::ImgVec<[u8; 4]> {
fn from(value: Rendering) -> Self {
imgref::Img::new(
value.data,
value.size.width as usize,
value.size.height as usize,
)
}
}
impl<'a> From<&'a Rendering> for imgref::ImgRef<'a, [u8; 4]> {
fn from(value: &'a Rendering) -> Self {
imgref::Img::new(
value.data.as_slice(),
value.size.width as usize,
value.size.height as usize,
)
}
}
#[doc(hidden)] pub fn info_text_drawable<C: PixelColor + 'static>(
text: &str,
color_value: C,
) -> impl Drawable<Color = C> + '_ {
Text::with_baseline(
text,
Point::new(5, 5),
MonoTextStyle::new(&FONT_7X13_BOLD, color_value),
Baseline::Top,
)
}
#[cfg(test)]
mod tests {
use super::*;
fn _headless_renderer_is_object_safe(_: &dyn HeadlessRenderer) {}
}