Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub inline fn dynLibOpen(libName: []const u8) !std.DynLib {
test {
// TODO: refactor code so we can use this here:
// std.testing.refAllDeclsRecursive(@This());
_ = Modules;
_ = Core;
_ = gpu;
_ = sysaudio;
Expand Down
108 changes: 95 additions & 13 deletions src/module.zig
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,6 @@ pub const ObjectID = u64;

const ObjectTypeID = u16;

const PackedObjectTypeID = packed struct(u16) {
// 2^10 (1024) modules in an application
module_name_id: u10,
// 2^6 (64) lists of objects per module
object_name_id: u6,
};

pub const ObjectsOptions = struct {
/// If set to true, Mach will track when fields are set using the setField/setAll
/// methods using a bitset with one bit per field to indicate 'the field was set'.
Expand Down Expand Up @@ -606,6 +599,10 @@ pub fn Modules(module_lists: anytype) type {

module_names: StringTable = .{},
object_names: StringTable = .{},
name_ids: std.MultiArrayList(struct {
module_name_id: u32,
object_name_id: u32,
}) = .{},
graph: Graph,

/// Enum describing all declarations for a given comptime-known module.
Expand Down Expand Up @@ -649,19 +646,21 @@ pub fn Modules(module_lists: anytype) type {
const Mod2 = @TypeOf(@field(m.mods, field.name));
var mod: Mod2 = undefined;
const module_name_id = try m.module_names.indexOrPut(allocator, @tagName(Mod2.mach_module));
inline for (@typeInfo(@TypeOf(mod)).@"struct".fields) |mod_field| {
const mod_fields = @typeInfo(@TypeOf(mod)).@"struct".fields;
try m.name_ids.ensureUnusedCapacity(allocator, mod_fields.len);
inline for (mod_fields) |mod_field| {
if (@typeInfo(mod_field.type) == .@"struct" and @hasDecl(mod_field.type, "IsMachObjects")) {
const object_name_id = try m.object_names.indexOrPut(allocator, mod_field.name);

// TODO: use packed struct(TypeID) here. Same thing, just get the type from central location
const object_type_id: u16 = @bitCast(PackedObjectTypeID{
.module_name_id = @intCast(module_name_id),
.object_name_id = @intCast(object_name_id),
const object_type_id = m.name_ids.addOneAssumeCapacity();
m.name_ids.set(object_type_id, .{
.module_name_id = module_name_id,
.object_name_id = object_name_id,
});

@field(mod, mod_field.name).internal = .{
.allocator = allocator,
.type_id = object_type_id,
.type_id = @intCast(object_type_id),
.graph = &m.graph,
};
}
Expand All @@ -672,6 +671,7 @@ pub fn Modules(module_lists: anytype) type {

pub fn deinit(m: *@This(), allocator: std.mem.Allocator) void {
m.graph.deinit(allocator);
m.name_ids.deinit(allocator);
// TODO: remainder of deinit
}

Expand Down Expand Up @@ -936,3 +936,85 @@ fn ModulesByName(comptime modules: anytype) type {
},
});
}

test "Long field name" {
const test_module = struct {
pub const mach_module = .test_module;
really_really_really_really_really_really_really_long_field_name: Objects(.{}, struct {}),
another_field: Objects(.{}, struct {}),
};

//TODO: swap to testing allocator once remainder of deinit implemented
var aa = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = aa.allocator();

var modules = Modules(.{test_module}){
.mods = undefined,
.graph = undefined,
};
try modules.init(allocator);
modules.deinit(allocator);
aa.deinit();
}

test "Many fields, same module" {
const test_module = struct {
pub const mach_module = .test_module;
field0: Objects(.{}, struct {}),
field1: Objects(.{}, struct {}),
field2: Objects(.{}, struct {}),
field3: Objects(.{}, struct {}),
field4: Objects(.{}, struct {}),
field5: Objects(.{}, struct {}),
field6: Objects(.{}, struct {}),
field7: Objects(.{}, struct {}),
field8: Objects(.{}, struct {}),
field9: Objects(.{}, struct {}),
};

//TODO: swap to testing allocator once remainder of deinit implemented
var aa = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = aa.allocator();

var modules = Modules(.{test_module}){
.mods = undefined,
.graph = undefined,
};
try modules.init(allocator);
modules.deinit(allocator);
aa.deinit();
}

test "Many fields, Many modules" {
const test_module0 = struct {
pub const mach_module = .test_module0;
field0: Objects(.{}, struct {}),
field1: Objects(.{}, struct {}),
field2: Objects(.{}, struct {}),
field3: Objects(.{}, struct {}),
};
const test_module1 = struct {
pub const mach_module = .test_module1;
field4: Objects(.{}, struct {}),
field5: Objects(.{}, struct {}),
field6: Objects(.{}, struct {}),
field7: Objects(.{}, struct {}),
};
const test_module2 = struct {
pub const mach_module = .test_module2;
field8: Objects(.{}, struct {}),
field9: Objects(.{}, struct {}),
};

//TODO: swap to testing allocator once remainder of deinit implemented
var aa = std.heap.ArenaAllocator.init(std.heap.page_allocator);
const allocator = aa.allocator();

var modules = Modules(.{ test_module0, test_module1, test_module2 }){
.mods = undefined,
.graph = undefined,
};
try modules.init(allocator);
modules.deinit(allocator);
aa.deinit();
}
Loading