add(testing): new namespace containing testing capabilities for zterm
Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 39s

The namespace shall also be used for testing the rendering of
`Container`s and `Element`s (including the `Scrollable` element).

The testing renderer currently is a striped down version of the double
buffered render without the secondary buffer and the flushing to stdout.
The internal `Cell` slice (the *screen*) is used for equality checks.

The testing namespace shall provide a way to describe the expected
`Cell` slices that should be validated against.
This commit is contained in:
2025-02-24 17:14:57 +01:00
parent 5c5c59cbfc
commit 33262c9638
6 changed files with 180 additions and 19 deletions

View File

@@ -7,8 +7,6 @@ const Size = @import("size.zig").Size;
/// Double-buffered intermediate rendering pipeline
pub const Buffered = struct {
const log = std.log.scoped(.renderer_buffered);
// _ = log;
allocator: std.mem.Allocator,
created: bool,
size: Size,
@@ -33,21 +31,22 @@ pub const Buffered = struct {
}
pub fn resize(this: *@This(), size: Size) !void {
log.debug("renderer::resize", .{});
defer this.size = size;
this.size = size;
const n = @as(usize, size.cols) * @as(usize, size.rows);
if (!this.created) {
this.screen = this.allocator.alloc(Cell, @as(usize, size.cols) * @as(usize, size.rows)) catch @panic("render.zig: Out of memory.");
@memset(this.screen, .{});
this.virtual_screen = this.allocator.alloc(Cell, @as(usize, size.cols) * @as(usize, size.rows)) catch @panic("render.zig: Out of memory.");
this.screen = this.allocator.alloc(Cell, n) catch @panic("render.zig: Out of memory.");
this.virtual_screen = this.allocator.alloc(Cell, n) catch @panic("render.zig: Out of memory.");
@memset(this.virtual_screen, .{});
this.created = true;
} else {
this.allocator.free(this.screen);
this.screen = this.allocator.alloc(Cell, @as(usize, size.cols) * @as(usize, size.rows)) catch @panic("render.zig: Out of memory.");
@memset(this.screen, .{});
this.screen = this.allocator.alloc(Cell, n) catch @panic("render.zig: Out of memory.");
this.allocator.free(this.virtual_screen);
this.virtual_screen = this.allocator.alloc(Cell, @as(usize, size.cols) * @as(usize, size.rows)) catch @panic("render.zig: Out of memory.");
this.virtual_screen = this.allocator.alloc(Cell, n) catch @panic("render.zig: Out of memory.");
@memset(this.virtual_screen, .{});
}
try this.clear();
@@ -55,7 +54,6 @@ pub const Buffered = struct {
/// Clear the entire screen and reset the screen buffer, to force a re-draw with the next `flush` call.
pub fn clear(this: *@This()) !void {
log.debug("renderer::clear", .{});
try terminal.clearScreen();
@memset(this.screen, .{});
}
@@ -85,15 +83,12 @@ pub const Buffered = struct {
// free immediately
container.allocator.free(cells);
for (container.elements.items) |*element| {
try this.render(T, element);
}
for (container.elements.items) |*element| try this.render(T, element);
}
/// Write *virtual screen* to alternate screen (should be called once and last during each render loop iteration in the main loop).
pub fn flush(this: *@This()) !void {
// TODO: measure timings of rendered frames?
log.debug("renderer::flush", .{});
const writer = terminal.writer();
const s = this.screen;
const vs = this.virtual_screen;