First of all, thanks for the effort. I tried this library with zig v0.9.1
and I got started very fast.
However, one thing that would be nice is to use zig-ecs
with the current v0.11.0
version of the zig compiler.
Currently, if I try to build a simple project (or the examples) using zig v0.11.0-dev.1571+c1f71963a
I receive a quite generic error:
$ zig build
error: zigecs-test...
error: The following command terminated unexpectedly:
/home/stefanpartheym/.zvm/master/zig build-exe /home/stefanpartheym/develop/stefanpartheym/zigecs-test/src/main.zig --cache-dir /home/stefanpartheym/develop/stefanpartheym/zigecs-test/zig-cache --global-cache-dir /home/stefanpartheym/.cache/zig --name zigecs-test --pkg-begin ecs /home/stefanpartheym/develop/stefanpartheym/zigecs-test/deps/zig-ecs/src/ecs.zig --pkg-end --enable-cache
error: the following build command failed with exit code 11:
/home/stefanpartheym/develop/stefanpartheym/zigecs-test/zig-cache/o/ee157244c8abf2f8e61ae7f5813ecc82/build /home/stefanpartheym/.zvm/master/zig /home/stefanpartheym/develop/stefanpartheym/zigecs-test /home/stefanpartheym/develop/stefanpartheym/zigecs-test/zig-cache /home/stefanpartheym/.cache/zig run
If I then try to execute the actual command line run by zig build
:
$ /home/stefanpartheym/.zvm/master/zig build-exe /home/stefanpartheym/develop/stefanpartheym/zigecs-test/src/main.zig --cache-dir /home/stefanpartheym/develop/stefanpartheym/zigecs-test/zig-cache --global-cache-dir /home/stefanpartheym/.cache/zig --name zigecs-test --pkg-begin ecs /home/stefanpartheym/develop/stefanpartheym/zigecs-test/deps/zig-ecs/src/ecs.zig --pkg-end --enable-cache
fish: Job 1, '/home/stefanpartheym/.zvm/maste…' terminated by signal SIGSEGV (Adressbereichsfehler)
... the process segfaults.
I suspect, this is may be due to some very complex comptime syntax in src/ecs/component_storage.zig
, which might be deprecated in current compiler versions:
In line 186 of component_storage.zig there is pub usingnamespace if (is_empty_struct)
. Which, if I remove like follows, reveals a different error (but at least not a segfault):
diff --git a/src/ecs/component_storage.zig b/src/ecs/component_storage.zig
index e3aa6b7..72a4408 100644
--- a/src/ecs/component_storage.zig
+++ b/src/ecs/component_storage.zig
@@ -183,17 +183,6 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
return self.set.len();
}
- pub usingnamespace if (is_empty_struct)
- struct {
- /// Sort Entities according to the given comparison function. Only T == Entity is allowed. The constraint param only exists for
- /// parity with non-empty Components
- pub fn sort(self: Self, comptime T: type, context: anytype, comptime lessThan: fn (@TypeOf(context), T, T) bool) void {
- std.debug.assert(T == Entity);
- self.set.sort(context, lessThan);
- }
- }
- else
- struct {
/// Direct access to the array of objects
pub fn raw(self: Self) []Component {
return self.instances.items;
@@ -262,7 +251,6 @@ pub fn ComponentStorage(comptime Component: type, comptime Entity: type) type {
self.set.arrange(length, swap_context, SortContext.sort, swap_context);
}
}
- };
/// Direct access to the array of entities
pub fn data(self: Self) []const Entity {
Using this patch will result in the following compilation error:
deps/zig-ecs/src/ecs/registry.zig:287:13: error: unable to resolve comptime value
self.assure(@TypeOf(value)).add(entity, value);
~~~~^~~~~~~
deps/zig-ecs/src/ecs/registry.zig:287:13: note: argument to function being called at comptime must be comptime-known
deps/zig-ecs/src/ecs/registry.zig:217:54: note: expression is evaluated at comptime because the generic function was instantiated with a comptime-only return type
pub fn assure(self: *Registry, comptime T: type) *Storage(T) {
^~~~~~~~~~~
referenced by:
add__anon_4436: deps/zig-ecs/src/ecs/registry.zig:287:13
main: src/main.zig:16:8
remaining reference traces hidden; use '-freference-trace' to see all reference traces
Finally, as reference, the build.zig
and src/main.zig
files I used:
build.zig:
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "zigecs-test",
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
exe.addModule("ecs", b.createModule(.{
.source_file = std.build.FileSource{ .path = "deps/zig-ecs/src/ecs.zig" },
}));
exe.install();
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest(.{
.root_source_file = .{ .path = "src/main.zig" },
.target = target,
.optimize = optimize,
});
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.step);
}
src/main.zig
const std = @import("std");
const builtin = @import("builtin");
const ecs = @import("ecs");
const Position = struct {
x: f32,
y: f32,
};
pub fn main() !void {
std.debug.print("## Testing zig-ecs (zig v{}) ##\n", .{ builtin.zig_version });
var reg = ecs.Registry.init(std.heap.page_allocator);
var player = reg.create();
reg.add(player, Position{ .x = 10, .y = 10 });
}
Thanks and best regards
Stefan