use serde::Serialize;
#[derive(Debug, Serialize, Clone)]
pub struct Renderer {
no_returns_render: Vec<RenderMode>,
single_render: Vec<RenderMode>,
mode: RenderMode,
render_list: Vec<RenderFrame>,
}
type RenderFn<'a> = &'a mut dyn FnMut(RenderMode) -> Renders;
impl Renderer {
pub fn new(
mode: RenderMode,
no_returns_render: Option<Vec<RenderMode>>,
single_render: Option<Vec<RenderMode>>,
) -> Self {
Self {
no_returns_render: no_returns_render.unwrap_or(RenderMode::NO_RETURNS_RENDER.to_vec()),
single_render: single_render.unwrap_or(RenderMode::SINGLE_RENDER.to_vec()),
mode,
render_list: Vec::new(),
}
}
pub fn render_step(&mut self, render: RenderFn) {
if self.mode != RenderMode::None && !self.single_render.contains(&self.mode) {
let render_return = render(self.mode);
if !self.no_returns_render.contains(&self.mode) {
if let Renders::SingleRgbArray(frame) = render_return {
self.render_list.push(frame)
}
}
}
}
pub fn get_renders(&mut self, render: RenderFn) -> Renders {
if self.single_render.contains(&self.mode) {
render(self.mode)
} else if self.mode != RenderMode::None && !self.no_returns_render.contains(&self.mode) {
let renders = self.render_list.clone();
self.render_list = Vec::new();
Renders::RgbArray(renders)
} else {
Renders::None
}
}
pub fn reset(&mut self) {
self.render_list = Vec::new();
}
}
#[derive(Debug, Clone, Serialize, PartialEq, Eq, PartialOrd, Ord)]
pub enum RenderColor {
RGB(u8, u8, u8),
}
#[derive(Debug, Clone, PartialEq, PartialOrd, Eq, Ord, Serialize)]
pub struct RenderFrame(pub Vec<Vec<RenderColor>>);
#[derive(PartialEq, PartialOrd, Debug, Clone, Copy, Serialize, Eq, Ord, Default)]
pub enum RenderMode {
Human,
SingleRgbArray,
RgbArray,
Ansi,
#[default]
None,
}
impl RenderMode {
pub const DEFAULT: &'static [RenderMode] = &[];
const NO_RETURNS_RENDER: &'static [RenderMode] = &[RenderMode::Human];
const SINGLE_RENDER: &'static [RenderMode] = &[RenderMode::SingleRgbArray];
}
#[derive(PartialEq, PartialOrd, Debug, Clone, Serialize, Ord, Eq)]
pub enum Renders {
SingleRgbArray(RenderFrame),
RgbArray(Vec<RenderFrame>),
Ansi(Vec<String>),
None,
}