zgpu

git clone git://git.electrosoup.com/zgpu
Log | Files | Refs | Submodules | README

commit 0632a496f0f5d313cfe07f3620c0dc81eec837f6
parent 67797425147031b412ecbe1653008b8ff9f1e235
Author: Christian Ermann <christianermann@gmail.com>
Date:   Wed, 23 Apr 2025 18:45:09 -0700

Add 'Callback' function to convert Zig functions into WGPU callbacks

Diffstat:
Asrc/callback.zig | 29+++++++++++++++++++++++++++++
Msrc/logging.zig | 17+++--------------
Msrc/main.zig | 3++-
3 files changed, 34 insertions(+), 15 deletions(-)

diff --git a/src/callback.zig b/src/callback.zig @@ -0,0 +1,29 @@ +const std = @import("std"); + +fn CallbackType(comptime T: type) type { + const enum_type = switch (@typeInfo(T)) { + .@"fn" => |f| f.params[0].type.?, + else => unreachable, + }; + return fn (enum_type, ?[*:0]const u8, ?*anyopaque) callconv(.C) void; +} + +pub fn Callback( + user_callback: anytype, +) CallbackType(@TypeOf(user_callback)) { + const enum_type = switch (@typeInfo(@TypeOf(user_callback))) { + .@"fn" => |f| f.params[0].type.?, + else => @compileError("callback must be a function"), + }; + return struct { + const callback = user_callback; + fn wrapped_callback( + enum_value: enum_type, + message: ?[*:0]const u8, + userdata: ?*anyopaque, + ) callconv(.C) void { + _ = userdata; + callback(enum_value, std.mem.span(message.?)); + } + }.wrapped_callback; +} diff --git a/src/logging.zig b/src/logging.zig @@ -11,23 +11,12 @@ pub const LogLevel = enum(u32) { trace = 0x00000005, }; -pub const LogCallback = fn (LogLevel, []const u8) void; +pub const LogCallback = fn (LogLevel, ?[*:0]const u8, ?*anyopaque) callconv(.C) void; pub fn setLogLevel(level: LogLevel) void { c.wgpuSetLogLevel(@intCast(@intFromEnum(level))); } -pub fn setLogCallback(comptime callback: LogCallback) void { - const Callback = struct { - const user_callback = callback; - pub fn callback_c( - level: c_int, - message: ?[*:0]const u8, - userdata: ?*anyopaque, - ) callconv(.C) void { - _ = userdata; - user_callback(@enumFromInt(level), std.mem.span(message.?)); - } - }; - c.wgpuSetLogCallback(@ptrCast(&Callback.callback_c), null); +pub fn setLogCallback(callback: *const LogCallback) void { + c.wgpuSetLogCallback(@ptrCast(callback), null); } diff --git a/src/main.zig b/src/main.zig @@ -3,6 +3,7 @@ const std = @import("std"); const glfw = @import("glfw.zig"); const Instance = @import("instance.zig").Instance; const Logging = @import("logging.zig"); +const Callback = @import("callback.zig").Callback; pub fn zgpu_log_callback(level: Logging.LogLevel, message: []const u8) void { switch (level) { @@ -32,7 +33,7 @@ pub fn main() !void { const display = try glfw.native.getX11Display(); const window_id = try glfw.native.getX11Window(window); - Logging.setLogCallback(zgpu_log_callback); + Logging.setLogCallback(Callback(zgpu_log_callback)); Logging.setLogLevel(.warn); const instance = Instance.create(&.{