ecs: improve comptime error messages with empty sets

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2023-03-26 19:43:53 -07:00 committed by Stephen Gutekanst
parent 4575080ca9
commit 6f499aa418

View file

@ -98,6 +98,9 @@ pub fn MessagesTag(comptime messages: anytype) type {
}); });
} }
const NoComponents = @TypeOf(.{});
const NoGlobals = @TypeOf(.{});
/// Returns the namespaced components struct **type**. /// Returns the namespaced components struct **type**.
// //
/// Consult `namespacedComponents` for how a value of this type looks. /// Consult `namespacedComponents` for how a value of this type looks.
@ -114,6 +117,14 @@ fn NamespacedComponents(comptime modules: anytype) type {
.is_comptime = false, .is_comptime = false,
.alignment = @alignOf(@TypeOf(module.components)), .alignment = @alignOf(@TypeOf(module.components)),
}}; }};
} else {
fields = fields ++ [_]std.builtin.Type.StructField{.{
.name = module_name,
.type = NoComponents,
.default_value = null,
.is_comptime = false,
.alignment = @alignOf(NoComponents),
}};
} }
} }
return @Type(.{ return @Type(.{
@ -150,6 +161,8 @@ fn namespacedComponents(comptime modules: anytype) NamespacedComponents(modules)
const module_name = @tagName(@field(module, "name")); const module_name = @tagName(@field(module, "name"));
if (@hasDecl(module, "components")) { if (@hasDecl(module, "components")) {
@field(x, module_name) = module.components; @field(x, module_name) = module.components;
} else {
@field(x, module_name) = .{};
} }
} }
return x; return x;
@ -176,23 +189,21 @@ fn NamespacedGlobals(comptime modules: anytype) type {
const module = @field(modules, module_field.name); const module = @field(modules, module_field.name);
const module_name = @tagName(@field(module, "name")); const module_name = @tagName(@field(module, "name"));
const global_fields = std.meta.fields(module); const global_fields = std.meta.fields(module);
if (global_fields.len > 0) { const Globals = if (global_fields.len > 0) @Type(.{
const Globals = @Type(.{ .Struct = .{
.Struct = .{ .layout = .Auto,
.layout = .Auto, .is_tuple = false,
.is_tuple = false, .fields = global_fields,
.fields = global_fields, .decls = &[_]std.builtin.Type.Declaration{},
.decls = &[_]std.builtin.Type.Declaration{}, },
}, }) else NoGlobals;
}); fields = fields ++ [_]std.builtin.Type.StructField{.{
fields = fields ++ [_]std.builtin.Type.StructField{.{ .name = module_name,
.name = module_name, .type = Globals,
.type = Globals, .default_value = null,
.default_value = null, .is_comptime = false,
.is_comptime = false, .alignment = @alignOf(Globals),
.alignment = @alignOf(Globals), }};
}};
}
} }
return @Type(.{ return @Type(.{
.Struct = .{ .Struct = .{
@ -256,8 +267,8 @@ pub fn World(comptime modules: anytype) type {
pub fn send(world: *Self, comptime msg_tag: anytype) !void { pub fn send(world: *Self, comptime msg_tag: anytype) !void {
inline for (std.meta.fields(@TypeOf(modules))) |module_field| { inline for (std.meta.fields(@TypeOf(modules))) |module_field| {
const module = @field(modules, module_field.name); const module = @field(modules, module_field.name);
if (@hasDecl(module, "messages")) { if (@hasDecl(module, "Message")) {
if (@hasField(module.messages, @tagName(msg_tag))) try module.update(world, msg_tag); if (@hasField(module.Message, @tagName(msg_tag))) try module.update(world, msg_tag);
} }
} }
} }