use "collections"
primitive Differ
"""
Cell-by-cell frame differencing.
"""
fun diff(prev: Grid, curr: Grid): Array[(USize, USize, Cell)] val =>
"""
Compare two grids cell-by-cell and return (col, row, Cell) for each
changed cell. If dimensions differ, treat as full redraw of curr.
"""
if (prev.width != curr.width) or (prev.height != curr.height) then
_full_redraw(curr)
else
recover val
let changes = Array[(USize, USize, Cell)]
for row in Range(0, curr.height) do
for col in Range(0, curr.width) do
match (prev(col, row), curr(col, row))
| (let p: Cell, let c: Cell) =>
if p != c then
changes.push((col, row, c))
end
end
end
end
changes
end
end
fun _full_redraw(curr: Grid): Array[(USize, USize, Cell)] val =>
recover val
let changes = Array[(USize, USize, Cell)]
for row in Range(0, curr.height) do
for col in Range(0, curr.width) do
match curr(col, row)
| let c: Cell => changes.push((col, row, c))
end
end
end
changes
end