From b1b8321fa493f63cae5f2dc7302ca1b20fcd4ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Partheym=C3=BCller?= Date: Wed, 8 Feb 2023 11:40:19 +0100 Subject: [PATCH] change comptime access to typeInfo of load function to satisfy compiler / use function pointer in order to make @field() work --- zig-ecs/src/resources/assets.zig | 25 ++++++++++++++----------- zig-ecs/src/resources/cache.zig | 16 ++++++++-------- 2 files changed, 22 insertions(+), 19 deletions(-) diff --git a/zig-ecs/src/resources/assets.zig b/zig-ecs/src/resources/assets.zig index 3b6a6e2..6481783 100644 --- a/zig-ecs/src/resources/assets.zig +++ b/zig-ecs/src/resources/assets.zig @@ -37,8 +37,8 @@ pub const Assets = struct { return self.get(ReturnType(loader, true)).load(id, loader); } - fn ReturnType(comptime loader: anytype, strip_ptr: bool) type { - var ret = @typeInfo(@TypeOf(@field(loader, "load"))).BoundFn.return_type.?; + fn ReturnType(comptime loader: anytype, comptime strip_ptr: bool) type { + var ret = @typeInfo(@typeInfo(@TypeOf(@field(loader, "load"))).Pointer.child).Fn.return_type.?; if (strip_ptr) { return std.meta.Child(ret); } @@ -47,9 +47,6 @@ pub const Assets = struct { }; test "assets" { - // zig v0.10.0: Compilation Error - // error: no field named 'load' in struct 'resources.assets.test.assets.ThingLoadArgs' - const Thing = struct { fart: i32, pub fn deinit(self: *@This()) void { @@ -65,13 +62,19 @@ test "assets" { }; const OtherThingLoadArgs = struct { - pub fn load(_: @This()) *OtherThing { + // Use actual field "load" as function pointer to avoid zig v0.10.0 + // compiler error: "error: no field named 'load' in struct '...'" + load: *const fn (_: @This()) *OtherThing, + pub fn loadFn(_: @This()) *OtherThing { return std.testing.allocator.create(OtherThing) catch unreachable; } }; const ThingLoadArgs = struct { - pub fn load(_: @This()) *Thing { + // Use actual field "load" as function pointer to avoid zig v0.10.0 + // compiler error: "error: no field named 'load' in struct '...'" + load: *const fn (_: @This()) *Thing, + pub fn loadFn(_: @This()) *Thing { return std.testing.allocator.create(Thing) catch unreachable; } }; @@ -79,16 +82,16 @@ test "assets" { var assets = Assets.init(std.testing.allocator); defer assets.deinit(); - _ = assets.get(Thing).load(6, ThingLoadArgs{}); + _ = assets.get(Thing).load(6, ThingLoadArgs{ .load = ThingLoadArgs.loadFn }); try std.testing.expectEqual(assets.get(Thing).size(), 1); - _ = assets.load(4, ThingLoadArgs{}); + _ = assets.load(4, ThingLoadArgs{ .load = ThingLoadArgs.loadFn }); try std.testing.expectEqual(assets.get(Thing).size(), 2); - _ = assets.get(OtherThing).load(6, OtherThingLoadArgs{}); + _ = assets.get(OtherThing).load(6, OtherThingLoadArgs{ .load = OtherThingLoadArgs.loadFn }); try std.testing.expectEqual(assets.get(OtherThing).size(), 1); - _ = assets.load(8, OtherThingLoadArgs{}); + _ = assets.load(8, OtherThingLoadArgs{ .load = OtherThingLoadArgs.loadFn }); try std.testing.expectEqual(assets.get(OtherThing).size(), 2); assets.get(OtherThing).clear(); diff --git a/zig-ecs/src/resources/cache.zig b/zig-ecs/src/resources/cache.zig index 0d8fbd8..2195973 100644 --- a/zig-ecs/src/resources/cache.zig +++ b/zig-ecs/src/resources/cache.zig @@ -42,12 +42,12 @@ pub fn Cache(comptime T: type) type { self.safe_deinit(self); } - pub fn load(self: *@This(), id: u32, comptime loader: anytype) @typeInfo(@TypeOf(@field(loader, "load"))).BoundFn.return_type.? { + pub fn load(self: *@This(), id: u32, comptime loader: anytype) @typeInfo(@typeInfo(@TypeOf(@field(loader, "load"))).Pointer.child).Fn.return_type.? { if (self.resources.get(id)) |resource| { return resource; } - var resource = loader.load(); + var resource = loader.load(loader); _ = self.resources.put(id, resource) catch unreachable; return resource; } @@ -82,9 +82,6 @@ pub fn Cache(comptime T: type) type { } test "cache" { - // zig v0.10.0: Compilation Error - // error: no field named 'load' in struct 'resources.cache.test.cache.ThingLoadArgs' - const utils = @import("../ecs/utils.zig"); const Thing = struct { @@ -95,7 +92,10 @@ test "cache" { }; const ThingLoadArgs = struct { - pub fn load(self: @This()) *Thing { + // Use actual field "load" as function pointer to avoid zig v0.10.0 + // compiler error: "error: no field named 'load' in struct '...'" + load: *const fn (self: @This()) *Thing, + pub fn loadFn(self: @This()) *Thing { _ = self; return std.testing.allocator.create(Thing) catch unreachable; } @@ -104,8 +104,8 @@ test "cache" { var cache = Cache(Thing).init(std.testing.allocator); defer cache.deinit(); - _ = cache.load(utils.hashString("my/id"), ThingLoadArgs{}); - _ = cache.load(utils.hashString("another/id"), ThingLoadArgs{}); + _ = cache.load(utils.hashString("my/id"), ThingLoadArgs{ .load = ThingLoadArgs.loadFn }); + _ = cache.load(utils.hashString("another/id"), ThingLoadArgs{ .load = ThingLoadArgs.loadFn }); try std.testing.expectEqual(cache.size(), 2); cache.remove(utils.hashString("my/id"));