Skip to main content

rlevo_core/render/
mod.rs

1//! Rendering abstractions for environment visualization.
2//!
3//! # Module layout
4//!
5//! | Submodule          | What it provides                                                    |
6//! |--------------------|---------------------------------------------------------------------|
7//! | [`ascii`]          | [`AsciiRenderable`] trait and [`AsciiRenderer`] — optional text dump helper (ADR-0013). |
8//! | [`styled`]         | [`StyledFrame`] / [`StyledLine`] / [`StyledSpan`] / [`SpanStyle`] / [`Color`] / [`Modifier`] — colour-aware projection consumed by the `ratatui` TUI and the static-HTML report tier. |
9//! | [`palette`]        | Project-wide semantic colour constants (`AGENT_FG`, `GOAL_FG`, `HAZARD_FG`, …). Every styled-output implementor should reach for these rather than raw [`Color`] values to satisfy the accessibility contract. |
10//! | [`payload`]        | Per-family structured snapshot types ([`Landscape2DSnapshot`], [`Box2dSnapshot`], [`Locomotion2DSnapshot`], …) and the corresponding opt-in payload-source traits consumed by the report tier. |
11//!
12//! # Renderer trait
13//!
14//! [`Renderer`] is generic over frame type, so ASCII, image, and no-op
15//! renderers all share the same interface. Use [`NullRenderer`] when
16//! rendering is not required — `Frame = ()` means no allocation occurs and
17//! the compiler eliminates every call site.
18//!
19//! [`AsciiRenderer`]: crate::render::AsciiRenderer
20//! [`StyledFrame`]: crate::render::StyledFrame
21//! [`StyledLine`]: crate::render::StyledLine
22//! [`StyledSpan`]: crate::render::StyledSpan
23//! [`SpanStyle`]: crate::render::SpanStyle
24//! [`Color`]: crate::render::Color
25//! [`Modifier`]: crate::render::Modifier
26//! [`Landscape2DSnapshot`]: crate::render::Landscape2DSnapshot
27//! [`Box2dSnapshot`]: crate::render::Box2dSnapshot
28//! [`Locomotion2DSnapshot`]: crate::render::Locomotion2DSnapshot
29//! [`NullRenderer`]: crate::render::NullRenderer
30
31pub mod ascii;
32pub mod palette;
33pub mod payload;
34pub mod styled;
35
36pub use ascii::{AsciiRenderable, AsciiRenderer};
37pub use payload::{
38    Box2dPayloadSource, Box2dSnapshot, BodyKind, CardTable, Classic2DBody, Classic2DPayloadSource,
39    Classic2DRole, Classic2DSnapshot, GridAgentMarker, GridColor, GridDir, GridDoorState,
40    GridPayloadSource, GridSnapshot, GridTile, Landscape2DPayloadSource, Landscape2DSnapshot,
41    Locomotion2DPayloadSource, Locomotion2DSnapshot, Point2, RigidBody2D, TabularCell, TabularGrid,
42    TabularLayout, TabularMarker, TabularMarkerKind, TabularPayloadSource, TabularSnapshot,
43};
44pub use styled::{Color, Modifier, SpanStyle, StyledFrame, StyledLine, StyledSpan};
45
46/// A renderer for environment `E`.
47///
48/// The associated `Frame` type makes rendering zero-cost when `NullRenderer` is
49/// used — `Frame = ()` means no allocation occurs and the call optimises away.
50///
51/// ASCII text renderers pick `Frame = String`; image renderers pick
52/// `Frame = Vec<u8>` or `Frame = image::RgbImage`.
53pub trait Renderer<E> {
54    /// The output produced by one render call.
55    type Frame;
56
57    /// Render the current state of `env` and return a frame.
58    fn render(&self, env: &E) -> Self::Frame;
59}
60
61/// A no-op renderer with `Frame = ()`.
62///
63/// Use this as the default renderer type when rendering is not needed.
64/// The compiler eliminates all calls at zero runtime cost.
65#[derive(Debug, Clone, Copy, Default)]
66pub struct NullRenderer;
67
68impl<E> Renderer<E> for NullRenderer {
69    type Frame = ();
70
71    fn render(&self, _env: &E) {}
72}