retroglyph_core/lib.rs
1//! retroglyph-core: the `no_std`-compatible foundation of retroglyph.
2//!
3//! Grid, tile, style, color, text, terminal, and event types, plus the
4//! [`Backend`] trait and the dependency-free [`Headless`] test backend, and
5//! the `App`/`Flow`/`Frame` game loop contract. Platform backends
6//! (`retroglyph-crossterm`, `retroglyph-software`) and drawing helpers
7//! (`retroglyph-widgets`) are separate crates that depend on this one.
8//!
9//! # Architecture
10//!
11//! [`Terminal<B>`](Terminal) is the drawing API a game calls into (`put`,
12//! `print`, `layer`, ...). It owns a double-buffered [`Grid`] and diffs the
13//! current frame against the previous one in [`present`](Terminal::present),
14//! sending only changed cells to the [`Backend`]. `B` is the only thing that
15//! changes between a headless test and a real window or terminal:
16//!
17//! ```text
18//! ┌───────────────────────────┐
19//! │ App::update(...) │ game logic, once, generic over B
20//! └──────────────┬─────────────┘
21//! │ put / print / present
22//! ▼
23//! ┌───────────────────────────┐
24//! │ Terminal<B> │ double-buffered Grid, cell diff
25//! └──────────────┬─────────────┘
26//! │ draw / draw_layers / poll_event
27//! ▼
28//! ┌───────────────────────────┐
29//! │ B: Backend │ the only piece that swaps out
30//! └──────────────┬─────────────┘
31//! │
32//! ┌─────────────────────┼─────────────────────┐
33//! ▼ ▼ ▼
34//! Headless (here) Crossterm SoftwareRenderer
35//! in-memory grid, (retroglyph-crossterm) (retroglyph-software)
36//! synthetic events real TTY, ANSI output winit window, pixels
37//! ```
38//!
39//! [`Headless`] stores presented content in memory and lets tests inject
40//! synthetic [`Event`]s with [`Headless::push_event`](backend::Headless::push_event);
41//! nothing here talks to a real terminal or window. Swapping `Headless` for
42//! `Crossterm` or `SoftwareRenderer` changes only the `B` type parameter --
43//! `App` implementations, [`Terminal`] calls, and game logic are unchanged.
44//! `run_blocking` drives `Terminal<Headless>` and `Terminal<Crossterm>`
45//! identically; the software backend's windowed loop drives `Terminal<SoftwareRenderer>`
46//! through the same [`App`]/[`step`] contract, inverted because winit owns the
47//! event loop instead of handing control back to a driver function.
48//!
49//! See `examples/headless.rs` (`cargo run -p retroglyph-core --example
50//! headless`) for the smallest possible use of [`Headless`], depending on
51//! nothing but this crate.
52#![cfg_attr(not(feature = "std"), no_std)]
53extern crate alloc;
54
55// Compile the code blocks in this crate's own README as doctests so its quick start is
56// type-checked on every test run and cannot silently rot. The `cfg(doctest)` gate keeps this out
57// of the rendered crate documentation -- see `retroglyph-crossterm`'s matching include for the
58// same pattern applied to the workspace root README.
59#[cfg(doctest)]
60#[doc = include_str!("../README.md")]
61struct ReadmeDoctests;
62
63// clippy::too_long_first_doc_paragraph is a known-noisy nursery lint (rust-lang/rust-clippy#13441)
64// that here misattributes its span across every subsequent `pub mod`/`pub use` declaration below
65// (through to the next blank line) rather than just this one doc comment, which is well under
66// its own 100-char threshold in isolation -- confirmed by testing shorter wording alone, which
67// silences it despite touching nothing else in that byte range.
68#[allow(clippy::too_long_first_doc_paragraph)]
69/// Time-driven value animation: easing curves, a stateful `Tween`, and a periodic oscillator.
70pub mod animate;
71/// The `App`-driven game loop.
72pub mod app;
73/// Pluggable rendering backends.
74pub mod backend;
75/// A scrolling viewport into a world larger than the screen.
76pub mod camera;
77pub mod color;
78pub mod event;
79/// Fixed-timestep accumulator for game loops.
80pub mod frame_clock;
81pub mod grid;
82#[cfg(feature = "egc")]
83pub mod layout;
84pub mod style;
85pub mod subcell;
86pub mod terminal;
87pub mod text;
88/// The atomic drawable unit (glyph, style, sub-cell offsets).
89pub mod tile;
90
91pub use animate::{Easing, Tween, oscillate};
92#[cfg(feature = "std")]
93pub use app::run_blocking;
94pub use app::{App, Flow, Frame, step};
95pub use backend::{Backend, Headless};
96pub use camera::Camera;
97pub use color::{AnsiColor, Color, InvalidAnsiIndex};
98pub use event::{
99 Event, KeyCode, KeyEvent, KeyEventKind, KeyModifiers, KeyState, MouseButton, MouseEvent,
100 MouseEventKind, PhysicalPos, SystemTheme,
101};
102pub use frame_clock::FrameClock;
103#[cfg(feature = "gem")]
104pub use grid::BlendMode;
105pub use grid::{Grid, Pos, Rect, Size};
106#[cfg(feature = "egc")]
107pub use layout::{HAlign, TextLayout, TextMetrics, VAlign};
108pub use style::Style;
109pub use subcell::{Glyph, quantize_half_block, quantize_quadrant, quantize_sextant};
110pub use terminal::Terminal;
111pub use text::{Line, Span};
112pub use tile::Tile;