RasterExRatatui.Grid (RasterExRatatui v0.4.0)

Copy Markdown View Source

The current frame of an ExRatatui.CellSession, as a cell map plus the list of pixel regions on screen.

A CellSession hands out a %Snapshot{} (every cell) or a %Diff{} (only the cells that changed since the last one). The grid folds either into a map keyed by {col, row} and reports what changed, which is what lets RasterExRatatui.Raster rasterise only those cells.

Regions are never merged: every payload carries the complete list of regions on screen (see ExRatatui.CellSession.Region), so the payload's list replaces the grid's outright.

Examples

iex> alias ExRatatui.CellSession.{Cell, Diff}
iex> alias RasterExRatatui.Grid
iex> full = %Diff{width: 2, height: 1, ops: [%Cell{col: 0, symbol: "a"}, %Cell{col: 1, symbol: "b"}]}
iex> {grid, :all, false} = Grid.apply_diff(Grid.new(), full)
iex> {grid, [{1, 0}], false} = Grid.apply_diff(grid, %Diff{width: 2, height: 1, ops: [%Cell{col: 1, symbol: "c"}]})
iex> Grid.cell(grid, 1, 0).symbol
"c"

Summary

Types

What changed: every cell, or the positions of the cells that did.

t()

Functions

Folds a snapshot or a diff into the grid; see put_snapshot/2 and apply_diff/2.

Merges a diff's cells into the grid and replaces its regions.

The cell at {col, row}, or nil when no payload has set it.

An empty grid, 0×0 with no regions.

Replaces the grid with a snapshot's cells and regions. Everything counts as changed.

Types

changed()

@type changed() :: :all | [{non_neg_integer(), non_neg_integer()}]

What changed: every cell, or the positions of the cells that did.

t()

@type t() :: %RasterExRatatui.Grid{
  cells: %{
    required({non_neg_integer(), non_neg_integer()}) =>
      ExRatatui.CellSession.Cell.t()
  },
  height: non_neg_integer(),
  regions: [ExRatatui.CellSession.Region.t()],
  width: non_neg_integer()
}

Functions

apply(grid, snapshot)

@spec apply(t(), ExRatatui.CellSession.Snapshot.t() | ExRatatui.CellSession.Diff.t()) ::
  {t(), changed(), regions_changed? :: boolean()}

Folds a snapshot or a diff into the grid; see put_snapshot/2 and apply_diff/2.

Examples

iex> alias ExRatatui.CellSession.Snapshot
iex> {_grid, changed, _} = RasterExRatatui.Grid.apply(RasterExRatatui.Grid.new(), %Snapshot{width: 1, height: 1})
iex> changed
:all

apply_diff(grid, diff)

@spec apply_diff(t(), ExRatatui.CellSession.Diff.t()) :: {t(), changed(), boolean()}

Merges a diff's cells into the grid and replaces its regions.

Returns {grid, changed, regions_changed?}. changed is :all for a full payload (every cell present, which a CellSession sends first, after a resize, and after a close) or when the diff's dimensions differ from the grid's; the cell map then starts over from the diff alone. Otherwise it lists the {col, row} of every op.

Examples

iex> alias ExRatatui.CellSession.{Cell, Diff, Region}
iex> alias RasterExRatatui.Grid
iex> {grid, :all, false} = Grid.apply_diff(Grid.new(), %Diff{width: 1, height: 1, ops: [%Cell{}]})
iex> region = %Region{width: 1, height: 1, pixel_width: 1, pixel_height: 1, data: <<0, 0, 0>>}
iex> {_grid, [], true} = Grid.apply_diff(grid, %Diff{width: 1, height: 1, regions: [region]})

cell(grid, col, row)

The cell at {col, row}, or nil when no payload has set it.

Examples

iex> RasterExRatatui.Grid.cell(RasterExRatatui.Grid.new(), 0, 0)
nil

new()

@spec new() :: t()

An empty grid, 0×0 with no regions.

Examples

iex> RasterExRatatui.Grid.new()
%RasterExRatatui.Grid{width: 0, height: 0, cells: %{}, regions: []}

put_snapshot(grid, snapshot)

@spec put_snapshot(t(), ExRatatui.CellSession.Snapshot.t()) :: {t(), :all, boolean()}

Replaces the grid with a snapshot's cells and regions. Everything counts as changed.

Returns {grid, :all, regions_changed?}.

Examples

iex> alias ExRatatui.CellSession.{Cell, Snapshot}
iex> snapshot = %Snapshot{width: 1, height: 1, cells: [%Cell{symbol: "x"}]}
iex> {grid, :all, false} = RasterExRatatui.Grid.put_snapshot(RasterExRatatui.Grid.new(), snapshot)
iex> RasterExRatatui.Grid.cell(grid, 0, 0).symbol
"x"