diff --git a/src/Engine.zig b/src/Engine.zig index 85ad47dc..29382109 100644 --- a/src/Engine.zig +++ b/src/Engine.zig @@ -2,7 +2,6 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const glfw = @import("glfw"); const gpu = @import("gpu"); -const App = @import("app"); const structs = @import("structs.zig"); const enums = @import("enums.zig"); const Timer = @import("Timer.zig"); @@ -43,8 +42,8 @@ pub const Core = struct { return core.internal.setSizeLimits(min, max); } - pub fn setKeyCallback(core: *Core, comptime cb: fn (app: *App, engine: *Engine, key: enums.Key, action: enums.Action) void) void { - core.internal.setKeyCallback(cb); + pub fn pollEvent(core: *Core) ?structs.Event { + return core.internal.pollEvent(); } }; diff --git a/src/native.zig b/src/native.zig index c762ab50..bbbe3255 100644 --- a/src/native.zig +++ b/src/native.zig @@ -11,12 +11,17 @@ const c = @import("c.zig").c; pub const CoreGlfw = struct { window: glfw.Window, backend_type: gpu.Adapter.BackendType, + allocator: std.mem.Allocator, + events: EventQueue = .{}, user_ptr: UserPtr = undefined, + const EventQueue = std.TailQueue(structs.Event); + const EventNode = EventQueue.Node; + const UserPtr = struct { - app: *App, - engine: *Engine, + core: *CoreGlfw, }; + pub fn init(allocator: std.mem.Allocator, engine: *Engine) !CoreGlfw { const options = engine.options; const backend_type = try util.detectBackendType(allocator); @@ -39,16 +44,44 @@ pub const CoreGlfw = struct { return CoreGlfw{ .window = window, .backend_type = backend_type, + .allocator = engine.allocator, }; } - fn initCallback(self: *CoreGlfw, app: *App, engine: *Engine) void { - self.user_ptr = UserPtr{ - .app = app, - .engine = engine, - }; + fn pushEvent(self: *CoreGlfw, event: structs.Event) void { + const node = self.allocator.create(EventNode) catch unreachable; + node.* = .{ .data = event }; + self.events.append(node); + } + + fn initCallback(self: *CoreGlfw) void { + self.user_ptr = UserPtr{ .core = self }; self.window.setUserPointer(&self.user_ptr); + + const callback = struct { + fn callback(window: glfw.Window, key: glfw.Key, scancode: i32, action: glfw.Action, mods: glfw.Mods) void { + const core = (window.getUserPointer(UserPtr) orelse unreachable).core; + + switch (action) { + .press => core.pushEvent(.{ + .key_press = .{ + .key = toMachKey(key), + }, + }), + .release => core.pushEvent(.{ + .key_release = .{ + .key = toMachKey(key), + }, + }), + else => {}, + } + + _ = scancode; + _ = mods; + } + }.callback; + self.window.setKeyCallback(callback); } pub fn setShouldClose(self: *CoreGlfw, value: bool) void { @@ -67,16 +100,9 @@ pub const CoreGlfw = struct { ); } - pub fn setKeyCallback(self: *CoreGlfw, comptime cb: fn (app: *App, engine: *Engine, key: enums.Key, action: enums.Action) void) void { - const callback = struct { - fn callback(window: glfw.Window, key: glfw.Key, scancode: i32, action: glfw.Action, mods: glfw.Mods) void { - const usrptr = window.getUserPointer(UserPtr) orelse unreachable; - cb(usrptr.app, usrptr.engine, CoreGlfw.toMachKey(key), CoreGlfw.toMachAction(action)); - _ = scancode; - _ = mods; - } - }.callback; - self.window.setKeyCallback(callback); + pub fn pollEvent(self: *CoreGlfw) ?structs.Event { + if (self.events.popFirst()) |n| return n.data; + return null; } fn toMachAction(action: glfw.Action) enums.Action { @@ -381,7 +407,7 @@ pub fn main() !void { defer app.deinit(&engine); // Glfw specific: initialize the user pointer used in callbacks - engine.core.internal.initCallback(&app, &engine); + engine.core.internal.initCallback(); const window = engine.core.internal.window; while (!window.shouldClose()) { diff --git a/src/structs.zig b/src/structs.zig index da697ccb..4fec8d4a 100644 --- a/src/structs.zig +++ b/src/structs.zig @@ -1,4 +1,5 @@ const gpu = @import("gpu"); +const enums = @import("enums.zig"); pub const Size = struct { width: u32, @@ -51,3 +52,12 @@ pub const Options = struct { /// Whether the application has a preference for low power or high performance GPU. power_preference: gpu.PowerPreference = .none, }; + +pub const Event = union(enum) { + key_press: struct { + key: enums.Key, + }, + key_release: struct { + key: enums.Key, + }, +};