From 07c96af5d76c13bdf29d6c0dfc6282fdb231c732 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Thu, 27 Jun 2024 11:34:05 -0400 Subject: [PATCH] the rest of the events --- src/au.zig | 103 ++------------------ src/au/Bus.zig | 257 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main.zig | 8 +- 3 files changed, 270 insertions(+), 98 deletions(-) create mode 100644 src/au/Bus.zig diff --git a/src/au.zig b/src/au.zig index 00a4c2d..a21adc6 100644 --- a/src/au.zig +++ b/src/au.zig @@ -4,6 +4,8 @@ const builtin = @import("builtin"); const vk = @import("vk"); const c = @import("c.zig"); +const EventBus = @import("au/EventBus.zig"); + pub const use_debug_messenger = switch (builtin.mode) { .Debug, .ReleaseSafe => true, .ReleaseSmall, .ReleaseFast => false, @@ -47,7 +49,6 @@ pub const B: *const BaseWrapper = &_bw; pub const I: *const InstanceProxy = &_ip; pub const D: *const DeviceProxy = &_dp; pub const W: *const Window = &_window; -pub const E: *const EventBus = &_events; pub const Q: *const QueueProxy = &_qp; pub const device_config: *const CandidateDeviceInfo = &_dconfig; @@ -385,7 +386,7 @@ pub fn debug_callback( return vk.FALSE; } -const Window = struct { +pub const Window = struct { const Self = @This(); alloc: std.mem.Allocator, @@ -427,110 +428,24 @@ const Window = struct { } }; -pub fn wait_events() void { +pub fn wait_events() []const EventBus.Event { _events.clear(); c.glfwWaitEvents(); + return _events.events.items; } -pub fn poll_events() void { +pub fn poll_events() []const EventBus.Event { _events.clear(); c.glfwPollEvents(); + return _events.events.items; } -pub fn wait_events_timeout(seconds: f64) void { +pub fn wait_events_timeout(seconds: f64) []const EventBus.Event { _events.clear(); c.glfwWaitEventsTimeout(seconds); + return _events.events.items; } -const Event = union(enum) { - charMods: struct { - codepoint: u21, - mods: i32, - }, - mouseButton: struct { - btn: u32, // todo enum - action: bool, // todo enum - mods: u32, - }, -}; - -// pub const GLFWwindowposfun = ?*const fn (?*GLFWwindow, c_int, c_int) callconv(.C) void; -// pub const GLFWwindowsizefun = ?*const fn (?*GLFWwindow, c_int, c_int) callconv(.C) void; -// pub const GLFWwindowclosefun = ?*const fn (?*GLFWwindow) callconv(.C) void; -// pub const GLFWwindowrefreshfun = ?*const fn (?*GLFWwindow) callconv(.C) void; -// pub const GLFWwindowfocusfun = ?*const fn (?*GLFWwindow, c_int) callconv(.C) void; -// pub const GLFWwindowiconifyfun = ?*const fn (?*GLFWwindow, c_int) callconv(.C) void; -// pub const GLFWwindowmaximizefun = ?*const fn (?*GLFWwindow, c_int) callconv(.C) void; -// pub const GLFWframebuffersizefun = ?*const fn (?*GLFWwindow, c_int, c_int) callconv(.C) void; -// pub const GLFWwindowcontentscalefun = ?*const fn (?*GLFWwindow, f32, f32) callconv(.C) void; -// pub const GLFWmousebuttonfun = ?*const fn (?*GLFWwindow, c_int, c_int, c_int) callconv(.C) void; -// pub const GLFWcursorposfun = ?*const fn (?*GLFWwindow, f64, f64) callconv(.C) void; -// pub const GLFWcursorenterfun = ?*const fn (?*GLFWwindow, c_int) callconv(.C) void; -// pub const GLFWscrollfun = ?*const fn (?*GLFWwindow, f64, f64) callconv(.C) void; -// pub const GLFWkeyfun = ?*const fn (?*GLFWwindow, c_int, c_int, c_int, c_int) callconv(.C) void; -// pub const GLFWcharfun = ?*const fn (?*GLFWwindow, c_uint) callconv(.C) void; -// pub const GLFWcharmodsfun = ?*const fn (?*GLFWwindow, c_uint, c_int) callconv(.C) void; -// pub const GLFWdropfun = ?*const fn (?*GLFWwindow, c_int, [*c][*c]const u8) callconv(.C) void; // todo lifetime issues -// pub const GLFWmonitorfun = ?*const fn (?*GLFWmonitor, c_int) callconv(.C) void; -// pub const GLFWjoystickfun = ?*const fn (c_int, c_int) callconv(.C) void; // todo skip for now - -pub fn onCharMods(handle: ?*c.GLFWwindow, code: u32, mods: i32) callconv(.C) void { - const bus: *EventBus = - @alignCast(@ptrCast(c.glfwGetWindowUserPointer(handle))); - bus.events.append(bus.alloc, .{ - .charMods = .{ - .codepoint = @intCast(code), - .mods = mods, - }, - }) catch unreachable; // todo circular queue; warn. -} - -pub fn onMouseButton(handle: ?*c.GLFWwindow, btn: c_int, action: c_int, mods: c_int) callconv(.C) void { - const bus: *EventBus = - @alignCast(@ptrCast(c.glfwGetWindowUserPointer(handle))); - bus.events.append(bus.alloc, .{ - .mouseButton = .{ - .btn = @intCast(btn), - .action = action == c.GLFW_PRESS, - .mods = @intCast(mods), - }, - }) catch unreachable; // todo circular queue; warn. -} - -const EventBus = struct { - const Self = @This(); - - alloc: std.mem.Allocator, - events: std.ArrayListUnmanaged(Event), // todo bounded array? - - pub fn init(alloc: std.mem.Allocator) Self { - return .{ - .alloc = alloc, - .events = .{}, - }; - } - - pub fn deinit(self: *EventBus) void { - self.events.deinit(self.alloc); - } - - pub fn connect(self: *EventBus, window: *Window) !void { - c.glfwSetWindowUserPointer(window.handle, self); - _ = c.glfwSetCharModsCallback(window.handle, onCharMods); - _ = c.glfwSetMouseButtonCallback(window.handle, onMouseButton); - } - - pub fn disconnect(_: *EventBus, window: *Window) !void { - // todo somehow prevent double-disconnect? - _ = c.glfwSetCharModsCallback(window.handle, null); - _ = c.glfwSetMouseButtonCallback(window.handle, null); - } - - pub fn clear(self: *EventBus) void { - self.events.clearRetainingCapacity(); - } -}; - fn init_event_bus(alloc: std.mem.Allocator) !void { _events = EventBus.init(alloc); errdefer _events.deinit(); diff --git a/src/au/Bus.zig b/src/au/Bus.zig new file mode 100644 index 0000000..95f0f90 --- /dev/null +++ b/src/au/Bus.zig @@ -0,0 +1,257 @@ +const std = @import("std"); +const c = @import("../c.zig"); +const Window = @import("../au.zig").Window; +const Self = @This(); + +alloc: std.mem.Allocator, +events: std.ArrayListUnmanaged(Event), // todo bounded array? + +pub fn init(alloc: std.mem.Allocator) Self { + return .{ + .alloc = alloc, + .events = .{}, + }; +} + +pub fn deinit(self: *Self) void { + self.events.deinit(self.alloc); +} + +pub fn connect(self: *Self, window: *Window) !void { + // todo somehow prevent double-connect? + c.glfwSetWindowUserPointer(window.handle, self); + _ = c.glfwSetWindowPosCallback(window.handle, onWindowPos); + _ = c.glfwSetWindowSizeCallback(window.handle, onWindowSize); + _ = c.glfwSetWindowCloseCallback(window.handle, onWindowClose); + _ = c.glfwSetWindowRefreshCallback(window.handle, onWindowRefresh); + _ = c.glfwSetWindowFocusCallback(window.handle, onWindowFocus); + _ = c.glfwSetWindowIconifyCallback(window.handle, onWindowIconify); + _ = c.glfwSetWindowMaximizeCallback(window.handle, onWindowMaximize); + _ = c.glfwSetFramebufferSizeCallback(window.handle, onFramebufferSize); + _ = c.glfwSetWindowContentScaleCallback(window.handle, onWindowContentScale); + _ = c.glfwSetMouseButtonCallback(window.handle, onMouseButton); + _ = c.glfwSetCursorPosCallback(window.handle, onCursorPos); + _ = c.glfwSetCursorEnterCallback(window.handle, onCursorEnter); + _ = c.glfwSetScrollCallback(window.handle, onScroll); + _ = c.glfwSetKeyCallback(window.handle, onKey); + _ = c.glfwSetCharModsCallback(window.handle, onCharMods); + // _ = c.glfwSetDropCallback(window.handle, onDrop); +} + +pub fn disconnect(_: *Self, window: *Window) !void { + // todo somehow prevent double-disconnect? + c.glfwSetWindowUserPointer(window.handle, null); + _ = c.glfwSetWindowPosCallback(window.handle, null); + _ = c.glfwSetWindowSizeCallback(window.handle, null); + _ = c.glfwSetWindowCloseCallback(window.handle, null); + _ = c.glfwSetWindowRefreshCallback(window.handle, null); + _ = c.glfwSetWindowFocusCallback(window.handle, null); + _ = c.glfwSetWindowIconifyCallback(window.handle, null); + _ = c.glfwSetWindowMaximizeCallback(window.handle, null); + _ = c.glfwSetFramebufferSizeCallback(window.handle, null); + _ = c.glfwSetWindowContentScaleCallback(window.handle, null); + _ = c.glfwSetMouseButtonCallback(window.handle, null); + _ = c.glfwSetCursorPosCallback(window.handle, null); + _ = c.glfwSetCursorEnterCallback(window.handle, null); + _ = c.glfwSetScrollCallback(window.handle, null); + _ = c.glfwSetKeyCallback(window.handle, null); + _ = c.glfwSetCharModsCallback(window.handle, null); + // _ = c.glfwSetDropCallback(window.handle, null); +} + +pub fn clear(self: *Self) void { + self.events.clearRetainingCapacity(); +} + +fn getBus(handle: ?*c.GLFWwindow) *Self { + return @alignCast(@ptrCast(c.glfwGetWindowUserPointer(handle))); +} + +pub const Event = union(enum) { + const WindowPos = struct { x: i32, y: i32 }; + const WindowSize = struct { x: i32, y: i32 }; + const WindowClose = struct {}; + const WindowRefresh = struct {}; + const WindowFocus = struct { focused: bool }; + const WindowIconify = struct { iconified: bool }; + const WindowMaximize = struct { maximized: bool }; + const FramebufferSize = struct { x: i32, y: i32 }; + const WindowContentScale = struct { x: f32, y: f32 }; + const MouseButton = struct { + button: c_int, // todo enum + action: c_int, // todo enum + mods: c_int, // todo bitmask + }; + const CursorPos = struct { x: f64, y: f64 }; + const CursorEnter = struct { entered: bool }; + const Scroll = struct { dx: f64, dy: f64 }; + const Key = struct { + key: c_int, // todo enum + scan: c_int, // todo ??? + action: c_int, // todo enum + mods: c_int, // todo bitmask + }; + const Char = struct { + code: u21, + }; + const CharMods = struct { + code: u21, + mods: c_int, // todo bitmask + }; + const Drop = struct { + paths: []const []const u8, // todo lifetime issues + }; + + windowPos: WindowPos, + windowSize: WindowSize, + windowClose: WindowClose, + windowRefresh: WindowRefresh, + windowFocus: WindowFocus, + windowIconify: WindowIconify, + windowMaximize: WindowMaximize, + framebufferSize: FramebufferSize, + windowContentScale: WindowContentScale, + mouseButton: MouseButton, + cursorPos: CursorPos, + cursorEnter: CursorEnter, + scroll: Scroll, + key: Key, + char: Char, + charMods: CharMods, + drop: Drop, +}; + +fn onWindowPos(handle: ?*c.GLFWwindow, x: c_int, y: c_int) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .windowPos = .{ + .x = @intCast(x), + .y = @intCast(y), + }, + }) catch unreachable; // todo circular queue; warn +} +fn onWindowSize(handle: ?*c.GLFWwindow, x: c_int, y: c_int) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .windowSize = .{ + .x = @intCast(x), + .y = @intCast(y), + }, + }) catch unreachable; // todo circular queue; warn +} +fn onWindowClose(handle: ?*c.GLFWwindow) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .windowClose = .{}, + }) catch unreachable; // todo circular queue; warn +} +fn onWindowRefresh(handle: ?*c.GLFWwindow) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .windowRefresh = .{}, + }) catch unreachable; // todo circular queue; warn +} +fn onWindowFocus(handle: ?*c.GLFWwindow, focused: c_int) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .windowFocus = .{ + .focused = focused == c.GLFW_TRUE, + }, + }) catch unreachable; // todo circular queue; warn +} +fn onWindowIconify(handle: ?*c.GLFWwindow, iconified: c_int) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .windowIconify = .{ + .iconified = iconified == c.GLFW_TRUE, + }, + }) catch unreachable; // todo circular queue; warn +} +fn onWindowMaximize(handle: ?*c.GLFWwindow, maximized: c_int) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .windowMaximize = .{ + .maximized = maximized == c.GLFW_TRUE, + }, + }) catch unreachable; // todo circular queue; warn +} +fn onFramebufferSize(handle: ?*c.GLFWwindow, x: c_int, y: c_int) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .framebufferSize = .{ + .x = @intCast(x), + .y = @intCast(y), + }, + }) catch unreachable; // todo circular queue; warn +} +fn onWindowContentScale(handle: ?*c.GLFWwindow, x: f32, y: f32) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .windowContentScale = .{ + .x = x, + .y = y, + }, + }) catch unreachable; // todo circular queue; warn +} +fn onMouseButton(handle: ?*c.GLFWwindow, button: c_int, action: c_int, mods: c_int) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .mouseButton = .{ + .button = button, + .action = action, + .mods = mods, + }, + }) catch unreachable; // todo circular queue; warn +} +fn onCursorPos(handle: ?*c.GLFWwindow, x: f64, y: f64) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .cursorPos = .{ + .x = x, + .y = y, + }, + }) catch unreachable; // todo circular queue; warn +} +fn onCursorEnter(handle: ?*c.GLFWwindow, entered: c_int) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .cursorEnter = .{ + .entered = entered == c.GLFW_TRUE, + }, + }) catch unreachable; // todo circular queue; warn +} +fn onScroll(handle: ?*c.GLFWwindow, dx: f64, dy: f64) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .scroll = .{ + .dx = dx, + .dy = dy, + }, + }) catch unreachable; // todo circular queue; warn +} +fn onKey(handle: ?*c.GLFWwindow, key: c_int, scan: c_int, action: c_int, mods: c_int) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .key = .{ + .key = key, + .scan = scan, + .action = action, + .mods = mods, + }, + }) catch unreachable; // todo circular queue; warn +} +fn onCharMods(handle: ?*c.GLFWwindow, code: c_uint, mods: c_int) callconv(.C) void { + const bus = getBus(handle); + bus.events.append(bus.alloc, .{ + .charMods = .{ + .code = @intCast(code), + .mods = mods, + }, + }) catch unreachable; // todo circular queue; warn +} +// fn onDrop(handle: ?*c.GLFWwindow, count: c_int, paths: [*c][*c]const u8) callconv(.C) void { +// const bus = getBus(handle); +// bus.events.append(bus.alloc, .{ +// .drop = .{}, +// }) catch unreachable; // todo circular queue; warn +// } diff --git a/src/main.zig b/src/main.zig index 84c4a61..1481741 100644 --- a/src/main.zig +++ b/src/main.zig @@ -102,10 +102,10 @@ pub fn main() !void { // std.debug.print("Initialized!!\n", .{ }); while (!au.W.should_close()) { - au.wait_events(); - // if (au.E.events.items.len > 0) { - // std.debug.print("Events: {any}\n", .{au.E.events.items}); - // } + for (au.wait_events()) |event| switch (event) { + .charMods => |e| std.debug.print("{any}\n", .{e}), + .mouseButton => |e| std.debug.print("{any}\n", .{e}), + }; } try au.D.deviceWaitIdle();