r3bl-open-core
r3bl-open-core copied to clipboard
Add compositor to tui framework
Problem
Currently RenderOps
and RenderPipline
end up generating crossterm commands which are transmitted to stdout
.
- There is an inefficiency w/ this approach since
ZOrder
can't be handled efficiently. - It is currently handled by fully flushing crossterm commands at a higher
ZOrder
followed by a lowerZOrder
and so on. - Take an ex of a modal dialog, which requires some inefficient painting to
stdout
for eachZOrder
that has to be rendered. - To make things worse, crossterm is slow, and when using bg color styled text, or lots of fg_colors (eg: lolcat) it just falls on its face and flickers like crazy and this is unacceptable. The compositor should fix this by only painting diffs.
One solution is to create a compositor that takes the RenderPipeline
and translates it into an intermediate representation (IR) which is quite simply a 2d array of PixelChar
. A PixelChar
is a struct that is defined as:
-
GraphemeSegment
- style information (from style: fg_color, bg_color)
- attrib information (from style: bold, italic, etc)
There are as many PixelChars
as there are window_size.col * window_size.row.
So the RenderPipeline
has to be rasterized into a grid of PixelChars
. Then this grid can be painted using whatever output device & library:
- crossterm
- termion
- webgl
- icedrs
One other thing that changes between these different outputs is the way input is captured. However, all that input can be normalized to a generic
InputEvent
type that currently exists today.
Notes
Might also need to use a diffing library like imara-diff to calculate the diffs between a sequence of
PixelChar
grids.
- https://www.reddit.com/r/rust/comments/ydi7xu/announcing_imaradiff_a_reliably_performant/
- https://github.com/pascalkuthe/imara-diff
Here's another rasterizer built atop termion
- https://github.com/nazmulidris/rust-sloth