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:
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(&.{