diff --git a/src/Engine.zig b/src/Engine.zig index 6956da7e..1613bcb2 100644 --- a/src/Engine.zig +++ b/src/Engine.zig @@ -2,6 +2,8 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const glfw = @import("glfw"); const gpu = @import("gpu"); +const App = @import("app"); +const enums = @import("enums.zig"); pub const VSyncMode = enum { /// Potential screen tearing. @@ -68,6 +70,10 @@ timer: std.time.Timer, pub const Core = struct { internal: GetCoreInternalType(), + + 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 const GpuDriver = struct { diff --git a/src/entry_native.zig b/src/entry_native.zig index b4a9239a..94061eb2 100644 --- a/src/entry_native.zig +++ b/src/entry_native.zig @@ -28,6 +28,10 @@ pub fn main() !void { try app.init(&engine); defer app.deinit(&engine); + if (@hasDecl(@TypeOf(engine.core.internal), "initCallback")) { + engine.core.internal.initCallback(&app, &engine); + } + const window = engine.core.internal.window; while (!window.shouldClose()) { try glfw.pollEvents(); diff --git a/src/native.zig b/src/native.zig index a6fd4ed6..b0dd4cb1 100644 --- a/src/native.zig +++ b/src/native.zig @@ -1,14 +1,21 @@ const std = @import("std"); const glfw = @import("glfw"); const gpu = @import("gpu"); +const App = @import("app"); const Engine = @import("Engine.zig"); +const enums = @import("enums.zig"); const util = @import("util.zig"); const c = @import("c.zig").c; pub const CoreGlfw = struct { window: glfw.Window, backend_type: gpu.Adapter.BackendType, + user_ptr: UserPtr = undefined, + const UserPtr = struct { + app: *App, + engine: *Engine, + }; pub fn init(allocator: std.mem.Allocator, engine: *Engine) !CoreGlfw { const options = engine.options; const backend_type = try util.detectBackendType(allocator); @@ -34,6 +41,42 @@ pub const CoreGlfw = struct { }; } + pub fn initCallback(self: *CoreGlfw, app: *App, engine: *Engine) void { + self.user_ptr = UserPtr{ + .app = app, + .engine = engine, + }; + + self.window.setUserPointer(&self.user_ptr); + } + + 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); + } + + fn toMachAction(action: glfw.Action) enums.Action { + return switch (action) { + .press => .press, + .release => .release, + .repeat => .repeat, + }; + } + + fn toMachKey(key: glfw.Key) enums.Key { + return switch (key) { + .space => .space, + else => unreachable, + }; + } + /// Default GLFW error handling callback fn errorCallback(error_code: glfw.Error, description: [:0]const u8) void { std.debug.print("glfw: {}: {s}\n", .{ error_code, description });