Expand description
retroglyph-core: the no_std-compatible foundation of retroglyph.
Grid, tile, style, color, text, terminal, and event types, plus the
Output/Input/Cursor backend
facets (bundled together as Backend) and the dependency-free
Headless test backend, and the App/Flow/Frame game loop contract.
Platform backends (retroglyph-crossterm, retroglyph-software) and drawing helpers
(retroglyph-ui) are separate crates that depend on this one.
Β§Features
Default features: egc, std.
Β§dev
βͺ Optional.
Forces BuildMode::Dev on in a build that would otherwise resolve to Release.
Can be used so an optimized build still reports development diagnostics (see the dev
module).
Β§egc
π’ Enabled by default.
Enables grapheme-cluster-aware text handling (via unicode-segmentation) for EGC-correct cell
diffing and layout.
Β§libm
βͺ Optional.
Uses libmβs software float implementation (roundf/fmaf/sinf/cosf/powf) for
the separable BlendMode channel math, via this crateβs own
math shim β the no_std side of that split. See std below for the alternative that prefers
the platformβs own float intrinsics when available; a build needs exactly one of the two.
Β§serde
βͺ Optional.
Adds Serialize/Deserialize impls for Color, Style, Size,
Offset, and (via ixy) Pos/Rect, so a config file can round-trip a saved camera position,
window geometry, sub-cell pixel offset, or theme color.
Color serializes through its Display/FromStr round trip (e.g. "bright-red",
"#ff8000") rather than a derived structural form, so hand-edited TOML/JSON stays legible.
Β§std
π’ Enabled by default.
Enables gem/std and alpha-blend/std, and uses stdβs float intrinsics (via this crateβs
math shim) instead of libmβs software implementation for the separable
BlendMode channel math.
Disabling this feature (--no-default-features) builds this crate no_std, and then needs
libm above as the float backend instead: see the crate-level compile_error! in src/lib.rs.
Β§testing
βͺ Optional.
Enables testingβs TestHarness, which drives an App against
Headless for tests, with
synthetic input queuing and frame-settling helpers.
Test-only surface, no_std + alloc compatible, off by default so it never ships in a release
build by accident.
Β§Architecture
Terminal<B> owns a double-buffered Grid and the
Backend lifecycle (resize, present, events). Drawing itself goes entirely
through Surface, handed out by
Terminal::draw/Terminal::surface:
a game calls term.draw(|s| { s.put(...); ... })
once per frame, and present diffs the current frame against the
previous one, sending only changed cells to the Backend. B is the only thing that
changes between a headless test and a real window or terminal:
βββββββββββββββββββββββββββββ
β App::update(...) β game logic, once, generic over B
ββββββββββββββββ¬ββββββββββββββ
β term.draw(|s| ...): writes through Surface
βΌ
βββββββββββββββββββββββββββββ
β Terminal<B> β double-buffered Grid, cell diff
ββββββββββββββββ¬ββββββββββββββ
β draw / draw_layers / poll_event
βΌ
βββββββββββββββββββββββββββββ
β B: Output + Input + Cursor β the only piece that swaps out
ββββββββββββββββ¬ββββββββββββββ
β
βββββββββββββββββββββββΌββββββββββββββββββββββ
βΌ βΌ βΌ
Headless (here) Crossterm SoftwareRenderer
in-memory grid, (retroglyph-crossterm) (retroglyph-software)
synthetic events real TTY, ANSI output winit window, pixelsHeadless stores presented content in memory and lets tests inject
synthetic Events with Headless::push_event;
nothing here talks to a real terminal or window. Swapping Headless for
Crossterm or SoftwareRenderer changes only the B type parameter β
App implementations, Terminal calls, and game logic are unchanged.
run_blocking drives Terminal<Headless> and Terminal<Crossterm>
identically; the software backendβs windowed loop drives Terminal<SoftwareRenderer>
through the same App contract, inverted because winit owns the
event loop instead of handing control back to a driver function.
See examples/headless.rs (cargo run -p retroglyph-core --example headless) for the smallest possible use of Headless, depending on
nothing but this crate.
ModulesΒ§
- app
- The
App-driven game loop. TheApp-driven game loop. - backend
- Pluggable rendering backends. Pluggable rendering backends.
- color
- Color and style types for character cells:
Color(this module) andStyle, a{fg, bg}pair of twoColors with no other relation to anything else in this crate. - dev
- Which diagnostics a build compiles in. Build-mode vocabulary: which diagnostics a build compiles in.
- event
- Input event system.
- frames
FrameClock/FrameStatsaccumulators for theApp/Framegame loop.FrameClockandFrameStats, the two accumulators behind theApp/Framegame loop.- grid
- The layered tile grid:
Grid, plus theSize,Pos, andRectcoordinate types used throughout the crate. - layout
- Text layout: measurement, word wrapping, and bounded alignment.
- surface
- The one grid-drawing primitive: an area-clipped, single-layer view over a
Grid.Surface: an area-clipped, single-layer view over aGrid. - symbols
- Border, gridline, and partial-block
chardata shared by widgets and backends.chardata for drawing borders, gridlines, and partial-block glyphs, plus the pixel-to-glyph matching logic that picks one of those glyphs for a raw pixel block. - terminal
Terminal: construction, sizing, resizing, cursor control, and raw grid/backend access.- testing
- Headless test harness driving an
Appwith synthetic input. Headless test harness driving anAppwith synthetic input. - text
- Styled text primitives:
SpanandLine. - tile
- The atomic drawable unit (glyph, style, sub-cell offsets). Fundamental unit of the grid: a single drawable tile.