libvaxis/src/Loop.zig

73 lines
2.2 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,
&self.vaxis.unicode.grapheme_data,
});
}
/// stops reading from the tty and returns it to it's initial state
pub fn stop(self: *Self) void {
if (self.vaxis.tty) |*tty| {
// stop the read loop, then join the thread
tty.stop();
if (self.thread) |thread| {
thread.join();
self.thread = null;
}
// once thread is closed we can deinit the tty
tty.deinit();
self.vaxis.tty = 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);
}
};
}