1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
//! `retroglyph`: a 2D pseudographic terminal library, one dependency and one `use`.
//!
//! Add this crate and you get the double-buffered `Terminal`/`App` game loop, styled cells, text
//! and layout helpers, and input events -- `app`, `color`, `event`, `frames`, `grid`, `layout`,
//! `surface`, `terminal`, `text`, `tile`, `symbols` -- plus a [`prelude`] with the handful of
//! names a program can't avoid, and one feature-gated module per backend (`crossterm`,
//! `software`, `gl`, `wgpu`, `terminal_wasm`, `ui`). Writing a new backend instead of a game?
//! Depend on [`retroglyph-core`](retroglyph_core) directly for its lower-level `backend`, `dev`,
//! and `math` modules.
//!
//! # Quick start
//!
//! ```sh
//! cargo add retroglyph
//! ```
//!
//! ```rust,no_run
//! use retroglyph::crossterm::Crossterm;
//! use retroglyph::prelude::*;
//!
//! struct Game;
//!
//! impl App<Crossterm> for Game {
//! fn update(&mut self, term: &mut Terminal<Crossterm>, _frame: &Frame) -> Flow {
//! term.surface().put((5, 5), '@', Style::new().fg(Color::GREEN));
//!
//! if let Some(Event::Key(k)) = term.poll(std::time::Duration::from_secs(1)) {
//! if k.code == KeyCode::Char('q') {
//! return Flow::Exit;
//! }
//! }
//! Flow::Continue
//! }
//! }
//!
//! fn main() -> std::io::Result<()> {
//! retroglyph::app::run(Crossterm::new()?, Game)
//! }
//! ```
//!
//! Want a native window or a browser tab instead of a real terminal? Enable the `software`, `gl`,
//! or `wgpu` feature instead of (or alongside) `crossterm`: same `Terminal`/`App` contract, a
//! different `Backend` type. See each backend module's own docs (and
//! [`WindowConfig`]/[`run_app`]) for the windowed quick start.
//!
//! # Features
//!
//! <!-- gen-features:start -->
//! Default features: `crossterm`, `ui`.
//!
//! ### `crossterm`
//!
//! 🟢 Enabled by default.
//!
//! Re-exports `retroglyph-crossterm` as [`crossterm`]: a real-terminal `Backend`
//! via `crossterm`.
//!
//! ### `default-font`
//!
//! ⚪ Optional.
//!
//! Forwards each enabled backend's own `default-font` feature (an embedded Unscii 16 bitmap font),
//! so a caller doesn't need to know which backend crate actually owns it.
//!
//! ### `gl`
//!
//! ⚪ Optional.
//!
//! Re-exports `retroglyph-gl` as [`gl`]: a GPU `Backend` via `glow` (OpenGL 3.3 native,
//! WebGL2 wasm). Also pulls in the curated windowed re-exports (`WindowConfig`, `PresenterBuilder`,
//! `Windowed`, `WindowedLaunchError`, `run_app`, `run_app_on`).
//!
//! ### `serde`
//!
//! ⚪ Optional.
//!
//! Adds `Serialize`/`Deserialize` impls to the curated types that support them (`Color`, `Style`,
//! geometry, ..., plus [`ui::theme::Theme`]/`Density` when `ui` is also enabled). Forwards to
//! `retroglyph-core`'s and `retroglyph-ui`'s own `serde` features; neither backend crate has one.
//!
//! ### `software`
//!
//! ⚪ Optional.
//!
//! Re-exports `retroglyph-software` as [`software`]: a CPU pixel `Backend` via
//! `softbuffer`. Also pulls in the curated windowed re-exports (`WindowConfig`, `PresenterBuilder`,
//! `Windowed`, `WindowedLaunchError`, `run_app`, `run_app_on`).
//!
//! ### `terminal-wasm`
//!
//! ⚪ Optional.
//!
//! Re-exports `retroglyph-terminal-wasm` as [`terminal_wasm`]: a browser `Backend` driven by
//! pushed/pulled ANSI I/O (e.g. xterm.js). Its `#[wasm_bindgen]` FFI module only compiles for
//! `target_arch = "wasm32"`, but the crate (and this re-export) build portably otherwise.
//!
//! ### `testing`
//!
//! ⚪ Optional.
//!
//! Enables [`TestHarness`] and its error, the published headless `App` driver for testing your own
//! `App`. Forwards to `retroglyph-core`'s own `testing` feature.
//!
//! ### `tilesets`
//!
//! ⚪ Optional.
//!
//! Forwards each enabled backend's own `tilesets` feature (PNG sprite/tileset loading), so a
//! caller doesn't need to know which backend crate actually owns it. Mirrors `default-font` above;
//! see [`retroglyph_window::tileset`](https://docs.rs/retroglyph-window) for the `TilesetOptions`/
//! `Codepage` config types that feature adds -- reach for `retroglyph-window` directly for those,
//! same as any other finer-grained windowed control this facade doesn't curate.
//!
//! ### `tracing`
//!
//! ⚪ Optional.
//!
//! Forwards to `retroglyph-crossterm`'s `tracing` feature: instruments `draw`/`flush`/`poll_event`
//! with `tracing` spans for profiling render/input time.
//!
//! ### `ui`
//!
//! 🟢 Enabled by default.
//!
//! Re-exports `retroglyph-ui` as [`ui`]: the immediate-mode widget/layout toolkit.
//!
//! ### `wgpu`
//!
//! ⚪ Optional.
//!
//! Re-exports `retroglyph-wgpu` as [`wgpu`]: a GPU `Backend` via `wgpu` (Vulkan,
//! Metal, D3D12, WebGPU). Also pulls in the curated windowed re-exports (`WindowConfig`,
//! `PresenterBuilder`, `Windowed`, `WindowedLaunchError`, `run_app`, `run_app_on`).
//! <!-- gen-features:end -->
// Compile the code blocks in both this crate's own README and the workspace root README as
// doctests so the quick-start examples are type-checked on every test run and cannot silently
// rot. The `cfg(doctest)` gate keeps these out of the rendered crate documentation. The workspace
// root README's quick start now demonstrates this crate (previously `retroglyph-crossterm`,
// before this crate existed), so it's doctested here instead.
;
;
pub use ;
/// The trait a backend's own builder implements to be driven end to end by
/// [`launch`](Launch::launch): the user names the backend (`CrosstermOptions`, `Windowed<B>`, ...)
/// and gets back that backend's own unwrapped error, rather than a facade-wide one. See this
/// trait's own docs for why there is no unified error here (`retroglyph::LaunchError`, tracked by
/// #430, is only needed if the facade grows an entry point that can return either backend's
/// error).
pub use Launch;
// `retroglyph_core::testing` also holds `conformance` (`Observable`, `assert_output_contract`,
// ...), the harness a *new backend* uses to prove it satisfies the `Output`/`Input`/`Cursor`
// contracts. That's backend-author surface, not game-author surface, so only the two
// game-facing items are re-exported here, individually, rather than the whole module.
//
// `RunError` is re-exported by its own name rather than a facade-specific alias: a future
// unified driver error (`LaunchError`, tracked by #430) must not also be named `RunError`, or the
// two would collide right here at `retroglyph::RunError`.
pub use ;
// A `pub mod` line's own doc comment and its target module's inner `//!` doc concatenate into one
// rendered page (see `retroglyph-core`'s matching comment in its own `lib.rs`), and the combined
// first paragraph here grows past this noisy nursery lint's threshold.
/// The names a program cannot avoid, glob-importable in one line.
/// A real-terminal [`Backend`](retroglyph_core::backend::Backend) via
/// [`crossterm`](https://crates.io/crates/crossterm).
pub use retroglyph_crossterm as crossterm;
/// A GPU [`Backend`](retroglyph_core::backend::Backend) via
/// [`glow`](https://crates.io/crates/glow): OpenGL 3.3 (native) and WebGL2 (wasm).
pub use retroglyph_gl as gl;
/// A CPU pixel [`Backend`](retroglyph_core::backend::Backend) via
/// [`softbuffer`](https://crates.io/crates/softbuffer).
pub use retroglyph_software as software;
/// A browser [`Backend`](retroglyph_core::backend::Backend) driven by pushed/pulled ANSI I/O
/// (e.g. [xterm.js](https://xtermjs.org/)).
pub use retroglyph_terminal_wasm as terminal_wasm;
/// The immediate-mode widget/layout toolkit: panels, gauges, tables, input/focus, theming,
/// animation.
pub use retroglyph_ui as ui;
/// A GPU [`Backend`](retroglyph_core::backend::Backend) via
/// [`wgpu`](https://crates.io/crates/wgpu): Vulkan, Metal, D3D12, and WebGPU.
pub use retroglyph_wgpu as wgpu;
// The curated windowed surface (issue #1203): a windowed backend's own quick-start needs a way
// to build a window and drive its event loop, without reaching past this crate into
// `retroglyph-window` for the whole `winit` module. `run_windowed`/`run_windowed_with_proxy`/
// `run_windowed_with_typed_proxy`/`run_app_with_proxy`/`run_app_with_typed_proxy` stay
// reachable only through `retroglyph_window::winit` directly: they're cross-thread event
// injection power tools, not quick-start material.
pub use PresenterBuilder;
pub use ;
// ── `run_default`: one call, no per-app `#[cfg]` table ──────────────────────────────
//
// Four near-identical items below, one per backend, `#[cfg]`-gated so exactly one is compiled
// for any given feature set (never zero, never more than one: each arm excludes every
// higher-priority feature via `not(any(...))`, the same shape `retroglyph-examples`' own
// `launch::<E>()` dispatch table already uses). A single generic function spanning every
// backend isn't expressible instead: `Launch::Backend` differs per implementor, and stable Rust
// has no way to write "`A` implements `App<B>` for whichever `B` this arm turns out to be" as
// one bound (no non-lifetime higher-ranked trait bounds; see rust#108185, and `Launch`'s own
// doc comment above for the same limitation). Priority: `software` > `gl` > `wgpu` >
// `crossterm`, matching the tile-demo gallery's dispatch table this replaces (retroglyph#1295),
// with `wgpu` slotted between the other two windowed backends and the real-terminal one.
/// Picks a backend from this crate's enabled Cargo features and drives `app` on it, using that
/// backend's own default configuration.
///
/// See the priority order above. Each backend is built with [`PresenterBuilder::new()`] for a
/// windowed backend, paced by [`RunOptions::default()`](app::RunOptions), or
/// [`Crossterm::builder()`](crossterm::Crossterm::builder) for the terminal one.
///
/// This is the zero-config fast path, not a general-purpose driver: an app that needs a specific
/// grid size, window title, tileset, or pacing has outgrown "default" and should call that
/// backend's own [`Launch::launch`] directly instead, e.g. `Windowed::new(builder, "My
/// Game").launch(app, RunOptions::animated(60))` or `Crossterm::builder().launch(app, options)`.
///
/// Absent entirely (not a compile error) when none of `crossterm`, `software`, `gl`, or `wgpu`
/// is enabled: there is no backend left to pick.
///
/// # Errors
///
/// Returns the picked backend's own [`Launch::Error`] if it fails to launch; see that backend's
/// `Launch` impl for the exact conditions (a real terminal that can't enter raw mode, a
/// presenter that fails to build, or a window/event loop that fails to start or run).
/// See [`run_default`]'s `software`-enabled overload. `gl` is the other GPU windowed backend;
/// `software` wins if both happen to be enabled.
///
/// # Errors
///
/// See [`run_default`]'s `software`-enabled overload.
/// See [`run_default`]'s `software`-enabled overload. `wgpu` is the other GPU windowed backend;
/// it loses to `software`/`gl` if either is also enabled.
///
/// # Errors
///
/// See [`run_default`]'s `software`-enabled overload.
/// See [`run_default`]'s `software`-enabled overload. `crossterm` is the real-terminal backend;
/// it loses to any windowed backend that's also enabled.
///
/// # Errors
///
/// See [`run_default`]'s `software`-enabled overload.
///
/// # Examples
///
/// ```no_run
/// use retroglyph::crossterm::Crossterm;
/// use retroglyph::prelude::*;
///
/// struct Game;
///
/// impl App<Crossterm> for Game {
/// fn update(&mut self, term: &mut Terminal<Crossterm>, _frame: &Frame) -> Flow {
/// term.surface().put((5, 5), '@', Style::new().fg(Color::GREEN));
/// Flow::Continue
/// }
/// }
///
/// fn main() -> Result<(), std::io::Error> {
/// retroglyph::run_default(Game)
/// }
/// ```