Architecture
Pipeline
Data flows in one direction through a fixed pipeline:
Each step has a single responsibility. Nothing flows backwards.
GridState
GridState is the central structure. It holds three sub-states:
All mutations go through GridState::apply(GridCommand). Direct field
mutation is not exposed. This makes the state easy to snapshot and replay.
Commands
GridCommand is an enum of all possible mutations:
Commands are cheap to construct and can be queued. The renderer calls apply
once per animation frame with any pending commands.
SceneFrame
SceneBuilder::build(&grid_state) returns a SceneFrame — a flat list of
ScenePrimitive values that describe exactly what should appear on screen:
Rect— filled rectangle (cell background, selection highlight)Text— cell label with font, color, and clipping boundsLine— grid border line
The scene is renderer-agnostic. You can implement a new backend (WebGL, SVG,
terminal) by consuming SceneFrame without touching core.
Crate dependency graph
Adding a renderer
-
Create a new crate
Add
rs-grid-sceneas a dependency. -
Consume SceneFrame
Call
SceneBuilder::build(&grid_state)to get aSceneFrame, then iterate overSceneFrame::primitives. -
Issue draw calls
Map each
ScenePrimitive(Rect, Text, Line) to your backend's API.
Do not modify rs-grid-core or rs-grid-scene when adding a renderer.
These crates must remain WASM-free and testable with plain cargo test.