diff options
| author | Mitchell Hashimoto <m@mitchellh.com> | 2025-08-06 09:52:41 -0700 |
|---|---|---|
| committer | Mitchell Hashimoto <m@mitchellh.com> | 2025-08-07 08:14:02 -0700 |
| commit | fa08434b28580229c39082dc4f1de6731ed0ed3b (patch) | |
| tree | b104f16828a52aed913d3082c86a484696bff7c2 /src/datastruct/split_tree.zig | |
| parent | ad1cfe8347144575e65f590cdd6ca83badc4dd21 (diff) | |
apprt/gtk-ng: initial GhosttySplitTree widget
Diffstat (limited to 'src/datastruct/split_tree.zig')
| -rw-r--r-- | src/datastruct/split_tree.zig | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/src/datastruct/split_tree.zig b/src/datastruct/split_tree.zig index 9cd929faa..759387073 100644 --- a/src/datastruct/split_tree.zig +++ b/src/datastruct/split_tree.zig @@ -37,6 +37,9 @@ const Allocator = std.mem.Allocator; /// for the debug view. If this isn't specified then the node handle /// will be used. /// +/// Note: for both the ref and unref functions, the allocator is optional. +/// If the functions take less arguments, then the allocator will not be +/// passed. pub fn SplitTree(comptime V: type) type { return struct { const Self = @This(); @@ -88,8 +91,8 @@ pub fn SplitTree(comptime V: type) type { const alloc = arena.allocator(); const nodes = try alloc.alloc(Node, 1); - nodes[0] = .{ .leaf = try view.ref(gpa) }; - errdefer view.unref(gpa); + nodes[0] = .{ .leaf = try viewRef(view, gpa) }; + errdefer viewUnref(view, gpa); return .{ .arena = arena, @@ -104,7 +107,7 @@ pub fn SplitTree(comptime V: type) type { // Unref all our views const gpa: Allocator = self.arena.child_allocator; for (self.nodes) |node| switch (node) { - .leaf => |view| view.unref(gpa), + .leaf => |view| viewUnref(view, gpa), .split => {}, }; self.arena.deinit(); @@ -113,6 +116,12 @@ pub fn SplitTree(comptime V: type) type { self.* = undefined; } + /// Returns true if this is an empty tree. + pub fn isEmpty(self: *const Self) bool { + // An empty tree has no nodes. + return self.nodes.len == 0; + } + /// An iterator over all the views in the tree. pub fn iterator( self: *const Self, @@ -367,13 +376,13 @@ pub fn SplitTree(comptime V: type) type { errdefer for (0..reffed) |i| { switch (nodes[i]) { .split => {}, - .leaf => |view| view.unref(gpa), + .leaf => |view| viewUnref(view, gpa), } }; for (0..nodes.len) |i| { switch (nodes[i]) { .split => {}, - .leaf => |view| nodes[i] = .{ .leaf = try view.ref(gpa) }, + .leaf => |view| nodes[i] = .{ .leaf = try viewRef(view, gpa) }, } reffed = i; } @@ -658,6 +667,24 @@ pub fn SplitTree(comptime V: type) type { try writer.writeAll(row); } } + + fn viewRef(view: *View, gpa: Allocator) Allocator.Error!*View { + const func = @typeInfo(@TypeOf(View.ref)).@"fn"; + return switch (func.params.len) { + 1 => view.ref(), + 2 => try view.ref(gpa), + else => @compileError("invalid view ref function"), + }; + } + + fn viewUnref(view: *View, gpa: Allocator) void { + const func = @typeInfo(@TypeOf(View.unref)).@"fn"; + switch (func.params.len) { + 1 => view.unref(), + 2 => view.unref(gpa), + else => @compileError("invalid view unref function"), + } + } }; } |
