module: make send() local args type known
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
ca05c9f3d9
commit
9eac721f24
2 changed files with 26 additions and 21 deletions
|
|
@ -68,7 +68,7 @@ pub fn World(comptime mods: anytype) type {
|
|||
try world.entities.removeComponent(entity, module_tag, component_name);
|
||||
}
|
||||
|
||||
pub inline fn send(m: *@This(), comptime event_name: Modules.LocalEvent, args: anytype) void {
|
||||
pub inline fn send(m: *@This(), comptime event_name: Modules.LocalEvent, args: Modules.LocalArgsM(M, event_name)) void {
|
||||
const mod_ptr: *Mods = @alignCast(@fieldParentPtr(Mods, @tagName(module_tag), m));
|
||||
const world = @fieldParentPtr(WorldT, "mod", mod_ptr);
|
||||
world.modules.sendToModule(module_tag, event_name, args);
|
||||
|
|
|
|||
|
|
@ -76,29 +76,34 @@ pub fn Modules(comptime mods: anytype) type {
|
|||
inline for (modules) |M| {
|
||||
_ = Module(M); // Validate the module
|
||||
if (M.name != module_name) continue;
|
||||
inline for (M.events) |event| {
|
||||
const Ev = @TypeOf(event);
|
||||
const name_tag = if (@hasField(Ev, "local")) event.local else continue;
|
||||
if (name_tag != event_name) continue;
|
||||
|
||||
const Handler = switch (@typeInfo(@TypeOf(event.handler))) {
|
||||
.Fn => @TypeOf(event.handler),
|
||||
.Type => |t| switch (@typeInfo(t)) {
|
||||
.Fn => event.handler,
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
// TODO: passing std.meta.Tuple here instead of TupleHACK results in a compiler
|
||||
// segfault. The only difference is that TupleHACk does not produce a real tuple,
|
||||
// `@Type(.{.Struct = .{ .is_tuple = false }})` instead of `.is_tuple = true`.
|
||||
return UninjectedArgsTuple(TupleHACK, Handler);
|
||||
}
|
||||
@compileError("mach: module ." ++ @tagName(M.name) ++ " has no .local event handler for ." ++ @tagName(event_name));
|
||||
return LocalArgsM(M, event_name);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn LocalArgsM(comptime M: type, event_name: LocalEvent) type {
|
||||
_ = Module(M); // Validate the module
|
||||
inline for (M.events) |event| {
|
||||
const Ev = @TypeOf(event);
|
||||
const name_tag = if (@hasField(Ev, "local")) event.local else continue;
|
||||
if (name_tag != event_name) continue;
|
||||
|
||||
const Handler = switch (@typeInfo(@TypeOf(event.handler))) {
|
||||
.Fn => @TypeOf(event.handler),
|
||||
.Type => |t| switch (@typeInfo(t)) {
|
||||
.Fn => event.handler,
|
||||
else => unreachable,
|
||||
},
|
||||
else => unreachable,
|
||||
};
|
||||
|
||||
// TODO: passing std.meta.Tuple here instead of TupleHACK results in a compiler
|
||||
// segfault. The only difference is that TupleHACk does not produce a real tuple,
|
||||
// `@Type(.{.Struct = .{ .is_tuple = false }})` instead of `.is_tuple = true`.
|
||||
return UninjectedArgsTuple(TupleHACK, Handler);
|
||||
}
|
||||
@compileError("mach: module ." ++ @tagName(M.name) ++ " has no .local event handler for ." ++ @tagName(event_name));
|
||||
}
|
||||
|
||||
/// Returns an args tuple representing the standard, uninjected, arguments which the given
|
||||
/// global event handler requires.
|
||||
fn Args(event_name: GlobalEvent) type {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue