Core: use .app local init/deinit/tick events (avoid global events)

Signed-off-by: Stephen Gutekanst <stephen@hexops.com>
This commit is contained in:
Stephen Gutekanst 2024-04-28 11:45:59 -07:00 committed by Stephen Gutekanst
parent fb37f74d41
commit 2c8ba82aa3
9 changed files with 41 additions and 48 deletions

View file

@ -5,14 +5,20 @@ const gpu = mach.gpu;
pub const name = .app; pub const name = .app;
pub const Mod = mach.Mod(@This()); pub const Mod = mach.Mod(@This());
pub const global_events = .{ pub const local_events = .{
.init = .{ .handler = init }, .init = .{ .handler = init },
.deinit = .{ .handler = deinit },
.tick = .{ .handler = tick }, .tick = .{ .handler = tick },
}; };
title_timer: mach.Timer, title_timer: mach.Timer,
pipeline: *gpu.RenderPipeline, pipeline: *gpu.RenderPipeline,
pub fn deinit(core: *mach.Core.Mod, game: *Mod) void {
game.state().pipeline.release();
core.send(.deinit, .{});
}
fn init(game: *Mod, core: *mach.Core.Mod) !void { fn init(game: *Mod, core: *mach.Core.Mod) !void {
// Create our shader module // Create our shader module
const shader_module = core.state().device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl")); const shader_module = core.state().device.createShaderModuleWGSL("shader.wgsl", @embedFile("shader.wgsl"));
@ -54,10 +60,6 @@ fn init(game: *Mod, core: *mach.Core.Mod) !void {
try updateWindowTitle(core); try updateWindowTitle(core);
} }
pub fn deinit(game: *Mod) void {
game.state().pipeline.release();
}
// TODO(important): remove need for returning an error here // TODO(important): remove need for returning an error here
fn tick(core: *mach.Core.Mod, game: *Mod) !void { fn tick(core: *mach.Core.Mod, game: *Mod) !void {
// TODO(important): event polling should occur in mach.Core module and get fired as ECS event. // TODO(important): event polling should occur in mach.Core module and get fired as ECS event.

View file

@ -22,10 +22,10 @@ pub const components = .{
.follower = .{ .type = void }, .follower = .{ .type = void },
}; };
// Global events that we will listen for. pub const local_events = .{
pub const global_events = .{ .init = .{ .handler = init },
.init = .{ .handler = init }, // Event sent on app startup .deinit = .{ .handler = deinit },
.tick = .{ .handler = tick }, // Event sent on each frame .tick = .{ .handler = tick },
}; };
// Define the globally unique name of our module. You can use any name here, but keep in mind no // Define the globally unique name of our module. You can use any name here, but keep in mind no
@ -38,6 +38,10 @@ pub const name = .app;
// Note that Mod.state() returns an instance of our module struct. // Note that Mod.state() returns an instance of our module struct.
pub const Mod = mach.Mod(@This()); pub const Mod = mach.Mod(@This());
pub fn deinit(core: *mach.Core.Mod) void {
core.send(.deinit, .{});
}
// TODO(important): remove need for returning an error here // TODO(important): remove need for returning an error here
fn init( fn init(
// These are injected dependencies - as long as these modules were registered in the top-level // These are injected dependencies - as long as these modules were registered in the top-level

View file

@ -27,7 +27,7 @@ pub const components = .{
.scale = .{ .type = f32 }, .scale = .{ .type = f32 },
}; };
pub const global_events = .{ pub const local_events = .{
.init = .{ .handler = init }, .init = .{ .handler = init },
.deinit = .{ .handler = deinit }, .deinit = .{ .handler = deinit },
.tick = .{ .handler = tick }, .tick = .{ .handler = tick },

View file

@ -32,20 +32,18 @@ frame_render_pass: *gpu.RenderPassEncoder = undefined,
pub const name = .app; pub const name = .app;
pub const Mod = mach.Mod(@This()); pub const Mod = mach.Mod(@This());
pub const global_events = .{ pub const local_events = .{
.init = .{ .handler = init }, .init = .{ .handler = init },
.deinit = .{ .handler = deinit }, .deinit = .{ .handler = deinit },
.tick = .{ .handler = tick }, .tick = .{ .handler = tick },
};
pub const local_events = .{
.after_init = .{ .handler = afterInit }, .after_init = .{ .handler = afterInit },
.end_frame = .{ .handler = endFrame }, .end_frame = .{ .handler = endFrame },
}; };
fn deinit(sprite_pipeline: *gfx.SpritePipeline.Mod, glyphs: *Glyphs.Mod) !void { fn deinit(core: *mach.Core.Mod, sprite_pipeline: *gfx.SpritePipeline.Mod, glyphs: *Glyphs.Mod) !void {
sprite_pipeline.send(.deinit, .{}); sprite_pipeline.send(.deinit, .{});
glyphs.send(.deinit, .{}); glyphs.send(.deinit, .{});
core.send(.deinit, .{});
} }
fn init(sprite_pipeline: *gfx.SpritePipeline.Mod, glyphs: *Glyphs.Mod, game: *Mod) !void { fn init(sprite_pipeline: *gfx.SpritePipeline.Mod, glyphs: *Glyphs.Mod, game: *Mod) !void {

View file

@ -24,14 +24,12 @@ pub const name = .app;
pub const Mod = mach.Mod(@This()); pub const Mod = mach.Mod(@This());
pub const global_events = .{ pub const global_events = .{
.init = .{ .handler = init },
.deinit = .{ .handler = deinit },
.tick = .{ .handler = tick },
.audio_state_change = .{ .handler = audioStateChange }, .audio_state_change = .{ .handler = audioStateChange },
}; };
pub const local_events = .{ pub const local_events = .{
.init = .{ .handler = init }, .init = .{ .handler = init },
.deinit = .{ .handler = deinit },
.tick = .{ .handler = tick }, .tick = .{ .handler = tick },
}; };
@ -55,9 +53,9 @@ fn init(audio: *mach.Audio.Mod, piano: *Mod) void {
std.debug.print("[arrow down] decrease volume 10%\n", .{}); std.debug.print("[arrow down] decrease volume 10%\n", .{});
} }
fn deinit(audio: *mach.Audio.Mod) void { fn deinit(core: *mach.Core.Mod, audio: *mach.Audio.Mod) void {
// Initialize audio module
audio.send(.deinit, .{}); audio.send(.deinit, .{});
core.send(.deinit, .{});
} }
fn audioStateChange( fn audioStateChange(

View file

@ -36,20 +36,19 @@ frame_render_pass: *gpu.RenderPassEncoder = undefined,
pub const name = .app; pub const name = .app;
pub const Mod = mach.Mod(@This()); pub const Mod = mach.Mod(@This());
pub const global_events = .{ pub const local_events = .{
.init = .{ .handler = init }, .init = .{ .handler = init },
.deinit = .{ .handler = deinit }, .deinit = .{ .handler = deinit },
.tick = .{ .handler = tick }, .tick = .{ .handler = tick },
};
pub const local_events = .{
.end_frame = .{ .handler = endFrame }, .end_frame = .{ .handler = endFrame },
}; };
fn deinit( fn deinit(
core: *mach.Core.Mod,
sprite_pipeline: *gfx.SpritePipeline.Mod, sprite_pipeline: *gfx.SpritePipeline.Mod,
) !void { ) !void {
sprite_pipeline.send(.init, .{}); sprite_pipeline.send(.init, .{});
core.send(.deinit, .{});
} }
fn init( fn init(

View file

@ -34,16 +34,13 @@ frame_render_pass: *gpu.RenderPassEncoder = undefined,
// Define the globally unique name of our module. You can use any name here, but keep in mind no // Define the globally unique name of our module. You can use any name here, but keep in mind no
// two modules in the program can have the same name. // two modules in the program can have the same name.
pub const name = .game; pub const name = .app;
pub const Mod = mach.Mod(@This()); pub const Mod = mach.Mod(@This());
pub const global_events = .{ pub const local_events = .{
.init = .{ .handler = init }, .init = .{ .handler = init },
.deinit = .{ .handler = deinit }, .deinit = .{ .handler = deinit },
.tick = .{ .handler = tick }, .tick = .{ .handler = tick },
};
pub const local_events = .{
.end_frame = .{ .handler = endFrame }, .end_frame = .{ .handler = endFrame },
}; };
@ -58,9 +55,11 @@ const text1: []const []const u8 = &.{
const text2: []const []const u8 = &.{"$!?😊"}; const text2: []const []const u8 = &.{"$!?😊"};
fn deinit( fn deinit(
core: *mach.Core.Mod,
text_pipeline: *gfx.TextPipeline.Mod, text_pipeline: *gfx.TextPipeline.Mod,
) !void { ) !void {
text_pipeline.send(.deinit, .{}); text_pipeline.send(.deinit, .{});
core.send(.deinit, .{});
} }
fn init( fn init(

View file

@ -10,12 +10,6 @@ pub const name = .mach_core;
pub const Mod = mach.Mod(@This()); pub const Mod = mach.Mod(@This());
pub const global_events = .{
.init = .{ .handler = fn () void },
.deinit = .{ .handler = fn () void },
.tick = .{ .handler = fn () void },
};
pub const local_events = .{ pub const local_events = .{
.update = .{ .handler = update, .description = .update = .{ .handler = update, .description =
\\ Send this when window entities have been updated and you want the new values respected. \\ Send this when window entities have been updated and you want the new values respected.
@ -105,7 +99,7 @@ fn init(core: *Mod) !void {
.main_window = main_window, .main_window = main_window,
}); });
core.sendGlobal(.init, .{}); mach.core.mods.send(.app, .init, .{});
core.send(.init_done, .{}); core.send(.init_done, .{});
} }
@ -153,15 +147,14 @@ fn deinit(core: *Mod) void {
} }
_ = gpa.deinit(); _ = gpa.deinit();
}
fn mainThreadTick(core: *Mod) !void {
_ = try mach.core.update(null);
// Send .tick to anyone interested
core.sendGlobal(.tick, .{});
}
fn exit(core: *Mod) void {
core.state().should_exit = true; core.state().should_exit = true;
} }
fn mainThreadTick() !void {
_ = try mach.core.update(null);
mach.core.mods.send(.app, .tick, .{});
}
fn exit() void {
mach.core.mods.send(.app, .deinit, .{});
}

View file

@ -15,7 +15,7 @@ var stack_space: [8 * 1024 * 1024]u8 = undefined;
pub fn initModule() !void { pub fn initModule() !void {
// Initialize the global set of Mach modules used in the program. // Initialize the global set of Mach modules used in the program.
try mods.init(std.heap.c_allocator); try mods.init(std.heap.c_allocator);
mods.mod.mach_core.send(.init, .{}); mods.send(.mach_core, .init, .{});
// Dispatch events until this .mach_core.init_done is sent // Dispatch events until this .mach_core.init_done is sent
try mods.dispatch(&stack_space, .{ .until = .{ try mods.dispatch(&stack_space, .{ .until = .{
@ -28,7 +28,7 @@ pub fn initModule() !void {
/// ///
/// Returns true if tick() should be called again, false if the application should exit. /// Returns true if tick() should be called again, false if the application should exit.
pub fn tick() !bool { pub fn tick() !bool {
mods.mod.mach_core.send(.main_thread_tick, .{}); mods.send(.mach_core, .main_thread_tick, .{});
// Dispatch events until this .mach_core.main_thread_tick_done is sent // Dispatch events until this .mach_core.main_thread_tick_done is sent
try mods.dispatch(&stack_space, .{ .until = .{ try mods.dispatch(&stack_space, .{ .until = .{