ecs: revamp module state API

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2023-03-27 08:58:37 -07:00 committed by Stephen Gutekanst
parent 8ff02361da
commit 026639da6d

View file

@ -216,6 +216,14 @@ fn NamespacedState(comptime modules: anytype) type {
}); });
} }
/// Returns the type of the named field in the given struct.
fn FieldType(comptime Struct: type, comptime field_name: []const u8) type {
inline for (@typeInfo(Struct).Struct.fields) |f| {
if (std.mem.eql(u8, f.name, field_name)) return f.type;
}
@panic("no such struct field '" ++ field_name ++ "' in type: " ++ @typeName(Struct));
}
pub fn World(comptime modules: anytype) type { pub fn World(comptime modules: anytype) type {
const all_components = namespacedComponents(modules); const all_components = namespacedComponents(modules);
return struct { return struct {
@ -225,34 +233,20 @@ pub fn World(comptime modules: anytype) type {
const Self = @This(); const Self = @This();
pub fn Module(comptime module_tag: anytype) type { pub fn Module(comptime module_tag: anytype, comptime NSState: type) type {
return struct { return struct {
world: *Self, world: *Self,
/// Gets a state value called `.state_tag` from the module. const State = FieldType(NSState, @tagName(module_tag));
pub inline fn getState(m: @This(), comptime state_tag: anytype) @TypeOf(@field(
@field(m.world.state, @tagName(module_tag)), /// Returns a pointer to the state struct of this module.
@tagName(state_tag), pub inline fn state(m: @This()) *State {
)) { return &@field(m.world.state, @tagName(module_tag));
return comptime @field(
@field(m.world.state, @tagName(module_tag)),
@tagName(state_tag),
);
} }
/// Sets a state value called `.state_tag` in the module. /// Returns a pointer to the state struct of this module.
pub inline fn setState( pub inline fn initState(m: @This(), s: State) void {
m: *@This(), m.state().* = s;
comptime state_tag: anytype,
value: @TypeOf(@field(
@field(m.world.state, @tagName(module_tag)),
@tagName(state_tag),
)),
) void {
comptime @field(
@field(m.world.state, @tagName(module_tag)),
@tagName(state_tag),
) = value;
} }
/// Sets the named component to the specified value for the given entity, /// Sets the named component to the specified value for the given entity,
@ -294,7 +288,7 @@ pub fn World(comptime modules: anytype) type {
}; };
} }
pub inline fn mod(world: *Self, comptime module_tag: anytype) Self.Module(module_tag) { pub inline fn mod(world: *Self, comptime module_tag: anytype) Self.Module(module_tag, NamespacedState(modules)) {
return .{ .world = world }; return .{ .world = world };
} }