drawBatch method
override
Optimally draws a batch of cells
at the given start
position.
The width
parameter is used to determine when to move to the next line,
and if not provided, it defaults to the terminal width.
This method is more efficient than calling draw multiple times, and can reduce the number of ANSI escape sequences written to the terminal.
Implementation
@override
@nonVirtual
void drawBatch(
Iterable<Cell> cells, {
Offset start = Offset.zero,
int? width,
}) {
// Move the cursor to the start position and write a reset sequence.
moveCursorTo(start.x, start.y);
// TODO: Use dual-buffering instead of this one-off implementation.
//
// With dual-buffering we could remove the "drawBatch" method entirely, and
// stage all changes to the buffer in a separate buffer. Then, when the
// "flush" method is called, we would compare the two buffers and only write
// the necessary changes to the terminal. This would allow us to avoid
// writing the entire buffer to the terminal on every frame, and instead
// only write the changes.
final buffer = StringBuffer();
void writeSeq(Sequence seq) {
buffer.write(seq.toEscapedString());
}
writeSeq(resetStyle.toSequence());
// Determine the width of the batch.
width ??= size.$1 - 1;
var fg = Color.reset;
var bg = Color.reset;
var count = 0;
final list = List.of(cells);
for (final cell in list) {
// If the width has been reached, move to the next line.
if (count > width) {
count = 1;
buffer.writeln();
} else {
count++;
}
// If the style has changed, write a new style sequence.
if (cell.style.foreground case final Color color when color != fg) {
fg = color;
buffer.write(fg.setForeground().toSequence().toEscapedString());
}
if (cell.style.background case final Color color when color != bg) {
bg = color;
buffer.write(bg.setBackground().toSequence().toEscapedString());
}
// Write the content of the cell.
buffer.write(cell.symbol);
}
// Write the buffer to the terminal.
writer.write(utf8.encode(buffer.toString()));
}