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
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
@type changed() :: :all | [{non_neg_integer(), non_neg_integer()}]
What changed: every cell, or the positions of the cells that did.
@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
@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
@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]})
@spec cell(t(), non_neg_integer(), non_neg_integer()) :: ExRatatui.CellSession.Cell.t() | nil
The cell at {col, row}, or nil when no payload has set it.
Examples
iex> RasterExRatatui.Grid.cell(RasterExRatatui.Grid.new(), 0, 0)
nil
@spec new() :: t()
An empty grid, 0×0 with no regions.
Examples
iex> RasterExRatatui.Grid.new()
%RasterExRatatui.Grid{width: 0, height: 0, cells: %{}, regions: []}
@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"