diff --git a/src/module.zig b/src/module.zig index aa1ead45..f24e3df3 100644 --- a/src/module.zig +++ b/src/module.zig @@ -101,30 +101,6 @@ pub fn Modules(comptime modules2: anytype) type { } } - pub fn LocalArgsM(comptime M: type, event_name: LocalEvent) type { - _ = ModuleInterface(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 => switch (@typeInfo(event.handler)) { - .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 GlobalArgs(module_name: ModuleName(modules), event_name: GlobalEvent) type { @@ -135,30 +111,6 @@ pub fn Modules(comptime modules2: anytype) type { } } - pub fn GlobalArgsM(comptime M: type, event_name: GlobalEvent) type { - _ = ModuleInterface(M); // Validate the module - inline for (M.events) |event| { - const Ev = @TypeOf(event); - const name_tag = if (@hasField(Ev, "global")) event.global else continue; - if (name_tag != event_name) continue; - - const Handler = switch (@typeInfo(@TypeOf(event.handler))) { - .Fn => @TypeOf(event.handler), - .Type => switch (@typeInfo(event.handler)) { - .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 .global event handler for ." ++ @tagName(event_name)); - } - /// Send a global event which the specified module defines pub fn sendGlobal( m: *@This(), @@ -425,14 +377,14 @@ pub fn Module( try m.entities.removeComponent(entity, module_tag, component_name); } - pub inline fn send(m: *@This(), comptime event_name: ModulesT.LocalEvent, args: ModulesT.LocalArgsM(M, event_name)) void { + pub inline fn send(m: *@This(), comptime event_name: ModulesT.LocalEvent, args: LocalArgsM(M, event_name)) void { const MByName = ModsByName(ModulesT.modules, ModulesT); const mod_ptr: *MByName = @alignCast(@fieldParentPtr(MByName, @tagName(module_tag), m)); const modules = @fieldParentPtr(ModulesT, "mod", mod_ptr); modules.sendToModule(module_tag, event_name, args); } - pub inline fn sendGlobal(m: *@This(), comptime event_name: ModulesT.GlobalEvent, args: ModulesT.GlobalArgsM(M, event_name)) void { + pub inline fn sendGlobal(m: *@This(), comptime event_name: ModulesT.GlobalEvent, args: GlobalArgsM(M, event_name)) void { const MByName = ModsByName(ModulesT.modules, ModulesT); const mod_ptr: *MByName = @alignCast(@fieldParentPtr(MByName, @tagName(module_tag), m)); const modules = @fieldParentPtr(ModulesT, "mod", mod_ptr); @@ -535,6 +487,54 @@ fn UninjectedArgsTuple( return Tuple(std_args); } +pub fn LocalArgsM(comptime M: type, event_name: anytype) type { + _ = ModuleInterface(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 => switch (@typeInfo(event.handler)) { + .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)); +} + +pub fn GlobalArgsM(comptime M: type, event_name: anytype) type { + _ = ModuleInterface(M); // Validate the module + inline for (M.events) |event| { + const Ev = @TypeOf(event); + const name_tag = if (@hasField(Ev, "global")) event.global else continue; + if (name_tag != event_name) continue; + + const Handler = switch (@typeInfo(@TypeOf(event.handler))) { + .Fn => @TypeOf(event.handler), + .Type => switch (@typeInfo(event.handler)) { + .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 .global event handler for ." ++ @tagName(event_name)); +} + /// enum describing every possible comptime-known local event name fn LocalEventEnum(comptime modules: anytype) type { var enum_fields: []const std.builtin.Type.EnumField = &[0]std.builtin.Type.EnumField{};