change comptime access to typeInfo of load function to satisfy compiler / use function pointer in order to make @field() work

master
Stefan Partheymüller 2 years ago
parent 386113ac5f
commit b1b8321fa4

@ -37,8 +37,8 @@ pub const Assets = struct {
return self.get(ReturnType(loader, true)).load(id, loader); return self.get(ReturnType(loader, true)).load(id, loader);
} }
fn ReturnType(comptime loader: anytype, strip_ptr: bool) type { fn ReturnType(comptime loader: anytype, comptime strip_ptr: bool) type {
var ret = @typeInfo(@TypeOf(@field(loader, "load"))).BoundFn.return_type.?; var ret = @typeInfo(@typeInfo(@TypeOf(@field(loader, "load"))).Pointer.child).Fn.return_type.?;
if (strip_ptr) { if (strip_ptr) {
return std.meta.Child(ret); return std.meta.Child(ret);
} }
@ -47,9 +47,6 @@ pub const Assets = struct {
}; };
test "assets" { test "assets" {
// zig v0.10.0: Compilation Error
// error: no field named 'load' in struct 'resources.assets.test.assets.ThingLoadArgs'
const Thing = struct { const Thing = struct {
fart: i32, fart: i32,
pub fn deinit(self: *@This()) void { pub fn deinit(self: *@This()) void {
@ -65,13 +62,19 @@ test "assets" {
}; };
const OtherThingLoadArgs = struct { 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; return std.testing.allocator.create(OtherThing) catch unreachable;
} }
}; };
const ThingLoadArgs = struct { 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; return std.testing.allocator.create(Thing) catch unreachable;
} }
}; };
@ -79,16 +82,16 @@ test "assets" {
var assets = Assets.init(std.testing.allocator); var assets = Assets.init(std.testing.allocator);
defer assets.deinit(); 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); 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); 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); 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); try std.testing.expectEqual(assets.get(OtherThing).size(), 2);
assets.get(OtherThing).clear(); assets.get(OtherThing).clear();

@ -42,12 +42,12 @@ pub fn Cache(comptime T: type) type {
self.safe_deinit(self); 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| { if (self.resources.get(id)) |resource| {
return resource; return resource;
} }
var resource = loader.load(); var resource = loader.load(loader);
_ = self.resources.put(id, resource) catch unreachable; _ = self.resources.put(id, resource) catch unreachable;
return resource; return resource;
} }
@ -82,9 +82,6 @@ pub fn Cache(comptime T: type) type {
} }
test "cache" { 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 utils = @import("../ecs/utils.zig");
const Thing = struct { const Thing = struct {
@ -95,7 +92,10 @@ test "cache" {
}; };
const ThingLoadArgs = struct { 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; _ = self;
return std.testing.allocator.create(Thing) catch unreachable; return std.testing.allocator.create(Thing) catch unreachable;
} }
@ -104,8 +104,8 @@ test "cache" {
var cache = Cache(Thing).init(std.testing.allocator); var cache = Cache(Thing).init(std.testing.allocator);
defer cache.deinit(); defer cache.deinit();
_ = cache.load(utils.hashString("my/id"), ThingLoadArgs{}); _ = cache.load(utils.hashString("my/id"), ThingLoadArgs{ .load = ThingLoadArgs.loadFn });
_ = cache.load(utils.hashString("another/id"), ThingLoadArgs{}); _ = cache.load(utils.hashString("another/id"), ThingLoadArgs{ .load = ThingLoadArgs.loadFn });
try std.testing.expectEqual(cache.size(), 2); try std.testing.expectEqual(cache.size(), 2);
cache.remove(utils.hashString("my/id")); cache.remove(utils.hashString("my/id"));

Loading…
Cancel
Save