//! Renderer which holds the screen to compare with the previous screen for efficient rendering. const std = @import("std"); const terminal = @import("terminal.zig"); const Contents = std.ArrayList(u8); const Position = terminal.Position; const Size = terminal.Size; pub fn Buffered(comptime fullscreen: bool) type { return struct { refresh: bool = false, size: terminal.Size = undefined, screen: Contents = undefined, pub fn init(allocator: std.mem.Allocator) @This() { return .{ .fullscreen = fullscreen, .screen = Contents.init(allocator), }; } pub fn deinit(this: *@This()) void { this.screen.deinit(); this.* = undefined; } pub fn resize(this: *@This(), size: Size) void { // TODO: are there size changes which impact the corresponding rendered content? // -> can I even be sure nothing needs to be re-rendered? this.size = size; this.refresh = true; } pub fn render(this: *@This(), content: *Contents) !void { // TODO: put the corresponding screen to the terminal // -> determine diff between screen and new content and only update the corresponding characters of the terminal _ = this; _ = content; @panic("Not yet implemented."); } }; } pub fn Plain(comptime _: bool) type { return struct { pub fn clear(this: @This(), anchor: Position, size: Size) !void { _ = this; _ = size; // NOTE: clear entire screen for the first content (derived from the anchor being at the very left-top) if (anchor.col == 1 and anchor.row == 1) { try terminal.clearScreen(); } } pub fn render(this: @This(), anchor: Position, size: Size, contents: *Contents) !void { _ = this; _ = size; // FIXME: this should respect the given `size` try terminal.setCursorPosition(anchor); _ = try terminal.write(contents.items); } }; }