Skip to content

Commit

Permalink
update to Zig 2024.1.0-mach
Browse files Browse the repository at this point in the history
Signed-off-by: Stephen Gutekanst <[email protected]>
  • Loading branch information
emidoots committed Jan 8, 2024
1 parent a2982b2 commit cb83f6a
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 25 deletions.
4 changes: 2 additions & 2 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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" },
Expand Down
8 changes: 4 additions & 4 deletions src/Archetype.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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;
Expand Down
29 changes: 15 additions & 14 deletions src/entities.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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).?;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);

Expand All @@ -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);
Expand All @@ -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));
Expand All @@ -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]);
}
Expand Down Expand Up @@ -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
Expand Down
10 changes: 5 additions & 5 deletions src/query.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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} },
} };
Expand Down

0 comments on commit cb83f6a

Please sign in to comment.