pub struct TerminalWasm { /* private fields */ }Expand description
A Backend that renders into an in-memory ANSI byte buffer and accepts
pushed input, for driving a browser terminal emulator from WASM.
Unlike retroglyph_crossterm::Crossterm,
this backend:
- never queries a TTY for its size: call
resize_terminal(or, if the input side doesn’t matter for the caller,Terminal::resizedirectly) whenever the host reports a new size (e.g. from xterm.js’sfitaddon); - never polls for input: input only ever arrives via
push_event, called from awasm-bindgenentry point in response to a JS event; - buffers rendered ANSI bytes in memory rather than writing to a
descriptor; call
take_outputonce per animation frame to drain them.
Implementations§
Source§impl TerminalWasm
impl TerminalWasm
Sourcepub const fn new(width: u16, height: u16) -> Self
pub const fn new(width: u16, height: u16) -> Self
Creates a new backend with the given initial size in cells.
§Examples
The push-input/pull-ANSI cycle this backend is built around: push a synthetic key event
via Input::push_event, draw a frame, then pull the rendered ANSI bytes back out with
take_output.
use retroglyph_core::backend::Input;
use retroglyph_core::event::{Event, KeyCode, KeyEvent, KeyModifiers};
use retroglyph_core::color::Style;
use retroglyph_core::terminal::Terminal;
use retroglyph_terminal_wasm::TerminalWasm;
let mut backend = TerminalWasm::new(10, 3);
backend.push_event(Event::Key(KeyEvent::new(KeyCode::Char('q'), KeyModifiers::NONE)));
let mut term = Terminal::new(backend);
assert_eq!(
term.poll(std::time::Duration::ZERO),
Some(Event::Key(KeyEvent::new(KeyCode::Char('q'), KeyModifiers::NONE)))
);
term.draw(|s| s.put((0, 0), '@', Style::default()))?;
let ansi = term.backend_mut().take_output();
assert!(ansi.contains('@'), "output: {ansi:?}");Sourcepub fn take_output(&mut self) -> String
pub fn take_output(&mut self) -> String
Drains and returns the ANSI bytes rendered since the last call, as a UTF-8 string.
Returns an empty string if nothing has been drawn since the last call. Call this once per animation frame from JS and write the result into the terminal emulator.
This allocates a fresh String every call (the replacement buffer left behind is
pre-sized to the outgoing one’s capacity, so a steady frame rate converges to one
right-sized allocation per frame instead of regrowing from empty each time; see
retroglyph#287). Callers that can reuse a long-lived, JS-side buffer across frames
should prefer take_output_into instead, which never
allocates on the hot path.
Sourcepub fn take_output_into(&mut self, buf: &mut String)
pub fn take_output_into(&mut self, buf: &mut String)
Drains the ANSI bytes rendered since the last call into buf, clearing buf first.
Equivalent to *buf = self.take_output() but reuses buf’s existing allocation instead
of returning a new String each call, and leaves this backend’s own internal buffer
capacity untouched (just cleared) for the next frame, so neither side allocates once
buf has grown to its steady-state size. Intended for callers holding a long-lived
buffer across frames (e.g. a JS-side driver reusing the same String every animation
frame) instead of receiving a fresh allocation from take_output
each time.
§Examples
use retroglyph_core::color::Style;
use retroglyph_core::terminal::Terminal;
use retroglyph_terminal_wasm::TerminalWasm;
let mut term = Terminal::new(TerminalWasm::new(10, 3));
term.draw(|s| s.put((0, 0), '@', Style::default()))?;
let mut buf = String::from("stale contents");
term.backend_mut().take_output_into(&mut buf);
assert!(buf.contains('@'), "buf: {buf:?}");
assert!(!buf.contains("stale"));Trait Implementations§
Source§impl Cursor for TerminalWasm
impl Cursor for TerminalWasm
Source§fn set_cursor_style(&mut self, style: CursorStyle)
fn set_cursor_style(&mut self, style: CursorStyle)
Writes the DECSCUSR cursor-shape escape.
This is the standard VT100/ANSI (DEC private mode) cursor-shape sequence and is not one of
the areas where browser terminal emulators diverge: both xterm.js
(https://xtermjs.org/docs/api/vtfeatures/) and hterm/Terminalemulator
(https://chromium.googlesource.com/apps/libapps/+/HEAD/hterm/docs/ControlSequences.md)
implement CSI Ps SP q identically.
Source§fn set_cursor_visible(&mut self, visible: bool)
fn set_cursor_visible(&mut self, visible: bool)
Source§fn set_cursor_position(&mut self, position: Pos)
fn set_cursor_position(&mut self, position: Pos)
Source§impl Input for TerminalWasm
impl Input for TerminalWasm
Source§fn push_event(&mut self, event: Event)
fn push_event(&mut self, event: Event)
The sole public way to push an event onto a TerminalWasm; forwards to the crate-private
inherent push_event.
Source§impl Output for TerminalWasm
impl Output for TerminalWasm
Source§fn draw_layers<'a, I>(&mut self, content: I) -> Result<(), Self::Error>
fn draw_layers<'a, I>(&mut self, content: I) -> Result<(), Self::Error>
Source§fn flush(&mut self) -> Result<(), Self::Error>
fn flush(&mut self) -> Result<(), Self::Error>
Source§fn draw<'a, I>(&mut self, content: I) -> Result<(), Self::Error>
fn draw<'a, I>(&mut self, content: I) -> Result<(), Self::Error>
Source§fn needs_full_frame(&self) -> bool
fn needs_full_frame(&self) -> bool
true if the backend needs the entire frame (all cells on
all layers) on every call to draw_layers, rather
than just the changed cells. Read moreSource§fn composites_layers(&self) -> bool
fn composites_layers(&self) -> bool
draw_layers. Read more