From 40232ae3941ff30e61fc4631c97c37a24664b99f Mon Sep 17 00:00:00 2001 From: Isaac Freund Date: Wed, 7 Oct 2020 00:04:35 +0200 Subject: [PATCH] Make Dispatcher work for server as well --- scanner.zig | 2 +- src/client_core.zig | 35 ----------------------------------- src/common_core.zig | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 38 insertions(+), 36 deletions(-) diff --git a/scanner.zig b/scanner.zig index 5dfb2c0..153f1f5 100644 --- a/scanner.zig +++ b/scanner.zig @@ -87,7 +87,7 @@ const Interface = struct { \\ data: T, \\ ) !void {{ \\ const proxy = @ptrCast(*client.Proxy, {}); - \\ try proxy.addDispatcher(client.Dispatcher({}, T).dispatcher, listener, data); + \\ try proxy.addDispatcher(common.Dispatcher({}, T).dispatcher, listener, data); \\ }} \\ , .{ snake_case, title_case, snake_case, title_case, snake_case, title_case }); diff --git a/src/client_core.zig b/src/client_core.zig index 2f93e20..0203760 100644 --- a/src/client_core.zig +++ b/src/client_core.zig @@ -102,38 +102,3 @@ pub const EventQueue = opaque { wl_event_queue_destroy(event_queue); } }; - -pub fn Dispatcher(comptime Object: type, comptime Data: type) type { - return struct { - pub fn dispatcher( - implementation: ?*const c_void, - proxy: *Proxy, - opcode: u32, - message: *const common.Message, - args: [*]common.Argument, - ) callconv(.C) c_int { - inline for (@typeInfo(Object.Event).Union.fields) |event_field, event_num| { - if (event_num == opcode) { - var event_data: event_field.field_type = undefined; - inline for (@typeInfo(event_field.field_type).Struct.fields) |f, i| { - @field(event_data, f.name) = switch (@sizeOf(f.field_type)) { - 4 => @bitCast(f.field_type, args[i].u), - 8 => @ptrCast(f.field_type, args[i].s), - else => unreachable, - }; - } - - const listener = @ptrCast(fn (object: *Object, event: Object.Event, data: Data) void, implementation); - listener( - @ptrCast(*Object, proxy), - @unionInit(Object.Event, event_field.name, event_data), - @intToPtr(Data, @ptrToInt(proxy.getUserData())), - ); - - return 0; - } - } - unreachable; - } - }; -} diff --git a/src/common_core.zig b/src/common_core.zig index f0fa19b..7867bff 100644 --- a/src/common_core.zig +++ b/src/common_core.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const wayland = @import("wayland.zig"); pub const Object = opaque {}; @@ -51,3 +52,39 @@ pub const Argument = extern union { a: ?*Array, h: std.os.fd_t, }; + +pub fn Dispatcher(comptime Obj: type, comptime Data: type) type { + const client = @hasDecl(Obj, "Event"); + const Payload = if (client) Obj.Event else Obj.Request; + return struct { + pub fn dispatcher( + implementation: ?*const c_void, + object: if (client) *wayland.client.Proxy else *wayland.server.Resource, + opcode: u32, + message: *const Message, + args: [*]Argument, + ) callconv(.C) c_int { + inline for (@typeInfo(Payload).Union.fields) |payload_field, payload_num| { + if (payload_num == opcode) { + var payload_data: payload_field.field_type = undefined; + inline for (@typeInfo(payload_field.field_type).Struct.fields) |f, i| { + @field(payload_data, f.name) = switch (@sizeOf(f.field_type)) { + 4 => @bitCast(f.field_type, args[i].u), + 8 => @ptrCast(f.field_type, args[i].s), + else => unreachable, + }; + } + + @ptrCast(fn (*Obj, Payload, Data) void, implementation)( + @ptrCast(*Obj, object), + @unionInit(Payload, payload_field.name, payload_data), + @intToPtr(Data, @ptrToInt(object.getUserData())), + ); + + return 0; + } + } + unreachable; + } + }; +}