module: elevate local/global args type construction
Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
parent
8711e5e3a7
commit
582a3c07f6
1 changed files with 50 additions and 50 deletions
100
src/module.zig
100
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
|
/// Returns an args tuple representing the standard, uninjected, arguments which the given
|
||||||
/// global event handler requires.
|
/// global event handler requires.
|
||||||
fn GlobalArgs(module_name: ModuleName(modules), event_name: GlobalEvent) type {
|
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
|
/// Send a global event which the specified module defines
|
||||||
pub fn sendGlobal(
|
pub fn sendGlobal(
|
||||||
m: *@This(),
|
m: *@This(),
|
||||||
|
|
@ -425,14 +377,14 @@ pub fn Module(
|
||||||
try m.entities.removeComponent(entity, module_tag, component_name);
|
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 MByName = ModsByName(ModulesT.modules, ModulesT);
|
||||||
const mod_ptr: *MByName = @alignCast(@fieldParentPtr(MByName, @tagName(module_tag), m));
|
const mod_ptr: *MByName = @alignCast(@fieldParentPtr(MByName, @tagName(module_tag), m));
|
||||||
const modules = @fieldParentPtr(ModulesT, "mod", mod_ptr);
|
const modules = @fieldParentPtr(ModulesT, "mod", mod_ptr);
|
||||||
modules.sendToModule(module_tag, event_name, args);
|
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 MByName = ModsByName(ModulesT.modules, ModulesT);
|
||||||
const mod_ptr: *MByName = @alignCast(@fieldParentPtr(MByName, @tagName(module_tag), m));
|
const mod_ptr: *MByName = @alignCast(@fieldParentPtr(MByName, @tagName(module_tag), m));
|
||||||
const modules = @fieldParentPtr(ModulesT, "mod", mod_ptr);
|
const modules = @fieldParentPtr(ModulesT, "mod", mod_ptr);
|
||||||
|
|
@ -535,6 +487,54 @@ fn UninjectedArgsTuple(
|
||||||
return Tuple(std_args);
|
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
|
/// enum describing every possible comptime-known local event name
|
||||||
fn LocalEventEnum(comptime modules: anytype) type {
|
fn LocalEventEnum(comptime modules: anytype) type {
|
||||||
var enum_fields: []const std.builtin.Type.EnumField = &[0]std.builtin.Type.EnumField{};
|
var enum_fields: []const std.builtin.Type.EnumField = &[0]std.builtin.Type.EnumField{};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue