mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-01-06 05:17:50 +00:00
datastruct: split_tree C API
This commit is contained in:
@@ -1301,6 +1301,60 @@ pub fn SplitTree(comptime V: type) type {
|
||||
|
||||
.none => void,
|
||||
};
|
||||
|
||||
/// A C-compatible API for using a split tree. The caller has to
|
||||
/// manually `@export` these symbols if they need them.
|
||||
///
|
||||
/// This is currently read-only since modification APIs aren't
|
||||
/// presently necessary from C. This will likely change in the future.
|
||||
pub const CApi = struct {
|
||||
pub const NodeTag = enum(c_int) {
|
||||
leaf,
|
||||
split,
|
||||
};
|
||||
|
||||
pub const Split = extern struct {
|
||||
horizontal: bool,
|
||||
ratio: f32,
|
||||
left: Node.Handle,
|
||||
right: Node.Handle,
|
||||
};
|
||||
|
||||
pub fn is_empty(self: *const Self) callconv(.c) bool {
|
||||
return self.isEmpty();
|
||||
}
|
||||
|
||||
pub fn len(self: *const Self) callconv(.c) usize {
|
||||
return self.nodes.len;
|
||||
}
|
||||
|
||||
pub fn is_split(self: *const Self, handle: Node.Handle) callconv(.c) bool {
|
||||
return switch (self.nodes[handle.idx()]) {
|
||||
.leaf => false,
|
||||
.split => true,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_split(
|
||||
self: *const Self,
|
||||
handle: Node.Handle,
|
||||
) callconv(.c) CApi.Split {
|
||||
const s = self.nodes[handle.idx()].split;
|
||||
return .{
|
||||
.horizontal = switch (s.layout) {
|
||||
.horizontal => true,
|
||||
.vertical => false,
|
||||
},
|
||||
.ratio = @floatCast(s.ratio),
|
||||
.left = s.left,
|
||||
.right = s.right,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_leaf(self: *const Self, handle: Node.Handle) *View {
|
||||
return self.nodes[handle.idx()].leaf;
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2202,3 +2256,145 @@ test "SplitTree: remove and zoom" {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
test "SplitTree: CApi is_empty" {
|
||||
const testing = std.testing;
|
||||
|
||||
var empty: TestTree = .empty;
|
||||
defer empty.deinit();
|
||||
try testing.expect(TestTree.CApi.is_empty(&empty));
|
||||
|
||||
var v1: TestTree.View = .{ .label = "A" };
|
||||
var t1: TestTree = try .init(testing.allocator, &v1);
|
||||
defer t1.deinit();
|
||||
try testing.expect(!TestTree.CApi.is_empty(&t1));
|
||||
}
|
||||
|
||||
test "SplitTree: CApi len" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var empty: TestTree = .empty;
|
||||
defer empty.deinit();
|
||||
try testing.expectEqual(@as(usize, 0), TestTree.CApi.len(&empty));
|
||||
|
||||
var v1: TestTree.View = .{ .label = "A" };
|
||||
var t1: TestTree = try .init(alloc, &v1);
|
||||
defer t1.deinit();
|
||||
try testing.expectEqual(@as(usize, 1), TestTree.CApi.len(&t1));
|
||||
|
||||
var v2: TestTree.View = .{ .label = "B" };
|
||||
var t2: TestTree = try .init(alloc, &v2);
|
||||
defer t2.deinit();
|
||||
|
||||
var split = try t1.split(
|
||||
alloc,
|
||||
.root,
|
||||
.right,
|
||||
0.5,
|
||||
&t2,
|
||||
);
|
||||
defer split.deinit();
|
||||
try testing.expectEqual(@as(usize, 3), TestTree.CApi.len(&split));
|
||||
}
|
||||
|
||||
test "SplitTree: CApi is_split" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var v1: TestTree.View = .{ .label = "A" };
|
||||
var t1: TestTree = try .init(alloc, &v1);
|
||||
defer t1.deinit();
|
||||
try testing.expect(!TestTree.CApi.is_split(&t1, .root));
|
||||
|
||||
var v2: TestTree.View = .{ .label = "B" };
|
||||
var t2: TestTree = try .init(alloc, &v2);
|
||||
defer t2.deinit();
|
||||
|
||||
var split = try t1.split(
|
||||
alloc,
|
||||
.root,
|
||||
.right,
|
||||
0.5,
|
||||
&t2,
|
||||
);
|
||||
defer split.deinit();
|
||||
try testing.expect(TestTree.CApi.is_split(&split, .root));
|
||||
try testing.expect(!TestTree.CApi.is_split(&split, @enumFromInt(1)));
|
||||
try testing.expect(!TestTree.CApi.is_split(&split, @enumFromInt(2)));
|
||||
}
|
||||
|
||||
test "SplitTree: CApi get_split" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var v1: TestTree.View = .{ .label = "A" };
|
||||
var t1: TestTree = try .init(alloc, &v1);
|
||||
defer t1.deinit();
|
||||
var v2: TestTree.View = .{ .label = "B" };
|
||||
var t2: TestTree = try .init(alloc, &v2);
|
||||
defer t2.deinit();
|
||||
|
||||
var split_h = try t1.split(
|
||||
alloc,
|
||||
.root,
|
||||
.right,
|
||||
0.5,
|
||||
&t2,
|
||||
);
|
||||
defer split_h.deinit();
|
||||
|
||||
const s_h = TestTree.CApi.get_split(&split_h, .root);
|
||||
try testing.expect(s_h.horizontal);
|
||||
try testing.expectApproxEqAbs(@as(f32, 0.5), s_h.ratio, 0.01);
|
||||
try testing.expectEqual(@as(TestTree.Node.Handle, @enumFromInt(2)), s_h.left);
|
||||
try testing.expectEqual(@as(TestTree.Node.Handle, @enumFromInt(1)), s_h.right);
|
||||
|
||||
var v3: TestTree.View = .{ .label = "C" };
|
||||
var t3: TestTree = try .init(alloc, &v3);
|
||||
defer t3.deinit();
|
||||
|
||||
var split_v = try t1.split(
|
||||
alloc,
|
||||
.root,
|
||||
.down,
|
||||
0.7,
|
||||
&t3,
|
||||
);
|
||||
defer split_v.deinit();
|
||||
|
||||
const s_v = TestTree.CApi.get_split(&split_v, .root);
|
||||
try testing.expect(!s_v.horizontal);
|
||||
try testing.expectApproxEqAbs(@as(f32, 0.7), s_v.ratio, 0.01);
|
||||
}
|
||||
|
||||
test "SplitTree: CApi get_leaf" {
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
var v1: TestTree.View = .{ .label = "A" };
|
||||
var t1: TestTree = try .init(alloc, &v1);
|
||||
defer t1.deinit();
|
||||
|
||||
const leaf = TestTree.CApi.get_leaf(&t1, .root);
|
||||
try testing.expectEqualStrings("A", leaf.label);
|
||||
|
||||
var v2: TestTree.View = .{ .label = "B" };
|
||||
var t2: TestTree = try .init(alloc, &v2);
|
||||
defer t2.deinit();
|
||||
|
||||
var split = try t1.split(
|
||||
alloc,
|
||||
.root,
|
||||
.right,
|
||||
0.5,
|
||||
&t2,
|
||||
);
|
||||
defer split.deinit();
|
||||
|
||||
const leaf_a = TestTree.CApi.get_leaf(&split, @enumFromInt(2));
|
||||
try testing.expectEqualStrings("A", leaf_a.label);
|
||||
|
||||
const leaf_b = TestTree.CApi.get_leaf(&split, @enumFromInt(1));
|
||||
try testing.expectEqualStrings("B", leaf_b.label);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user