Some checks failed
Zig Project Action / Lint, Spell-check and test zig project (push) Failing after 1m41s
104 lines
2.9 KiB
Zig
104 lines
2.9 KiB
Zig
// TODO planned features:
|
|
|
|
// FIX known issues:
|
|
|
|
pub fn main() !void {
|
|
// argument handling
|
|
var gpa: std.heap.GeneralPurposeAllocator(.{}) = .init;
|
|
defer if (gpa.deinit() == .leak) std.log.err("memory leak", .{});
|
|
|
|
var area: std.heap.ArenaAllocator = .init(gpa.allocator());
|
|
defer area.deinit();
|
|
// NOTE current setup
|
|
// - in debug builds use the gpa (to identify leaks!)
|
|
// - in other builds use the area to free all memory!
|
|
const allocator = switch (builtin.mode) {
|
|
.Debug => gpa.allocator(),
|
|
else => area.allocator(),
|
|
};
|
|
|
|
// argument handling
|
|
{
|
|
var arg_it = try std.process.argsWithAllocator(allocator);
|
|
defer arg_it.deinit();
|
|
|
|
// TODO may there be other options?
|
|
// usage: tui-diff
|
|
|
|
// skip own executable name
|
|
_ = arg_it.skip();
|
|
}
|
|
|
|
var threaded_io: std.Io.Threaded = .init(allocator);
|
|
errdefer threaded_io.deinit();
|
|
const io = threaded_io.io();
|
|
errdefer |err| log.err("Application Error: {any}", .{err});
|
|
|
|
var renderer = zterm.Renderer.Buffered.init(allocator);
|
|
defer renderer.deinit();
|
|
|
|
var app: App = .init(io, .init);
|
|
|
|
var root = try tui_diff.Container(App, allocator);
|
|
defer root.deinit(); // also de-initializes the children
|
|
|
|
try app.start();
|
|
defer app.stop() catch |err| log.err("Failed to stop application: {any}", .{err});
|
|
|
|
// event loop
|
|
loop: while (true) {
|
|
// batch events since last iteration
|
|
const len = blk: {
|
|
app.queue.poll();
|
|
app.queue.lock();
|
|
defer app.queue.unlock();
|
|
break :blk app.queue.len();
|
|
};
|
|
|
|
// handle events
|
|
for (0..len) |_| {
|
|
const event = app.queue.pop();
|
|
|
|
// pre event handling
|
|
switch (event) {
|
|
.key => |key| if (key.eql(.{ .cp = 'q' })) app.quit(),
|
|
else => {},
|
|
}
|
|
// NOTE returned errors should be propagated back to the application
|
|
root.handle(&app.model, event) catch |err| app.postEvent(.{
|
|
.err = .{
|
|
.err = err,
|
|
.msg = "Container Event handling failed",
|
|
},
|
|
});
|
|
|
|
// post event handling
|
|
switch (event) {
|
|
.quit => break :loop,
|
|
else => {},
|
|
}
|
|
}
|
|
|
|
root.resize(&app.model, try renderer.resize());
|
|
root.reposition(&app.model, .{});
|
|
|
|
try renderer.render(@TypeOf(root), &root, App.Model, &app.model);
|
|
try renderer.flush();
|
|
}
|
|
|
|
threaded_io.deinit();
|
|
}
|
|
|
|
const log = std.log.scoped(.default);
|
|
const App = zterm.App(Model, Event);
|
|
|
|
pub const panic = App.panic_handler;
|
|
|
|
const std = @import("std");
|
|
const builtin = @import("builtin");
|
|
const tui_diff = @import("tui-diff");
|
|
const zterm = @import("zterm");
|
|
|
|
const Event = tui_diff.Event;
|
|
const Model = tui_diff.Model;
|