From b4a479fb3f025fc0573451cb9a3b59615b68fe62 Mon Sep 17 00:00:00 2001 From: Stephen Gutekanst Date: Fri, 5 Apr 2024 13:53:32 -0700 Subject: [PATCH] module: basic event handler parameter validation Signed-off-by: Stephen Gutekanst --- examples/glyphs/Game.zig | 14 +++++++------- examples/glyphs/Text.zig | 2 +- examples/sprite/Game.zig | 14 +++++++------- examples/text/Game.zig | 12 ++++++------ src/module.zig | 9 +++++++-- 5 files changed, 28 insertions(+), 23 deletions(-) diff --git a/examples/glyphs/Game.zig b/examples/glyphs/Game.zig index 99f1c41e..857f8718 100644 --- a/examples/glyphs/Game.zig +++ b/examples/glyphs/Game.zig @@ -61,10 +61,10 @@ fn init( // Tell sprite_mod to use the texture const texture = text_mod.state.texture; - sprite_mod.send(.init_pipeline, .{ Sprite.PipelineOptions{ + sprite_mod.send(.init_pipeline, .{Sprite.PipelineOptions{ .pipeline = @intFromEnum(Pipeline.text), .texture = texture, - } }); + }}); // We can create entities, and set components on them. Note that components live in a module // namespace, e.g. the `Sprite` module could have a 3D `.location` component with a different @@ -77,7 +77,7 @@ fn init( try sprite_mod.set(player, .size, vec2(@floatFromInt(r.width), @floatFromInt(r.height))); try sprite_mod.set(player, .uv_transform, Mat3x3.translate(vec2(@floatFromInt(r.x), @floatFromInt(r.y)))); try sprite_mod.set(player, .pipeline, @intFromEnum(Pipeline.text)); - sprite_mod.send(.updated, .{ @intFromEnum(Pipeline.text) }); + sprite_mod.send(.updated, .{@intFromEnum(Pipeline.text)}); game.state = .{ .timer = try mach.Timer.start(), @@ -192,14 +192,14 @@ fn tick( ); try sprite_mod.set(game.state.player, .transform, player_transform); - sprite_mod.send(.updated, .{ @intFromEnum(Pipeline.text) }); + sprite_mod.send(.updated, .{@intFromEnum(Pipeline.text)}); // Perform pre-render work - sprite_mod.send(.pre_render, .{ @intFromEnum(Pipeline.text) }); + sprite_mod.send(.pre_render, .{@intFromEnum(Pipeline.text)}); // Render a frame - engine.send(.begin_pass, .{ gpu.Color{ .r = 1.0, .g = 1.0, .b = 1.0, .a = 1.0 } }); - sprite_mod.send(.render, .{ @intFromEnum(Pipeline.text) }); + engine.send(.begin_pass, .{gpu.Color{ .r = 1.0, .g = 1.0, .b = 1.0, .a = 1.0 }}); + sprite_mod.send(.render, .{@intFromEnum(Pipeline.text)}); engine.send(.end_pass, .{}); engine.send(.present, .{}); // Present the frame diff --git a/examples/glyphs/Text.zig b/examples/glyphs/Text.zig index d4a42e36..d44a21ad 100644 --- a/examples/glyphs/Text.zig +++ b/examples/glyphs/Text.zig @@ -70,7 +70,7 @@ fn init( s.ft = try ft.Library.init(); s.face = try s.ft.createFaceMemory(assets.roboto_medium_ttf, 0); - text_mod.send(.prepare, .{ &[_]u21{ '?', '!', 'a', 'b', '#', '@', '%', '$', '&', '^', '*', '+', '=', '<', '>', '/', ':', ';', 'Q', '~' } }); + text_mod.send(.prepare, .{&[_]u21{ '?', '!', 'a', 'b', '#', '@', '%', '$', '&', '^', '*', '+', '=', '<', '>', '/', ':', ';', 'Q', '~' }}); } fn prepare( diff --git a/examples/sprite/Game.zig b/examples/sprite/Game.zig index bcb7b9dc..dcfb4f6c 100644 --- a/examples/sprite/Game.zig +++ b/examples/sprite/Game.zig @@ -68,11 +68,11 @@ fn init( try sprite_mod.set(player, .uv_transform, Mat3x3.translate(vec2(0, 0))); try sprite_mod.set(player, .pipeline, @intFromEnum(Pipeline.default)); - sprite_mod.send(.init_pipeline, .{ Sprite.PipelineOptions{ + sprite_mod.send(.init_pipeline, .{Sprite.PipelineOptions{ .pipeline = @intFromEnum(Pipeline.default), .texture = try loadTexture(engine), - } }); - sprite_mod.send(.updated, .{ @intFromEnum(Pipeline.default) }); + }}); + sprite_mod.send(.updated, .{@intFromEnum(Pipeline.default)}); game.state = .{ .timer = try mach.Timer.start(), @@ -176,14 +176,14 @@ fn tick( player_pos.v[0] += direction.x() * speed * delta_time; player_pos.v[1] += direction.y() * speed * delta_time; try sprite_mod.set(game.state.player, .transform, Mat4x4.translate(player_pos)); - sprite_mod.send(.updated, .{ @intFromEnum(Pipeline.default) }); + sprite_mod.send(.updated, .{@intFromEnum(Pipeline.default)}); // Perform pre-render work - sprite_mod.send(.pre_render, .{ @intFromEnum(Pipeline.default) }); + sprite_mod.send(.pre_render, .{@intFromEnum(Pipeline.default)}); // Render a frame - engine.send(.begin_pass, .{ gpu.Color{ .r = 1.0, .g = 1.0, .b = 1.0, .a = 1.0 } }); - sprite_mod.send(.render, .{ @intFromEnum(Pipeline.default) }); + engine.send(.begin_pass, .{gpu.Color{ .r = 1.0, .g = 1.0, .b = 1.0, .a = 1.0 }}); + sprite_mod.send(.render, .{@intFromEnum(Pipeline.default)}); engine.send(.end_pass, .{}); engine.send(.present, .{}); // Present the frame diff --git a/examples/text/Game.zig b/examples/text/Game.zig index d37e0c1f..1708073d 100644 --- a/examples/text/Game.zig +++ b/examples/text/Game.zig @@ -108,9 +108,9 @@ fn init( try text_mod.set(player, .text, text1); try text_mod.set(player, .style, styles); - text_mod.send(.init_pipeline, .{ Text.PipelineOptions{ + text_mod.send(.init_pipeline, .{Text.PipelineOptions{ .pipeline = @intFromEnum(Pipeline.default), - } }); + }}); engine.dispatchNoError(); // TODO: no dispatch in user code game.state = .{ @@ -226,14 +226,14 @@ fn tick( player_pos.v[0] += direction.x() * speed * delta_time; player_pos.v[1] += direction.y() * speed * delta_time; try text_mod.set(game.state.player, .transform, Mat4x4.scaleScalar(upscale).mul(&Mat4x4.translate(player_pos))); - text_mod.send(.updated, .{ @intFromEnum(Pipeline.default) }); + text_mod.send(.updated, .{@intFromEnum(Pipeline.default)}); // Perform pre-render work - text_mod.send(.pre_render, .{ @intFromEnum(Pipeline.default) }); + text_mod.send(.pre_render, .{@intFromEnum(Pipeline.default)}); // Render a frame - engine.send(.begin_pass, .{ gpu.Color{ .r = 1.0, .g = 1.0, .b = 1.0, .a = 1.0 } }); - text_mod.send(.render, .{ @intFromEnum(Pipeline.default) }); + engine.send(.begin_pass, .{gpu.Color{ .r = 1.0, .g = 1.0, .b = 1.0, .a = 1.0 }}); + text_mod.send(.render, .{@intFromEnum(Pipeline.default)}); engine.send(.end_pass, .{}); engine.send(.present, .{}); // Present the frame diff --git a/src/module.zig b/src/module.zig index 78550c7b..62f3735d 100644 --- a/src/module.zig +++ b/src/module.zig @@ -36,7 +36,6 @@ pub fn Modules(comptime modules2: anytype) type { pub const modules = modules2; // TODO: add runtime module support - pub const ModuleID = u32; pub const EventID = u32; @@ -706,6 +705,12 @@ fn validateEvents(comptime error_prefix: anytype, comptime events: anytype) void error_prefix ++ ".{s} field .handler expected `.handler = fn` or `.handler = @TypeOf(fn)`, found found: {s}", .{ field.name, @typeName(@TypeOf(event.handler)) }, )); + + switch (@typeInfo(@TypeOf(event.handler))) { + .Fn => _ = UninjectedArgsTuple(@TypeOf(event.handler)), + .Type => _ = UninjectedArgsTuple(event.handler), + else => unreachable, + } } } @@ -1339,7 +1344,7 @@ test "dispatch" { // Global events which are not handled by anyone yet can be written as `pub const fooBar = fn() void;` // within a module, which allows pre-declaring that `fooBar` is a valid global event, and enables // its arguments to be inferred still like this: - modules.sendGlobal(.engine_renderer, .frame_done, .{ 1337 }); + modules.sendGlobal(.engine_renderer, .frame_done, .{1337}); // Local events modules.sendToModule(.engine_renderer, .update, .{});