terminal: dirty tracking on screen clone

This commit is contained in:
Mitchell Hashimoto
2024-04-28 10:46:39 -07:00
parent 3f9e3c39a4
commit d47f14f86a
2 changed files with 46 additions and 6 deletions

View File

@ -2962,6 +2962,11 @@ pub fn isDirty(self: *const PageList, pt: point.Point) bool {
return self.getCell(pt).?.isDirty(); return self.getCell(pt).?.isDirty();
} }
/// Mark a point as dirty, used for testing.
fn markDirty(self: *PageList, pt: point.Point) void {
self.pin(pt).?.markDirty();
}
/// Represents an exact x/y coordinate within the screen. This is called /// Represents an exact x/y coordinate within the screen. This is called
/// a "pin" because it is a fixed point within the pagelist direct to /// a "pin" because it is a fixed point within the pagelist direct to
/// a specific page pointer and memory offset. The benefit is that this /// a specific page pointer and memory offset. The benefit is that this
@ -3020,8 +3025,12 @@ pub const Pin = struct {
).?.*; ).?.*;
} }
/// Check if this pin is dirty.
pub fn isDirty(self: Pin) bool {
return self.page.data.isRowDirty(self.y);
}
/// Mark this pin location as dirty. /// Mark this pin location as dirty.
/// TODO: test
pub fn markDirty(self: Pin) void { pub fn markDirty(self: Pin) void {
var set = self.page.data.dirtyBitSet(); var set = self.page.data.dirtyBitSet();
set.set(self.y); set.set(self.y);
@ -4830,6 +4839,32 @@ test "PageList clone remap tracked pin not in cloned area" {
try testing.expect(pin_remap.get(p) == null); try testing.expect(pin_remap.get(p) == null);
} }
test "PageList clone full dirty" {
const testing = std.testing;
const alloc = testing.allocator;
var s = try init(alloc, 80, 24, null);
defer s.deinit();
try testing.expectEqual(@as(usize, s.rows), s.totalRows());
// Mark a row as dirty
s.markDirty(.{ .active = .{ .x = 0, .y = 0 } });
s.markDirty(.{ .active = .{ .x = 0, .y = 12 } });
s.markDirty(.{ .active = .{ .x = 0, .y = 23 } });
var s2 = try s.clone(.{
.top = .{ .screen = .{} },
.memory = .{ .alloc = alloc },
});
defer s2.deinit();
try testing.expectEqual(@as(usize, s.rows), s2.totalRows());
// Should still be dirty
try testing.expect(s2.isDirty(.{ .active = .{ .x = 0, .y = 0 } }));
try testing.expect(s2.isDirty(.{ .active = .{ .x = 0, .y = 12 } }));
try testing.expect(s2.isDirty(.{ .active = .{ .x = 0, .y = 23 } }));
}
test "PageList resize (no reflow) more rows" { test "PageList resize (no reflow) more rows" {
const testing = std.testing; const testing = std.testing;
const alloc = testing.allocator; const alloc = testing.allocator;

View File

@ -500,11 +500,16 @@ pub const Page = struct {
const other_rows = other.rows.ptr(other.memory)[y_start..y_end]; const other_rows = other.rows.ptr(other.memory)[y_start..y_end];
const rows = self.rows.ptr(self.memory)[0 .. y_end - y_start]; const rows = self.rows.ptr(self.memory)[0 .. y_end - y_start];
for (rows, other_rows) |*dst_row, *src_row| try self.cloneRowFrom( for (rows, other_rows) |*dst_row, *src_row| {
other, try self.cloneRowFrom(other, dst_row, src_row);
dst_row, }
src_row,
); // Set our dirty range for all the rows we copied
var dirty_set = self.dirtyBitSet();
dirty_set.setRangeValue(.{
.start = 0,
.end = y_end - y_start,
}, true);
// We should remain consistent // We should remain consistent
self.assertIntegrity(); self.assertIntegrity();