From 498ec7c1f339d32498d73a3dfe89fb1e659ff49d Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Fri, 21 Mar 2025 22:12:36 -0500 Subject: [PATCH] queue: add drain, use drain in vxfw --- src/queue.zig | 24 ++++++++++++++++--- src/vxfw/App.zig | 60 ++++++++++++++++++++++++++---------------------- 2 files changed, 54 insertions(+), 30 deletions(-) diff --git a/src/queue.zig b/src/queue.zig index 7a27d6a..f6a7363 100644 --- a/src/queue.zig +++ b/src/queue.zig @@ -36,9 +36,7 @@ pub fn Queue( self.not_full.signal(); } - const result = self.buf[self.mask(self.read_index)]; - self.read_index = self.mask2(self.read_index + 1); - return result; + return self.popLH(); } /// Push an item into the queue. Blocks until an item has been @@ -97,6 +95,20 @@ pub fn Queue( std.debug.assert(!self.isEmptyLH()); } + pub fn lock(self: *Self) void { + self.mutex.lock(); + } + + pub fn unlock(self: *Self) void { + self.mutex.unlock(); + } + + /// Used to efficiently drain the queue while the lock is externally held + pub fn drain(self: *Self) ?T { + if (self.isEmptyLH()) return null; + return self.popLH(); + } + fn isEmptyLH(self: Self) bool { return self.write_index == self.read_index; } @@ -137,6 +149,12 @@ pub fn Queue( fn mask2(self: Self, index: usize) usize { return index % (2 * self.buf.len); } + + fn popLH(self: *Self) T { + const result = self.buf[self.mask(self.read_index)]; + self.read_index = self.mask2(self.read_index + 1); + return result; + } }; } diff --git a/src/vxfw/App.zig b/src/vxfw/App.zig index 3c72748..ef3059b 100644 --- a/src/vxfw/App.zig +++ b/src/vxfw/App.zig @@ -119,33 +119,39 @@ pub fn run(self: *App, widget: vxfw.Widget, opts: Options) anyerror!void { try self.checkTimers(&ctx); - while (loop.tryEvent()) |event| { - defer { - // Reset our context - ctx.consume_event = false; - ctx.phase = .capturing; - } - switch (event) { - .key_press => { - try focus_handler.handleEvent(&ctx, event); - try self.handleCommand(&ctx.cmds); - }, - .focus_out => { - try mouse_handler.mouseExit(self, &ctx); - try focus_handler.handleEvent(&ctx, .focus_out); - }, - .focus_in => { - try focus_handler.handleEvent(&ctx, .focus_in); - }, - .mouse => |mouse| try mouse_handler.handleMouse(self, &ctx, mouse), - .winsize => |ws| { - try vx.resize(self.allocator, tty.anyWriter(), ws); - ctx.redraw = true; - }, - else => { - try focus_handler.handleEvent(&ctx, event); - try self.handleCommand(&ctx.cmds); - }, + { + loop.queue.lock(); + defer loop.queue.unlock(); + while (loop.queue.drain()) |event| { + defer { + // Reset our context + ctx.consume_event = false; + ctx.phase = .capturing; + } + switch (event) { + .key_press => { + try focus_handler.handleEvent(&ctx, event); + try self.handleCommand(&ctx.cmds); + }, + .focus_out => { + try mouse_handler.mouseExit(self, &ctx); + try focus_handler.handleEvent(&ctx, .focus_out); + try self.handleCommand(&ctx.cmds); + }, + .focus_in => { + try focus_handler.handleEvent(&ctx, .focus_in); + try self.handleCommand(&ctx.cmds); + }, + .mouse => |mouse| try mouse_handler.handleMouse(self, &ctx, mouse), + .winsize => |ws| { + try vx.resize(self.allocator, tty.anyWriter(), ws); + ctx.redraw = true; + }, + else => { + try focus_handler.handleEvent(&ctx, event); + try self.handleCommand(&ctx.cmds); + }, + } } } -- 2.51.2