libvaxis/src/Loop.zig

62 lines
1.9 KiB
Zig
Raw Normal View History

const std = @import("std");
const Queue = @import("queue.zig").Queue;
const Tty = @import("Tty.zig");
const Vaxis = @import("Vaxis.zig");
pub fn Loop(comptime T: type) type {
return struct {
const Self = @This();
const log = std.log.scoped(.loop);
queue: Queue(T, 512) = .{},
thread: ?std.Thread = null,
vaxis: *Vaxis,
/// spawns the input thread to read input from the tty
pub fn run(self: *Self) !void {
if (self.thread) |_| return;
if (self.vaxis.tty == null) self.vaxis.tty = try Tty.init();
self.thread = try std.Thread.spawn(.{}, Tty.run, .{ &self.vaxis.tty.?, T, self });
}
/// stops reading from the tty and returns it to it's initial state
pub fn stop(self: *Self) void {
if (self.vaxis.tty) |*tty| tty.stop();
if (self.thread) |thread| {
thread.join();
self.thread = null;
}
}
/// returns the next available event, blocking until one is available
pub fn nextEvent(self: *Self) T {
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) ?T {
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 {
self.queue.push(event);
}
pub fn tryPostEvent(self: *Self, event: T) bool {
return self.queue.tryPush(event);
}
};
}