diff --git a/examples/piano/App.zig b/examples/piano/App.zig index 25ea4390..de9128e7 100644 --- a/examples/piano/App.zig +++ b/examples/piano/App.zig @@ -25,6 +25,7 @@ pub const Mod = mach.Mod(@This()); pub const events = .{ .init = .{ .handler = init }, + .after_init = .{ .handler = afterInit }, .deinit = .{ .handler = deinit }, .tick = .{ .handler = tick }, .audio_state_change = .{ .handler = audioStateChange }, @@ -37,9 +38,8 @@ pub const components = .{ ghost_key_mode: bool = false, fn init(core: *mach.Core.Mod, audio: *mach.Audio.Mod, app: *Mod) void { - // Initialize audio module, telling it to send our module's .audio_state_change event when an - // entity's sound stops playing - audio.send(.init, .{app.event(.audio_state_change)}); + audio.send(.init, .{}); + app.send(.after_init, .{}); // Initialize piano module state app.init(.{}); @@ -53,6 +53,12 @@ fn init(core: *mach.Core.Mod, audio: *mach.Audio.Mod, app: *Mod) void { core.send(.start, .{}); } +fn afterInit(audio: *mach.Audio.Mod, app: *Mod) void { + // Configure the audio module to send our app's .audio_state_change event when an entity's sound + // finishes playing. + audio.state().on_state_change = app.event(.audio_state_change); +} + fn deinit(core: *mach.Core.Mod, audio: *mach.Audio.Mod) void { audio.send(.deinit, .{}); core.send(.deinit, .{}); diff --git a/src/Audio.zig b/src/Audio.zig index 4de1a6bf..b07ac3da 100644 --- a/src/Audio.zig +++ b/src/Audio.zig @@ -32,7 +32,7 @@ ms_render_ahead: f32 = 16, allocator: std.mem.Allocator, ctx: sysaudio.Context, player: sysaudio.Player, -on_state_change: mach.AnyEvent, +on_state_change: ?mach.AnyEvent = null, output_mu: std.Thread.Mutex = .{}, output: SampleBuffer, mixing_buffer: ?std.ArrayListUnmanaged(f32) = null, @@ -43,7 +43,7 @@ var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const SampleBuffer = std.fifo.LinearFifo(u8, .Dynamic); -fn init(audio: *Mod, on_state_change: mach.AnyEvent) !void { +fn init(audio: *Mod) !void { const allocator = gpa.allocator(); const ctx = try sysaudio.Context.init(null, allocator, .{}); try ctx.refresh(); @@ -70,7 +70,6 @@ fn init(audio: *Mod, on_state_change: mach.AnyEvent) !void { .allocator = allocator, .ctx = ctx, .player = player, - .on_state_change = on_state_change, .output = SampleBuffer.init(allocator), .debug = debug, }); @@ -171,7 +170,9 @@ fn audioTick(audio: *Mod) !void { try audio.set(id, .index, index + to_read); } } - if (did_state_change) audio.sendAnyEvent(audio.state().on_state_change); + if (audio.state().on_state_change) |on_state_change_event| { + if (did_state_change) audio.sendAnyEvent(on_state_change_event); + } // Write our rendered samples to the fifo, expanding its size as needed and converting our f32 // samples to the format the driver expects.