From 35fcbd05d7284e6495aa1dd6c20307fb934c9bcb Mon Sep 17 00:00:00 2001 From: Tim Culverhouse Date: Wed, 24 Jan 2024 10:20:00 -0600 Subject: [PATCH] update example Signed-off-by: Tim Culverhouse --- examples/text_input.zig | 53 ++++++++++++++++++++++++++++------------- src/vaxis.zig | 4 ++-- 2 files changed, 39 insertions(+), 18 deletions(-) diff --git a/examples/text_input.zig b/examples/text_input.zig index 86f4a71..626c27a 100644 --- a/examples/text_input.zig +++ b/examples/text_input.zig @@ -5,6 +5,17 @@ const TextInput = vaxis.widgets.TextInput; const border = vaxis.widgets.border; const log = std.log.scoped(.main); + +// Our EventType. This can contain internal events as well as Vaxis events. +// Internal events can be posted into the same queue as vaxis events to allow +// for a single event loop with exhaustive switching. Booya +const Event = union(enum) { + key_press: vaxis.Key, + winsize: vaxis.Winsize, + focus_in, + foo: u8, +}; + pub fn main() !void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; defer { @@ -16,14 +27,16 @@ pub fn main() !void { } const alloc = gpa.allocator(); - // Initialize Vaxis + // Initialize Vaxis with our event type var vx = try vaxis.init(Event, .{}); + // deinit takes an optional allocator. If your program is exiting, you can + // choose to pass a null allocator to save some exit time. defer vx.deinit(alloc); // Start the read loop. This puts the terminal in raw mode and begins // reading user input - try vx.start(); - defer vx.stop(); + try vx.startReadThread(); + defer vx.stopReadThread(); // Optionally enter the alternate screen try vx.enterAltScreen(); @@ -31,9 +44,13 @@ pub fn main() !void { // We'll adjust the color index every keypress for the border var color_idx: u8 = 0; + // init our text input widget. The text input widget needs an allocator to + // store the contents of the input var text_input = TextInput.init(alloc); defer text_input.deinit(); + // Sends queries to terminal to detect certain features. This should + // _always_ be called, but is left to the application to decide when try vx.queryTerminal(); // The main event loop. Vaxis provides a thread safe, blocking, buffered @@ -59,9 +76,22 @@ pub fn main() !void { } }, - .winsize => |ws| { - try vx.resize(alloc, ws); - }, + // winsize events are sent to the application to ensure that all + // resizes occur in the main thread. This lets us avoid expensive + // locks on the screen. All applications must handle this event + // unless they aren't using a screen (IE only detecting features) + // + // This is the only call that the core of Vaxis needs an allocator + // for. The allocations are because we keep a copy of each cell to + // optimize renders. When resize is called, we allocated two slices: + // one for the screen, and one for our buffered screen. Each cell in + // the buffered screen contains an ArrayList(u8) to be able to store + // the grapheme for that cell Each cell is initialized with a size + // of 1, which is sufficient for all of ASCII. Anything requiring + // more than one byte will incur an allocation on the first render + // after it is drawn. Thereafter, it will not allocate unless the + // screen is resized + .winsize => |ws| try vx.resize(alloc, ws), else => {}, } @@ -69,6 +99,7 @@ pub fn main() !void { // terminal and can spawn child windows as logical areas. Child windows // cannot draw outside of their bounds const win = vx.window(); + // Clear the entire space because we are drawing in immediate mode. // vaxis double buffers the screen. This new frame will be compared to // the old and only updated cells will be drawn @@ -89,13 +120,3 @@ pub fn main() !void { try vx.render(); } } - -// Our EventType. This can contain internal events as well as Vaxis events. -// Internal events can be posted into the same queue as vaxis events to allow -// for a single event loop with exhaustive switching. Booya -const Event = union(enum) { - key_press: vaxis.Key, - winsize: vaxis.Winsize, - focus_in, - foo: u8, -}; diff --git a/src/vaxis.zig b/src/vaxis.zig index 8431f6a..332b390 100644 --- a/src/vaxis.zig +++ b/src/vaxis.zig @@ -109,7 +109,7 @@ pub fn Vaxis(comptime T: type) type { } /// spawns the input thread to start listening to the tty for input - pub fn start(self: *Self) !void { + pub fn startReadThread(self: *Self) !void { self.tty = try Tty.init(); // run our tty read loop in it's own thread const read_thread = try std.Thread.spawn(.{}, Tty.run, .{ &self.tty.?, T, self }); @@ -117,7 +117,7 @@ pub fn Vaxis(comptime T: type) type { } /// stops reading from the tty - pub fn stop(self: *Self) void { + pub fn stopReadThread(self: *Self) void { if (self.tty) |_| { var tty = &self.tty.?; tty.stop();