a73x

9d6c13c8

Add cursor cache rebuild logic

a73x   2026-04-08 19:20


diff --git a/src/main.zig b/src/main.zig
index d3b59bc..36cb8a9 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -711,6 +711,40 @@ test "repackRowCaches keeps cursor span explicit for empty and non-empty cursor 
    try std.testing.expectEqualDeep([2]f32{ 9.0, 10.0 }, packed_instances.items[2].cell_pos);
}

test "rebuildCursorInstances emits visible cursor instance without changing layout state when count is unchanged" {
    var cache = RenderCache.empty;
    defer cache.deinit(std.testing.allocator);

    cache.cursor_instances = try makeTestInstances(std.testing.allocator, 1);
    cache.cursor_instances.items[0].cell_pos = .{ 99.0, 99.0 };
    cache.layout_dirty = false;

    var cursor_instances = try makeTestInstances(std.testing.allocator, 1);
    defer cursor_instances.deinit(std.testing.allocator);
    cursor_instances.items[0].cell_pos = .{ 4.0, 7.0 };

    const rebuilt = try cache.rebuildCursorInstances(std.testing.allocator, cursor_instances.items);

    try std.testing.expect(!rebuilt.len_changed);
    try std.testing.expectEqual(@as(usize, 1), cache.cursor_instances.items.len);
    try std.testing.expectEqualDeep([2]f32{ 4.0, 7.0 }, cache.cursor_instances.items[0].cell_pos);
    try std.testing.expect(!cache.layout_dirty);
}

test "rebuildCursorInstances marks layout dirty when cursor instance count changes" {
    var cache = RenderCache.empty;
    defer cache.deinit(std.testing.allocator);

    cache.cursor_instances = try makeTestInstances(std.testing.allocator, 1);
    cache.layout_dirty = false;

    const rebuilt = try cache.rebuildCursorInstances(std.testing.allocator, &.{});

    try std.testing.expect(rebuilt.len_changed);
    try std.testing.expectEqual(@as(usize, 0), cache.cursor_instances.items.len);
    try std.testing.expect(cache.layout_dirty);
}

test "rebuildRowInstances emits expected instances for a colored glyph row" {
    var term = try vt.Terminal.init(std.testing.allocator, .{
        .cols = 80,
@@ -1012,6 +1046,23 @@ const RenderCache = struct {
        self.total_instance_count = 0;
        self.layout_dirty = true;
    }

    fn rebuildCursorInstances(
        self: *RenderCache,
        alloc: std.mem.Allocator,
        cursor_instances: []const renderer.Instance,
    ) !RowRebuildResult {
        const old_len = self.cursor_instances.items.len;
        self.cursor_instances.clearRetainingCapacity();
        try self.cursor_instances.appendSlice(alloc, cursor_instances);

        const len_changed = markLayoutDirtyOnLenChange(old_len, self.cursor_instances.items.len);
        if (len_changed) self.layout_dirty = true;

        return .{
            .len_changed = len_changed,
        };
    }
};

const RowPackResult = struct {