diff --git a/zig-ecs/.gitignore b/zig-ecs/.gitignore index 2040c29..2aca84c 100644 --- a/zig-ecs/.gitignore +++ b/zig-ecs/.gitignore @@ -1 +1,4 @@ zig-cache +zig-arm-cache + +.DS_Store \ No newline at end of file diff --git a/zig-ecs/.vscode/tasks.json b/zig-ecs/.vscode/tasks.json index 92abd77..cbdbfd4 100644 --- a/zig-ecs/.vscode/tasks.json +++ b/zig-ecs/.vscode/tasks.json @@ -2,6 +2,11 @@ // See https://go.microsoft.com/fwlink/?LinkId=733558 // for the documentation about the tasks.json format "version": "2.0.0", + "options": { + "env": { + "ZIG_SYSTEM_LINKER_HACK": "1", + } + }, "tasks": [ { "label": "Build Project", @@ -12,9 +17,9 @@ ], }, { - "label": "Build and Run Project", + "label": "Build and Run Specific Target", "type": "shell", - "command": "zig build run", + "command": "zig build ${input:zigTarget}", "problemMatcher": [ "$gcc" ], @@ -27,9 +32,9 @@ } }, { - "label": "Pooooooooop", + "label": "Build and Run Project", "type": "shell", - "command": "zig build ${input:zigTarget}", + "command": "zig build run", "problemMatcher": [ "$gcc" ], @@ -41,6 +46,18 @@ "clear": true } }, + { + "label": "Build and Run Project (x64 on arm)", + "type": "shell", + "command": "~/zig/zig-x64/zig build run", + "problemMatcher": [ + "$gcc" + ], + "group": "build", + "presentation": { + "clear": true + } + }, { "label": "Build and Run Project (release-fast)", "type": "shell", @@ -120,13 +137,15 @@ "inputs": [ { "id": "zigTarget", - "description": "choose which target to run", - "type": "pickString", - "options": [ - "run", - "group_sort" - ], - "default": "run" + "type": "command", + "command": "zig.getTargets", + // "description": "choose which target to run", + // "type": "pickString", + // "options": [ + // "run", + // "group_sort" + // ], + // "default": "run" } ], -} \ No newline at end of file +} diff --git a/zig-ecs/build.zig b/zig-ecs/build.zig index 8af56bf..324c12c 100644 --- a/zig-ecs/build.zig +++ b/zig-ecs/build.zig @@ -1,8 +1,12 @@ -const Builder = @import("std").build.Builder; +const std = @import("std"); +const Builder = std.build.Builder; const builtin = @import("builtin"); pub fn build(b: *Builder) void { - const buildMode = b.standardReleaseOptions(); + const build_mode = b.standardReleaseOptions(); + + // use a different cache folder for macos arm builds + b.cache_root = if (std.builtin.os.tag == .macos and std.builtin.arch == std.builtin.Arch.aarch64) "zig-arm-cache" else "zig-cache"; const examples = [_][2][]const u8{ [_][]const u8{ "view_vs_group", "examples/view_vs_group.zig" }, @@ -25,7 +29,7 @@ pub fn build(b: *Builder) void { // first element in the list is added as "run" so "zig build run" works if (i == 0) { - exe.setOutputDir("zig-cache/bin"); + exe.setOutputDir(std.fs.path.joinPosix(b.allocator, &[_][]const u8{ b.cache_root, "bin" }) catch unreachable); const run_exe_step = b.step("run", b.fmt("run {}.zig", .{name})); run_exe_step.dependOn(&run_cmd.step); } @@ -33,12 +37,12 @@ pub fn build(b: *Builder) void { // internal tests const internal_test_step = b.addTest("src/tests.zig"); - internal_test_step.setBuildMode(buildMode); + internal_test_step.setBuildMode(build_mode); // public api tests const test_step = b.addTest("tests/tests.zig"); test_step.addPackagePath("ecs", "src/ecs.zig"); - test_step.setBuildMode(buildMode); + test_step.setBuildMode(build_mode); const test_cmd = b.step("test", "Run the tests"); test_cmd.dependOn(&internal_test_step.step); @@ -51,19 +55,27 @@ pub const LibType = enum(i32) { exe_compiled, }; -/// rel_path is used to add package paths. It should be the the same path used to include this build file -pub fn linkArtifact(b: *Builder, artifact: *std.build.LibExeObjStep, target: std.build.Target, lib_type: LibType, rel_path: []const u8) void { +pub fn getPackage(comptime prefix_path: []const u8) std.build.Pkg { + return .{ + .name = "ecs", + .path = prefix_path ++ "src/ecs.zig", + }; +} + +/// prefix_path is used to add package paths. It should be the the same path used to include this build file +pub fn linkArtifact(b: *Builder, artifact: *std.build.LibExeObjStep, target: std.build.Target, lib_type: LibType, comptime prefix_path: []const u8) void { + const build_mode = b.standardReleaseOptions(); switch (lib_type) { .static => { const lib = b.addStaticLibrary("ecs", "ecs.zig"); - lib.setBuildMode(buildMode); + lib.setBuildMode(build_mode); lib.install(); artifact.linkLibrary(lib); }, .dynamic => { - const lib = b.addSharedLibrary("ecs", "ecs.zig", null); - lib.setBuildMode(buildMode); + const lib = b.addSharedLibrary("ecs", "ecs.zig", .unversioned); + lib.setBuildMode(build_mode); lib.install(); artifact.linkLibrary(lib); @@ -71,5 +83,5 @@ pub fn linkArtifact(b: *Builder, artifact: *std.build.LibExeObjStep, target: std else => {}, } - artifact.addPackagePath("ecs", std.fs.path.join(b.allocator, &[_][]const u8{ rel_path, "ecs.zig" }) catch unreachable); + artifact.addPackage(getPackage(prefix_path)); } diff --git a/zig-ecs/src/ecs/entity.zig b/zig-ecs/src/ecs/entity.zig index c8f505a..076fe9d 100644 --- a/zig-ecs/src/ecs/entity.zig +++ b/zig-ecs/src/ecs/entity.zig @@ -14,9 +14,9 @@ pub fn EntityTraitsType(comptime size: EntityTraitsSize) type { } fn EntityTraitsDefinition(comptime EntityType: type, comptime IndexType: type, comptime VersionType: type) type { - std.debug.assert(@typeInfo(EntityType) == .Int and !EntityType.is_signed); - std.debug.assert(@typeInfo(IndexType) == .Int and !IndexType.is_signed); - std.debug.assert(@typeInfo(VersionType) == .Int and !VersionType.is_signed); + std.debug.assert(@typeInfo(EntityType) == .Int and std.meta.Int(.unsigned, @bitSizeOf(EntityType)) == EntityType); + std.debug.assert(@typeInfo(IndexType) == .Int and std.meta.Int(.unsigned, @bitSizeOf(IndexType)) == IndexType); + std.debug.assert(@typeInfo(VersionType) == .Int and std.meta.Int(.unsigned, @bitSizeOf(VersionType)) == VersionType); if (@bitSizeOf(IndexType) + @bitSizeOf(VersionType) != @bitSizeOf(EntityType)) @compileError("IndexType and VersionType must sum to EntityType's bit count"); diff --git a/zig-ecs/src/ecs/groups.zig b/zig-ecs/src/ecs/groups.zig index b5a03b9..0af32c1 100644 --- a/zig-ecs/src/ecs/groups.zig +++ b/zig-ecs/src/ecs/groups.zig @@ -85,7 +85,7 @@ pub const OwningGroup = struct { var component_ptrs: [component_info.fields.len][*]u8 = undefined; inline for (component_info.fields) |field, i| { - const storage = group.registry.assure(field.field_type.Child); + const storage = group.registry.assure(@typeInfo(field.field_type).Pointer.child); component_ptrs[i] = @ptrCast([*]u8, storage.instances.items.ptr); } @@ -104,7 +104,7 @@ pub const OwningGroup = struct { // fill and return the struct var comps: Components = undefined; inline for (@typeInfo(Components).Struct.fields) |field, i| { - const typed_ptr = @ptrCast([*]field.field_type.Child, @alignCast(@alignOf(field.field_type.Child), it.component_ptrs[i])); + const typed_ptr = @ptrCast([*]@typeInfo(field.field_type).Pointer.child, @alignCast(@alignOf(@typeInfo(field.field_type).Pointer.child), it.component_ptrs[i])); @field(comps, field.name) = &typed_ptr[it.index]; } return comps; @@ -173,7 +173,7 @@ pub const OwningGroup = struct { var component_ptrs: [component_info.fields.len][*]u8 = undefined; inline for (component_info.fields) |field, i| { - const storage = self.registry.assure(field.field_type.Child); + const storage = self.registry.assure(std.meta.Child(field.field_type)); component_ptrs[i] = @ptrCast([*]u8, storage.instances.items.ptr); } @@ -181,7 +181,7 @@ pub const OwningGroup = struct { const index = self.firstOwnedStorage().set.index(entity); var comps: Components = undefined; inline for (component_info.fields) |field, i| { - const typed_ptr = @ptrCast([*]field.field_type.Child, @alignCast(@alignOf(field.field_type.Child), component_ptrs[i])); + const typed_ptr = @ptrCast([*]std.meta.Child(field.field_type), @alignCast(@alignOf(std.meta.Child(field.field_type)), component_ptrs[i])); @field(comps, field.name) = &typed_ptr[index]; } diff --git a/zig-ecs/src/ecs/handles.zig b/zig-ecs/src/ecs/handles.zig index 567aeb9..452c974 100644 --- a/zig-ecs/src/ecs/handles.zig +++ b/zig-ecs/src/ecs/handles.zig @@ -4,9 +4,9 @@ const std = @import("std"); /// you choose the type of the handle (aka its size) and how much of that goes to the index and the version. /// the bitsize of version + id must equal the handle size. pub fn Handles(comptime HandleType: type, comptime IndexType: type, comptime VersionType: type) type { - std.debug.assert(@typeInfo(HandleType) == .Int and !HandleType.is_signed); - std.debug.assert(@typeInfo(IndexType) == .Int and !IndexType.is_signed); - std.debug.assert(@typeInfo(VersionType) == .Int and !VersionType.is_signed); + std.debug.assert(@typeInfo(HandleType) == .Int and std.meta.Int(.unsigned, @bitSizeOf(HandleType)) == HandleType); + std.debug.assert(@typeInfo(IndexType) == .Int and std.meta.Int(.unsigned, @bitSizeOf(IndexType)) == IndexType); + std.debug.assert(@typeInfo(VersionType) == .Int and std.meta.Int(.unsigned, @bitSizeOf(VersionType)) == VersionType); if (@bitSizeOf(IndexType) + @bitSizeOf(VersionType) != @bitSizeOf(HandleType)) @compileError("IndexType and VersionType must sum to HandleType's bit count"); diff --git a/zig-ecs/src/ecs/registry.zig b/zig-ecs/src/ecs/registry.zig index b049414..c0b861b 100644 --- a/zig-ecs/src/ecs/registry.zig +++ b/zig-ecs/src/ecs/registry.zig @@ -195,7 +195,8 @@ pub const Registry = struct { } pub fn deinit(self: *Registry) void { - for (self.components.items()) |ptr| { + var iter = self.components.iterator(); + while (iter.next()) |ptr| { // HACK: we dont know the Type here but we need to call deinit var storage = @intToPtr(*Storage(u1), ptr.value); storage.deinit(); @@ -342,7 +343,8 @@ pub const Registry = struct { pub fn removeAll(self: *Registry, entity: Entity) void { assert(self.valid(entity)); - for (self.components.items()) |ptr| { + var iter = self.components.iterator(); + while (iter.next()) |ptr| { // HACK: we dont know the Type here but we need to be able to call methods on the Storage(T) var store = @intToPtr(*Storage(u1), ptr.value); store.removeIfContains(entity); diff --git a/zig-ecs/src/ecs/type_store.zig b/zig-ecs/src/ecs/type_store.zig index 21db41f..a16704d 100644 --- a/zig-ecs/src/ecs/type_store.zig +++ b/zig-ecs/src/ecs/type_store.zig @@ -14,7 +14,8 @@ pub const TypeStore = struct { } pub fn deinit(self: *TypeStore) void { - for (self.map.items()) |kv| { + var iter = self.map.iterator(); + while (iter.next()) |kv| { self.allocator.free(kv.value); } self.map.deinit(); diff --git a/zig-ecs/src/resources/assets.zig b/zig-ecs/src/resources/assets.zig index bb02846..cc6aa53 100644 --- a/zig-ecs/src/resources/assets.zig +++ b/zig-ecs/src/resources/assets.zig @@ -14,7 +14,8 @@ pub const Assets = struct { } pub fn deinit(self: *Assets) void { - for (self.caches.items()) |ptr| { + var iter = self.caches.iterator(); + while (iter.next()) |ptr| { // HACK: we dont know the Type here but we need to call deinit @intToPtr(*Cache(u1), ptr.value).deinit(); } @@ -39,7 +40,7 @@ pub const Assets = struct { fn ReturnType(comptime loader: anytype, strip_ptr: bool) type { var ret = @typeInfo(@TypeOf(@field(loader, "load"))).BoundFn.return_type.?; if (strip_ptr) { - return ret.Child; + return std.meta.Child(ret); } return ret; } diff --git a/zig-ecs/src/resources/cache.zig b/zig-ecs/src/resources/cache.zig index 576ef9e..d9d9fd0 100644 --- a/zig-ecs/src/resources/cache.zig +++ b/zig-ecs/src/resources/cache.zig @@ -67,7 +67,8 @@ pub fn Cache(comptime T: type) type { pub fn clear(self: *@This()) void { // optionally deinit any resources that have a deinit method if (@hasDecl(T, "deinit")) { - for (self.resources.items()) |kv| { + var iter = self.resources.iterator(); + while (iter.next()) |kv| { @call(.{ .modifier = .always_inline }, @field(kv.value, "deinit"), .{}); } } @@ -75,7 +76,7 @@ pub fn Cache(comptime T: type) type { } pub fn size(self: @This()) usize { - return self.resources.items().len; + return self.resources.count(); } }; } diff --git a/zig-ecs/src/signals/dispatcher.zig b/zig-ecs/src/signals/dispatcher.zig index 15eab06..6bbaf03 100644 --- a/zig-ecs/src/signals/dispatcher.zig +++ b/zig-ecs/src/signals/dispatcher.zig @@ -15,7 +15,8 @@ pub const Dispatcher = struct { } pub fn deinit(self: *Dispatcher) void { - for (self.signals.items()) |ptr| { + var iter = self.signals.iterator(); + while (iter.next()) |ptr| { // HACK: we dont know the Type here but we need to call deinit var signal = @intToPtr(*Signal(void), ptr.value); signal.deinit();