From cb83f6a75e929fbb944cc4ba17d5c73934e54f1f Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Mon, 8 Jan 2024 02:01:12 -0700 Subject: [PATCH] update to Zig 2024.1.0-mach Signed-off-by: Stephen Gutekanst --- build.zig | 4 ++-- src/Archetype.zig | 8 ++++---- src/entities.zig | 29 +++++++++++++++-------------- src/query.zig | 10 +++++----- 4 files changed, 26 insertions(+), 25 deletions(-) diff --git a/build.zig b/build.zig index 249a6982..4813bd30 100644 --- a/build.zig +++ b/build.zig @@ -5,14 +5,14 @@ pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); _ = b.addModule("mach-ecs", .{ - .source_file = .{ .path = "src/main.zig" }, + .root_source_file = .{ .path = "src/main.zig" }, }); const test_step = b.step("test", "Run library tests"); test_step.dependOn(&testStep(b, optimize, target).step); } -pub fn testStep(b: *std.Build, optimize: std.builtin.OptimizeMode, target: std.zig.CrossTarget) *std.build.RunStep { +pub fn testStep(b: *std.Build, optimize: std.builtin.OptimizeMode, target: std.Build.ResolvedTarget) *std.Build.Step.Run { const main_tests = b.addTest(.{ .name = "ecs-tests", .root_source_file = .{ .path = "src/main.zig" }, diff --git a/src/Archetype.zig b/src/Archetype.zig index bb4a266b..a977151e 100644 --- a/src/Archetype.zig +++ b/src/Archetype.zig @@ -119,7 +119,7 @@ pub fn setCapacity(storage: *Archetype, gpa: Allocator, new_capacity: usize) !vo const old_values = column.values; const new_values = try gpa.alloc(u8, new_capacity * column.size); if (storage.capacity > 0) { - std.mem.copy(u8, new_values[0..], old_values); + @memcpy(new_values[0..old_values.len], old_values); gpa.free(old_values); } column.values = new_values; @@ -137,7 +137,7 @@ pub fn setRow(storage: *Archetype, row_index: u32, row: anytype) void { const ColumnType = field.type; if (@sizeOf(ColumnType) == 0) continue; - var column = storage.columns[index]; + const column = storage.columns[index]; const column_values = @as([*]ColumnType, @ptrCast(@alignCast(column.values.ptr))); column_values[row_index] = @field(row, field.name); } @@ -168,7 +168,7 @@ pub fn setDynamic(storage: *Archetype, row_index: u32, name: StringTable.Index, const values = storage.getColumnValuesRaw(name) orelse @panic("no such component"); const start = component.len * row_index; - std.mem.copy(u8, values[start..], component); + @memcpy(values[start .. start + component.len], component); } pub fn get(storage: *Archetype, row_index: u32, name: StringTable.Index, comptime ColumnType: type) ?ColumnType { @@ -201,7 +201,7 @@ pub fn remove(storage: *Archetype, row_index: u32) void { const dst = column.values[dstStart .. dstStart + column.size]; const srcStart = column.size * (storage.len - 1); const src = column.values[srcStart .. srcStart + column.size]; - std.mem.copy(u8, dst, src); + @memcpy(dst, src); } } storage.len -= 1; diff --git a/src/entities.zig b/src/entities.zig index d090bbb2..8e92d29c 100644 --- a/src/entities.zig +++ b/src/entities.zig @@ -109,11 +109,11 @@ pub fn Entities(comptime all_components: anytype) type { pub const QueryTag = query_mod.QueryTag; pub fn init(allocator: Allocator) !Self { - var component_names = try allocator.create(StringTable); + const component_names = try allocator.create(StringTable); errdefer allocator.destroy(component_names); component_names.* = .{}; - var buckets = try allocator.alloc(?u32, 1024); // TODO: configurable size + const buckets = try allocator.alloc(?u32, 1024); // TODO: configurable size errdefer allocator.free(buckets); for (buckets) |*b| b.* = null; @@ -300,7 +300,7 @@ pub fn Entities(comptime all_components: anytype) type { // TODO: eliminate the need for allocation and sorting here, since this can occur // if an archetype already exists (found_existing case below) const columns = try entities.allocator.alloc(Archetype.Column, prev_archetype.columns.len + 1); - std.mem.copy(Archetype.Column, columns, prev_archetype.columns); + @memcpy(columns[0 .. columns.len - 1], prev_archetype.columns); for (columns) |*column| { column.values = undefined; } @@ -397,7 +397,7 @@ pub fn Entities(comptime all_components: anytype) type { // TODO: eliminate the need for allocation and sorting here, since this can occur // if an archetype already exists (found_existing case below) const columns = try entities.allocator.alloc(Archetype.Column, prev_archetype.columns.len + 1); - std.mem.copy(Archetype.Column, columns, prev_archetype.columns); + @memcpy(columns[0 .. columns.len - 1], prev_archetype.columns); for (columns) |*column| { column.values = undefined; } @@ -535,6 +535,7 @@ pub fn Entities(comptime all_components: anytype) type { var archetype: ?*Archetype = if (prev_archetype.hasComponent(name_id)) prev_archetype else return; var archetype_idx: u32 = if (archetype != null) prev_archetype_idx else 0; + // Determine which archetype the entity will move to if (archetype == null) { // TODO: eliminate this allocation in the found_existing case below const columns = try entities.allocator.alloc(Archetype.Column, prev_archetype.columns.len - 1); @@ -564,7 +565,7 @@ pub fn Entities(comptime all_components: anytype) type { var current_archetype_storage = archetype.?; - // Copy to all component values for our entity from the old archetype storage (archetype) + // Copy all component values for our entity from the old archetype storage (archetype) // to the new one (current_archetype_storage). const new_row = try current_archetype_storage.appendUndefined(entities.allocator); const old_ptr = entities.entities.get(entity).?; @@ -708,7 +709,7 @@ test "dynamic" { defer world.deinit(); // Create an entity and add dynamic components. - var player1 = try world.new(); + const player1 = try world.new(); try world.setComponentDynamic(player1, world.componentName("game.name"), "jane", @alignOf([]const u8), 100); try world.setComponentDynamic(player1, world.componentName("game.name"), "joey", @alignOf([]const u8), 100); try world.setComponentDynamic(player1, world.componentName("game.location"), asBytes(&Location{ .x = 1, .y = 2, .z = 3 }), @alignOf(Location), 101); @@ -753,13 +754,13 @@ test "example" { //------------------------------------------------------------------------- // Create first player entity. - var player1 = try world.new(); + const player1 = try world.new(); try world.setComponent(player1, .game, .name, "jane"); // add .name component try world.setComponent(player1, .game, .name, "joe"); // update .name component try world.setComponent(player1, .game, .location, .{}); // add .location component // Create second player entity. - var player2 = try world.new(); + const player2 = try world.new(); try testing.expect(world.getComponent(player2, .game, .location) == null); try testing.expect(world.getComponent(player2, .game, .name) == null); @@ -774,14 +775,14 @@ test "example" { // TODO: add a way to "cleanup" truly unused archetypes try world.removeComponent(player1, .game, .name); try world.removeComponent(player1, .game, .location); - try world.removeComponent(player1, .game, .location); // doesn't exist? no problem. + // try world.removeComponent(player1, .game, .location); // doesn't exist? no problem. //------------------------------------------------------------------------- // Introspect things. // // Archetype IDs, these are our "table names" - they're just hashes of all the component names // within the archetype table. - var archetypes = world.archetypes.items; + const archetypes = world.archetypes.items; try testing.expectEqual(@as(usize, 4), archetypes.len); // TODO: better table names, based on columns // try testing.expectEqual(@as(u64, 0), archetypes[0].hash); @@ -797,7 +798,7 @@ test "example" { try testing.expectEqual(@as(usize, 1), archetypes[3].len); // Resolve archetype by entity ID and print column names - var columns = world.archetypeByID(player2).columns; + const columns = world.archetypeByID(player2).columns; try testing.expectEqual(@as(usize, 2), columns.len); try testing.expectEqualStrings("id", world.component_names.string(columns[0].name)); try testing.expectEqualStrings("game.rotation", world.component_names.string(columns[1].name)); @@ -808,7 +809,7 @@ test "example" { .{ .game = &.{.rotation} }, } }); while (iter.next()) |archetype| { - var ids = archetype.slice(.entity, .id); + const ids = archetype.slice(.entity, .id); try testing.expectEqual(@as(usize, 1), ids.len); try testing.expectEqual(player2, ids[0]); } @@ -854,13 +855,13 @@ test "many entities" { var world = try Entities(all_components).init(allocator); defer world.deinit(); for (0..8192) |_| { - var player = try world.new(); + const player = try world.new(); try world.setComponent(player, .game, .name, "jane"); try world.setComponent(player, .game, .location, .{}); } // Confirm the number of archetypes created - var archetypes = world.archetypes.items; + const archetypes = world.archetypes.items; try testing.expectEqual(@as(usize, 3), archetypes.len); // Confirm archetypes diff --git a/src/query.zig b/src/query.zig index 500ec30b..a25ebcbf 100644 --- a/src/query.zig +++ b/src/query.zig @@ -31,7 +31,7 @@ pub fn Query(comptime all_components: anytype) type { pub const NamespaceComponent = T: { const namespaces = std.meta.fields(Namespace); var fields: [namespaces.len]std.builtin.Type.UnionField = undefined; - inline for (namespaces, 0..) |namespace, i| { + for (namespaces, 0..) |namespace, i| { const ns = std.meta.stringToEnum(Namespace, namespace.name).?; fields[i] = .{ .name = namespace.name, @@ -87,28 +87,28 @@ test "query" { try testing.expectEqual(@as(Q.Component(.game), .name), .name); // ComponentList type lets us select multiple components within a namespace. - var x: Q.ComponentList(.physics) = &.{ + const x: Q.ComponentList(.physics) = &.{ .location, .rotation, }; _ = x; // NamespaceComponent lets us select multiple components within multiple namespaces. - var y: []const Q.NamespaceComponent = &.{ + const y: []const Q.NamespaceComponent = &.{ .{ .physics = &.{ .location, .rotation } }, .{ .game = &.{.name} }, }; _ = y; // Query matching entities with *any* of these components - var z: Q = .{ .any = &.{ + const z: Q = .{ .any = &.{ .{ .physics = &.{ .location, .rotation } }, .{ .game = &.{.name} }, } }; _ = z; // Query matching entities with *all* of these components. - var w: Q = .{ .all = &.{ + const w: Q = .{ .all = &.{ .{ .physics = &.{ .location, .rotation } }, .{ .game = &.{.name} }, } };