Skip to main content

Module frame

Module frame 

Source
Expand description

What one frame’s rows are as a change from the frame before’s.

A binding answers every gesture with a frame — the rows to paint, and where the caret is among them — and lifting a whole frame across a boundary (UniFFI records into Swift, serde into JS objects) costs the document, not the gesture: on a long document the lift is most of a keystroke and all of a click. Both renderers already keep the rows a frame did not change, so what is left to make cheap is the crossing, and the way to do that is to cross only the rows that changed.

A binding does not need to know why rows changed to know which did. It keeps the rows it last handed out and takes the common prefix and suffix against the ones it is about to: comparing a few hundred rows in memory is microseconds, and what falls between is exactly the span a renderer diffing whole frames would have found for itself. The one wrinkle is that a row carries the source offset each of its runs came from, and a keystroke moves every offset after it — so read by ==, every row below an edit is a different row, and the “span” is half the document. A row after the edit is the same row moved, and the suffix is matched on that footing: equal in everything, with its offsets shifted by one constant, which the frame then carries so the renderer moves its own copies the same way. The shift is read off the rows and checked on every row it is claimed for, never assumed from the edit, so a frame reproduces the rows exactly or names the row as changed.

This module is the algorithm; each binding supplies what “the same row, shifted” means for its own row type, and the fields the frame carries the answer in are documented on the binding’s DocView.

Structs§

RowDelta
Where two frames’ rows differ: the span of the old rows a span of the new ones replaces, and the offset the rows after it moved by. See row_delta.

Functions§

apply_row_delta
Apply delta — with the rows span it stands for — to rows, the frame before’s, so they become the frame’s: the reference for what a renderer does with the fields, and what the bindings’ tests apply a sequence of frames with. shift(row, by) moves every offset the row carries.
row_delta
The change from old to new, as the span outside their common prefix and suffix.