mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-04-06 07:38:21 +00:00
vt: add render_row_iterator_next
This commit is contained in:
@@ -227,6 +227,20 @@ GhosttyResult ghostty_render_state_row_iterator_new(
|
||||
GhosttyRenderState state,
|
||||
GhosttyRenderStateRowIterator* out_iterator);
|
||||
|
||||
/**
|
||||
* Move a render-state row iterator to the next row.
|
||||
*
|
||||
* Returns true if the iterator moved successfully and row data is
|
||||
* available to read at the new position.
|
||||
*
|
||||
* @param iterator The iterator handle to advance (may be NULL)
|
||||
* @return true if advanced to the next row, false if `iterator` is
|
||||
* NULL or if the iterator has reached the end
|
||||
*
|
||||
* @ingroup render
|
||||
*/
|
||||
bool ghostty_render_state_row_iterator_next(GhosttyRenderStateRowIterator iterator);
|
||||
|
||||
/**
|
||||
* Free a render-state row iterator.
|
||||
*
|
||||
|
||||
@@ -194,6 +194,7 @@ comptime {
|
||||
@export(&c.render_state_dirty_get, .{ .name = "ghostty_render_state_dirty_get" });
|
||||
@export(&c.render_state_dirty_set, .{ .name = "ghostty_render_state_dirty_set" });
|
||||
@export(&c.render_state_row_iterator_new, .{ .name = "ghostty_render_state_row_iterator_new" });
|
||||
@export(&c.render_state_row_iterator_next, .{ .name = "ghostty_render_state_row_iterator_next" });
|
||||
@export(&c.render_state_row_iterator_free, .{ .name = "ghostty_render_state_row_iterator_free" });
|
||||
@export(&c.render_state_free, .{ .name = "ghostty_render_state_free" });
|
||||
@export(&c.terminal_new, .{ .name = "ghostty_terminal_new" });
|
||||
|
||||
@@ -44,6 +44,7 @@ pub const render_state_colors_get = render.colors_get;
|
||||
pub const render_state_dirty_get = render.dirty_get;
|
||||
pub const render_state_dirty_set = render.dirty_set;
|
||||
pub const render_state_row_iterator_new = render.row_iterator_new;
|
||||
pub const render_state_row_iterator_next = render.row_iterator_next;
|
||||
pub const render_state_row_iterator_free = render.row_iterator_free;
|
||||
|
||||
pub const sgr_new = sgr.new;
|
||||
|
||||
@@ -20,7 +20,7 @@ const RowIteratorWrapper = struct {
|
||||
alloc: std.mem.Allocator,
|
||||
|
||||
/// The current index (also y value) into the row list.
|
||||
y: size.CellCountInt,
|
||||
y: ?size.CellCountInt,
|
||||
|
||||
/// These are the raw pointers into the render state data.
|
||||
raws: []const page.Row,
|
||||
@@ -69,6 +69,13 @@ fn new_(alloc_: ?*const CAllocator) error{OutOfMemory}!*RenderStateWrapper {
|
||||
return ptr;
|
||||
}
|
||||
|
||||
pub fn free(state_: RenderState) callconv(.c) void {
|
||||
const state = state_ orelse return;
|
||||
const alloc = state.alloc;
|
||||
state.state.deinit(alloc);
|
||||
alloc.destroy(state);
|
||||
}
|
||||
|
||||
pub fn update(
|
||||
state_: RenderState,
|
||||
terminal_: terminal_c.Terminal,
|
||||
@@ -208,7 +215,7 @@ fn row_iterator_new_(
|
||||
const row_data = state.state.row_data.slice();
|
||||
it.* = .{
|
||||
.alloc = alloc,
|
||||
.y = 0,
|
||||
.y = null,
|
||||
.raws = row_data.items(.raw),
|
||||
.cells = row_data.items(.cells),
|
||||
.dirty = row_data.items(.dirty),
|
||||
@@ -223,11 +230,12 @@ pub fn row_iterator_free(iterator_: RowIterator) callconv(.c) void {
|
||||
alloc.destroy(iterator);
|
||||
}
|
||||
|
||||
pub fn free(state_: RenderState) callconv(.c) void {
|
||||
const state = state_ orelse return;
|
||||
const alloc = state.alloc;
|
||||
state.state.deinit(alloc);
|
||||
alloc.destroy(state);
|
||||
pub fn row_iterator_next(iterator_: RowIterator) callconv(.c) bool {
|
||||
const it = iterator_ orelse return false;
|
||||
const next_y: size.CellCountInt = if (it.y) |y| y + 1 else 0;
|
||||
if (next_y >= it.raws.len) return false;
|
||||
it.y = next_y;
|
||||
return true;
|
||||
}
|
||||
|
||||
test "render: new/free" {
|
||||
@@ -410,7 +418,7 @@ test "render: row iterator new/free" {
|
||||
const iterator_ptr = iterator.?;
|
||||
const row_data = state.?.state.row_data.slice();
|
||||
|
||||
try testing.expectEqual(@as(size.CellCountInt, 0), iterator_ptr.y);
|
||||
try testing.expectEqual(@as(?size.CellCountInt, null), iterator_ptr.y);
|
||||
try testing.expectEqual(row_data.items(.raw).len, iterator_ptr.raws.len);
|
||||
try testing.expectEqual(row_data.items(.cells).len, iterator_ptr.cells.len);
|
||||
try testing.expectEqual(row_data.items(.dirty).len, iterator_ptr.dirty.len);
|
||||
@@ -420,6 +428,59 @@ test "render: row iterator free null" {
|
||||
row_iterator_free(null);
|
||||
}
|
||||
|
||||
test "render: row iterator next null" {
|
||||
try testing.expect(!row_iterator_next(null));
|
||||
}
|
||||
|
||||
test "render: row iterator next" {
|
||||
var terminal: terminal_c.Terminal = null;
|
||||
try testing.expectEqual(Result.success, terminal_c.new(
|
||||
&lib_alloc.test_allocator,
|
||||
&terminal,
|
||||
.{
|
||||
.cols = 80,
|
||||
.rows = 24,
|
||||
.max_scrollback = 10_000,
|
||||
},
|
||||
));
|
||||
defer terminal_c.free(terminal);
|
||||
|
||||
var state: RenderState = null;
|
||||
try testing.expectEqual(Result.success, new(
|
||||
&lib_alloc.test_allocator,
|
||||
&state,
|
||||
));
|
||||
defer free(state);
|
||||
|
||||
try testing.expectEqual(Result.success, update(state, terminal));
|
||||
|
||||
var iterator: RowIterator = null;
|
||||
try testing.expectEqual(Result.success, row_iterator_new(
|
||||
&lib_alloc.test_allocator,
|
||||
state,
|
||||
&iterator,
|
||||
));
|
||||
defer row_iterator_free(iterator);
|
||||
|
||||
const rows = state.?.state.rows;
|
||||
if (rows == 0) {
|
||||
try testing.expect(!row_iterator_next(iterator));
|
||||
return;
|
||||
}
|
||||
|
||||
try testing.expect(row_iterator_next(iterator));
|
||||
try testing.expectEqual(@as(?size.CellCountInt, 0), iterator.?.y);
|
||||
|
||||
var i: size.CellCountInt = 1;
|
||||
while (i < rows) : (i += 1) {
|
||||
try testing.expect(row_iterator_next(iterator));
|
||||
try testing.expectEqual(@as(?size.CellCountInt, i), iterator.?.y);
|
||||
}
|
||||
|
||||
try testing.expect(!row_iterator_next(iterator));
|
||||
try testing.expectEqual(@as(?size.CellCountInt, rows - 1), iterator.?.y);
|
||||
}
|
||||
|
||||
test "render: update" {
|
||||
var terminal: terminal_c.Terminal = null;
|
||||
try testing.expectEqual(Result.success, terminal_c.new(
|
||||
|
||||
Reference in New Issue
Block a user