Buffer

io.worxbend.tui.core.Buffer
final class Buffer(val area: Rect)

A mutable grid of Cells covering area, the in-memory render target for one frame.

x/y arguments are absolute terminal coordinates (the same space as area's offset), not area-relative — widgets receive a Rect positioned in absolute space and write to the buffer at those coordinates. Writes outside area are silently clipped, never errors; reads outside area return Cell.Empty.

Mutability is an implementation detail of the render loop — it never escapes through Widget.render's contract.

Attributes

Graph
Supertypes
class Object
trait Matchable
class Any

Members list

Value members

Concrete methods

def blit(source: Buffer, at: Position, region: Rect): Unit

Copies region of source into this buffer with the region's top-left landing at at.

Copies region of source into this buffer with the region's top-left landing at at.

Writes outside this buffer's area are clipped like any other write — this is how offscreen-rendered content (scroll views, overlays) lands on the frame. A region reaching past source's own area is trimmed to it, and the landing point moves by however much the trim shifted the region's origin, so the surviving cells keep their position relative to at instead of sliding onto the ones that were dropped.

Blitting a buffer onto itself works on a snapshot: without it, overlapping rows would read cells this call has already overwritten and smear them across the region.

Attributes

def blit(source: Buffer, at: Position): Unit

Copies all of source into this buffer at at.

Copies all of source into this buffer at at.

Attributes

def diff(next: Buffer): Iterator[(Position, Cell)]

The cells that changed going from this buffer (the previous frame) to next (the frame to display).

The cells that changed going from this buffer (the previous frame) to next (the frame to display).

This is what a terminal backend flushes each frame instead of redrawing everything. Positions covered by the continuation cell of a wide grapheme in next are never emitted — flushing the wide cell itself repaints both columns. If the two buffers cover different areas (e.g. after a resize), every cell of next is emitted.

Attributes

def diff(next: Buffer, emit: (Int, Int, Cell) => Unit): Unit

diff without the intermediate objects: calls emit(x, y, cell) for each changed cell, in row-major order.

diff without the intermediate objects: calls emit(x, y, cell) for each changed cell, in row-major order.

This is what backends use on the hot path — it allocates nothing per cell (no Position, no tuple, no iterator state), which matters because a 200x50 frame is 10 000 cells and runs at the tick rate.

Attributes

def get(x: Int, y: Int): Cell
def reset(): Unit

Resets every cell to Cell.Empty, recycling the buffer for the next frame.

Resets every cell to Cell.Empty, recycling the buffer for the next frame.

Attributes

def set(x: Int, y: Int, cell: Cell): Unit

Writes cell at (x, y); writes outside area are silently clipped.

Writes cell at (x, y); writes outside area are silently clipped.

A write can also mutate the neighbouring cell, because a two-column grapheme owns two cells and a terminal cannot draw half of one: writing a wide cell reserves the cell to its right as its continuation; overwriting a wide cell releases the continuation it held; and writing real content over a continuation blanks the wide grapheme that owned it, since that grapheme can no longer draw across a column somebody else has claimed.

Writing Cell.Empty over a continuation is the one exception and leaves the pair intact — that pair is how callers spell the filler itself, so treating it as a claim would erase the grapheme they just wrote.

Attributes

def setString(x: Int, y: Int, text: String, style: Style): Unit

Writes text starting at (x, y), one grapheme cluster per cell, clipping at the area's right edge.

Writes text starting at (x, y), one grapheme cluster per cell, clipping at the area's right edge.

A wide (two-column) cluster occupies its cell plus a continuation cell to the right, which set reserves; a wide cluster that would only half-fit at the right edge is dropped entirely. Grapheme clusters that begin with a combining mark (no base character before them in text) are skipped.

Attributes

An independent copy of this buffer. Backends snapshot the frame they just flushed so later mutation of the caller's buffer cannot corrupt the next diff.

An independent copy of this buffer. Backends snapshot the frame they just flushed so later mutation of the caller's buffer cannot corrupt the next diff.

Attributes

Concrete fields

val area: Rect