From cecf774ed2e784359b735ce491a86f86d087ea2a Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Mon, 11 Mar 2024 09:24:42 -0500 Subject: [PATCH] event: implement pollEvent and tryEvent Implement a way for an application to poll the event loop in a blocking way without popping an event. Implement a non-blocking pop. These together enable an application to poll the event loop and then drain it. This is useful when lots of events are delivered in a short amount of time so an application can batch process the events and then render. Signed-off-by: Tim Culverhouse --- src/queue.zig | 10 ++++++++++ src/vaxis.zig | 11 +++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/queue.zig b/src/queue.zig index 1d69ecc..30cb3f2 100644 --- a/src/queue.zig +++ b/src/queue.zig @@ -87,6 +87,16 @@ pub fn Queue( return self.pop(); } + /// Poll the queue. This call blocks until events are in the queue + pub fn poll(self: *Self) void { + self.mutex.lock(); + defer self.mutex.unlock(); + while (self.isEmptyLH()) { + self.not_empty.wait(&self.mutex); + } + std.debug.assert(!self.isEmptyLH()); + } + fn isEmptyLH(self: Self) bool { return self.write_index == self.read_index; } diff --git a/src/vaxis.zig b/src/vaxis.zig index 8de7452..51c7623 100644 --- a/src/vaxis.zig +++ b/src/vaxis.zig @@ -146,6 +146,17 @@ pub fn Vaxis(comptime T: type) type { return self.queue.pop(); } + /// blocks until an event is available. Useful when your application is + /// operating on a poll + drain architecture (see tryEvent) + pub fn pollEvent(self: *Self) void { + self.queue.poll(); + } + + /// returns an event if one is available, otherwise null. Non-blocking. + pub fn tryEvent(self: *Self) ?Event { + return self.queue.tryPop(); + } + /// posts an event into the event queue. Will block if there is not /// capacity for the event pub fn postEvent(self: *Self, event: T) void {