module: basic event handler parameter validation

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2024-04-05 13:53:32 -07:00 committed by Stephen Gutekanst
parent 92a9836c61
commit b4a479fb3f
5 changed files with 28 additions and 23 deletions

View file

@ -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

View file

@ -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(

View file

@ -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

View file

@ -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

View file

@ -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, .{});