mirror of
https://codeberg.org/fairyglade/ly.git
synced 2026-08-09 15:19:13 +02:00
review pt 1
This commit is contained in:
parent
0c14f4367a
commit
cc14fff5c6
5 changed files with 160 additions and 161 deletions
|
|
@ -74,18 +74,16 @@ pub fn build(b: *std.Build) !void {
|
|||
const zlua = b.dependency("zlua", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.lang = .luajit
|
||||
.lang = .luajit,
|
||||
});
|
||||
exe.root_module.addImport("zlua", zlua.module("zlua"));
|
||||
|
||||
|
||||
|
||||
const ly_ui = b.dependency("ly_ui", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.enable_x11_support = enable_x11_support,
|
||||
.fallback_uid_min = fallback_uid_min,
|
||||
.fallback_uid_max = fallback_uid_max
|
||||
.fallback_uid_max = fallback_uid_max,
|
||||
});
|
||||
exe.root_module.addImport("ly-ui", ly_ui.module("ly-ui"));
|
||||
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ local SQUARE_WIDTH = 10
|
|||
local SQUARE_HEIGHT = 5
|
||||
|
||||
local SQUARE_COUNT = 25
|
||||
|
||||
local FPS = 120
|
||||
|
||||
local squares = {}
|
||||
|
||||
for i = 0, SQUARE_COUNT-1 do
|
||||
|
|
@ -44,7 +47,7 @@ local timer = os.clock()
|
|||
function draw()
|
||||
-- Rather than progressing the animation by frame, do it based on
|
||||
-- seconds, like from os.clock().
|
||||
if timer + 0.025 < os.clock() then
|
||||
if timer + (1/FPS) < os.clock() then
|
||||
ly.clear()
|
||||
for i, v in ipairs(squares) do
|
||||
v.x = v.x + v.vx
|
||||
|
|
|
|||
|
|
@ -5,10 +5,11 @@ const Widget = ly_ui.Widget;
|
|||
const TerminalBuffer = ly_ui.TerminalBuffer;
|
||||
const Cell = ly_ui.Cell;
|
||||
const Allocator = std.mem.Allocator;
|
||||
const InfoLine = @import("../components/InfoLine.zig");
|
||||
|
||||
const zlua = @import("zlua");
|
||||
|
||||
const LyLua = @embedFile("ly.lua");
|
||||
const ly_lua = @embedFile("ly.lua");
|
||||
|
||||
const Lua = @This();
|
||||
|
||||
|
|
@ -21,8 +22,14 @@ width: usize,
|
|||
height: usize,
|
||||
margin: usize,
|
||||
io: std.Io,
|
||||
animation_delay: u16,
|
||||
|
||||
info_line: *InfoLine,
|
||||
fg: u32,
|
||||
bg: u32,
|
||||
|
||||
lua_error: bool = false,
|
||||
lua_error_logged: bool = false,
|
||||
lua_str: ?[:0]const u8 = null,
|
||||
|
||||
pub fn init(
|
||||
|
|
@ -30,8 +37,12 @@ pub fn init(
|
|||
alloc: Allocator,
|
||||
log: *LogFile,
|
||||
buf: *TerminalBuffer,
|
||||
file: ?[]const u8,
|
||||
file: []const u8,
|
||||
margin: u8,
|
||||
animation_delay: u16,
|
||||
info_line: *InfoLine,
|
||||
fg: u32,
|
||||
bg: u32,
|
||||
) !Lua {
|
||||
var self: Lua = .{
|
||||
.lua = try zlua.Lua.init(alloc),
|
||||
|
|
@ -43,6 +54,10 @@ pub fn init(
|
|||
.height = 0,
|
||||
.margin = margin,
|
||||
.io = io,
|
||||
.animation_delay = animation_delay,
|
||||
.info_line = info_line,
|
||||
.fg = fg,
|
||||
.bg = bg,
|
||||
};
|
||||
|
||||
// exclude IO and debug libraries
|
||||
|
|
@ -52,42 +67,179 @@ pub fn init(
|
|||
self.lua.openOS();
|
||||
self.lua.openString();
|
||||
self.lua.openTable();
|
||||
self.lua.openString();
|
||||
|
||||
if (file) |f| {
|
||||
const zf = std.mem.concatWithSentinel(alloc, u8, &[1][]const u8{f}, 0) catch unreachable;
|
||||
file_loading: {
|
||||
const zf = std.mem.concatWithSentinel(alloc, u8, &[1][]const u8{file}, 0) catch |e| {
|
||||
self.log.err(self.io, "lua", "failed to allocate file path: {}", .{e}) catch unreachable;
|
||||
self.lua_str = "failed to allocate file path!";
|
||||
self.lua_error = true;
|
||||
break :file_loading;
|
||||
};
|
||||
defer alloc.free(zf);
|
||||
self.lua.doString(LyLua) catch {
|
||||
|
||||
self.lua.doString(ly_lua) catch {
|
||||
const errorStr = self.lua.toString(-1) catch unreachable;
|
||||
self.lua_str = try self.allocator.dupeSentinel(u8, errorStr, 0);
|
||||
self.log.err(self.io, "Lua", "Lua Error: {s}", .{errorStr}) catch unreachable;
|
||||
self.log.err(self.io, "lua", "lua error: {s}", .{errorStr}) catch unreachable;
|
||||
self.lua_error = true;
|
||||
break :file_loading;
|
||||
};
|
||||
if (self.terminal_buffer.height != self.height or
|
||||
self.terminal_buffer.width != self.width)
|
||||
{
|
||||
self.width = self.terminal_buffer.width;
|
||||
self.height = self.terminal_buffer.height;
|
||||
_ = self.lua.getGlobal("ly");
|
||||
_ = self.lua.pushString("width");
|
||||
self.lua.pushInteger(@intCast(self.terminal_buffer.width));
|
||||
self.lua.setTable(-3);
|
||||
_ = self.lua.pushString("height");
|
||||
self.lua.pushInteger(@intCast(self.terminal_buffer.height));
|
||||
self.lua.setTable(-3);
|
||||
self.lua.setGlobal("ly");
|
||||
}
|
||||
self.propogateTerminalBounds();
|
||||
self.lua.doFile(zf) catch {
|
||||
const errorStr = self.lua.toString(-1) catch unreachable;
|
||||
self.lua_str = try self.allocator.dupeSentinel(u8, errorStr, 0);
|
||||
self.log.err(self.io, "Lua", "Lua Error: {s}", .{errorStr}) catch unreachable;
|
||||
self.log.err(self.io, "lua", "lua error: {s}", .{errorStr}) catch unreachable;
|
||||
self.lua_error = true;
|
||||
break :file_loading;
|
||||
};
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
fn draw(self: *Lua) void {
|
||||
self.propogateTerminalBounds();
|
||||
if (self.lua_error) {
|
||||
// Ly's Red Screen of Omega-Death:tm:
|
||||
const cell = Cell.init(0x2588, 0x00ff0000, 0x00ff0000);
|
||||
for (0..self.terminal_buffer.height) |y|
|
||||
for (0..self.terminal_buffer.width) |x|
|
||||
cell.put(x, y) catch {};
|
||||
if (self.lua_str) |str|
|
||||
for (str, 0..) |c, i| {
|
||||
Cell.init(c, 0x00FFFFFF, 0).put(
|
||||
@divFloor(self.width, 2) - @divFloor(str.len, 2) + i,
|
||||
self.margin + 5,
|
||||
) catch {};
|
||||
};
|
||||
if (!self.lua_error_logged) {
|
||||
self.info_line.addMessage("lua animation failed", self.bg, self.fg) catch {};
|
||||
self.lua_error_logged = true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
_ = self.lua.getGlobal("draw");
|
||||
self.lua.protectedCall(.{}) catch {
|
||||
const errorStr = self.lua.toString(-1) catch unreachable;
|
||||
self.lua_str = std.mem.concatWithSentinel(
|
||||
self.allocator,
|
||||
u8,
|
||||
&[_][]const u8{ "Cannot call draw(): ", errorStr },
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.log.err(self.io, "Lua", "Error (Cannot call draw()): {s}", .{errorStr}) catch unreachable;
|
||||
self.lua_error = true;
|
||||
};
|
||||
const bufferType = self.lua.getGlobal("_BUFFER");
|
||||
if (bufferType != .table) {
|
||||
self.log.err(self.io, "Lua", "global '_BUFFER' must be a table: got {}", .{bufferType}) catch {};
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"global '_BUFFER' must be a table: got {}",
|
||||
.{bufferType},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
return;
|
||||
}
|
||||
self.lua.pushNil();
|
||||
while (self.lua.next(-2)) {
|
||||
// expect the key to be an int
|
||||
// expect the value to be a table
|
||||
const pos = self.lua.toInteger(-2) catch {
|
||||
self.log.err(self.io, "Lua", "pos: cannot convert to integer", .{}) catch {};
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"pos: cannot convert to integer",
|
||||
.{},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
return;
|
||||
};
|
||||
|
||||
_ = self.lua.pushString("char");
|
||||
_ = self.lua.getTable(-2);
|
||||
const char = self.lua.toInteger(-1) catch {
|
||||
self.log.err(self.io, "Lua", "char: cannot convert to integer", .{}) catch {};
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"char: cannot convert to integer",
|
||||
.{},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
return;
|
||||
};
|
||||
self.lua.pop(1);
|
||||
_ = self.lua.pushString("fg");
|
||||
_ = self.lua.getTable(-2);
|
||||
const fg = self.lua.toInteger(-1) catch {
|
||||
self.log.err(self.io, "Lua", "fg: cannot convert to integer", .{}) catch {};
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"fg: cannot convert to integer",
|
||||
.{},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
return;
|
||||
};
|
||||
self.lua.pop(1);
|
||||
_ = self.lua.pushString("bg");
|
||||
_ = self.lua.getTable(-2);
|
||||
const bg = self.lua.toInteger(-1) catch {
|
||||
self.log.err(self.io, "Lua", "bg: cannot convert to integer", .{}) catch {};
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"bg: cannot convert to integer",
|
||||
.{},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
return;
|
||||
};
|
||||
self.lua.pop(1);
|
||||
self.lua.pop(1);
|
||||
if (pos < 0) continue; // do not draw cells that underflow
|
||||
TerminalBuffer.setCell(
|
||||
@rem(@as(usize, @intCast(pos)), self.width),
|
||||
@divFloor(@as(usize, @bitCast(pos)), self.width),
|
||||
.init(
|
||||
@intCast(char),
|
||||
@intCast(@as(i32, @truncate(fg))),
|
||||
@intCast(@as(i32, @truncate(bg))),
|
||||
),
|
||||
) catch {};
|
||||
}
|
||||
}
|
||||
|
||||
fn calculateTimeout(self: *Lua, _: *anyopaque) !?usize {
|
||||
return self.animation_delay;
|
||||
}
|
||||
|
||||
fn deinit(self: *Lua) void {
|
||||
if (self.lua_str) |str| self.allocator.free(str);
|
||||
self.lua.deinit();
|
||||
}
|
||||
|
||||
pub fn widget(self: *Lua) *Widget {
|
||||
if (self.instance) |*inst| return inst;
|
||||
self.instance = Widget.init(
|
||||
"Lua",
|
||||
null,
|
||||
self,
|
||||
deinit,
|
||||
null, //realloc
|
||||
draw, //draw
|
||||
null, //update
|
||||
null,
|
||||
calculateTimeout, //calculateTimeout
|
||||
);
|
||||
return &self.instance.?;
|
||||
}
|
||||
|
||||
fn propogateTerminalBounds(self: *Lua) void {
|
||||
if (self.terminal_buffer.height != self.height or
|
||||
self.terminal_buffer.width != self.width)
|
||||
{
|
||||
|
|
@ -102,162 +254,4 @@ fn draw(self: *Lua) void {
|
|||
self.lua.setTable(-3);
|
||||
self.lua.setGlobal("ly");
|
||||
}
|
||||
if (!self.lua_error) {
|
||||
_ = self.lua.getGlobal("draw");
|
||||
self.lua.protectedCall(.{}) catch {
|
||||
const errorStr = self.lua.toString(-1) catch unreachable;
|
||||
self.lua_str = std.mem.concatWithSentinel(
|
||||
self.allocator,
|
||||
u8,
|
||||
&[_][]const u8{ "Cannot call draw(): ", errorStr },
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.log.err(self.io, "Lua", "Error (Cannot call draw()): {s}", .{errorStr}) catch unreachable;
|
||||
self.lua_error = true;
|
||||
};
|
||||
const bufferType = self.lua.getGlobal("_BUFFER");
|
||||
if (bufferType != .table) {
|
||||
self.log.err(self.io, "Lua", "global '_BUFFER' must be a table: got {}", .{bufferType}) catch {};
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"global '_BUFFER' must be a table: got {}",
|
||||
.{bufferType},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
return;
|
||||
}
|
||||
self.lua.pushNil();
|
||||
while (self.lua.next(-2)) {
|
||||
// expect the key to be an int
|
||||
// expect the value to be a table
|
||||
const pos = self.lua.toInteger(-2) catch {
|
||||
self.log.err(self.io, "Lua", "pos: cannot convert to integer", .{}) catch {};
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"pos: cannot convert to integer",
|
||||
.{},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
return;
|
||||
};
|
||||
|
||||
_ = self.lua.pushString("char");
|
||||
_ = self.lua.getTable(-2);
|
||||
const char = self.lua.toInteger(-1) catch {
|
||||
self.log.err(self.io, "Lua", "char: cannot convert to integer", .{}) catch {};
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"char: cannot convert to integer",
|
||||
.{},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
return;
|
||||
};
|
||||
self.lua.pop(1);
|
||||
_ = self.lua.pushString("fg");
|
||||
_ = self.lua.getTable(-2);
|
||||
const fg = self.lua.toInteger(-1) catch {
|
||||
self.log.err(self.io, "Lua", "fg: cannot convert to integer", .{}) catch {};
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"fg: cannot convert to integer",
|
||||
.{},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
return;
|
||||
};
|
||||
self.lua.pop(1);
|
||||
_ = self.lua.pushString("bg");
|
||||
_ = self.lua.getTable(-2);
|
||||
const bg = self.lua.toInteger(-1) catch {
|
||||
self.log.err(self.io, "Lua", "bg: cannot convert to integer", .{}) catch {};
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"bg: cannot convert to integer",
|
||||
.{},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
return;
|
||||
};
|
||||
self.lua.pop(1);
|
||||
self.lua.pop(1);
|
||||
if (pos < 0) continue; // do not draw cells that underflow
|
||||
Cell.init(@intCast(char), @intCast(@as(i32, @truncate(fg))), @intCast(@as(i32, @truncate(bg))))
|
||||
.put(@rem(@as(usize, @intCast(pos)), self.width), @divFloor(@as(usize, @bitCast(pos)), self.width)) catch {};
|
||||
}
|
||||
} else {
|
||||
// Ly's Red Screen of Omega-Death:tm:
|
||||
const cell = Cell.init(0x2588, 0x00ff0000, 0x00ff0000);
|
||||
for (0..self.terminal_buffer.height) |y|
|
||||
for (0..self.terminal_buffer.width) |x|
|
||||
cell.put(x, y) catch {};
|
||||
if (self.lua_str) |str|
|
||||
for (str, 0..) |c, i| {
|
||||
Cell.init(c, 0x00FFFFFF, 0).put(@divFloor(self.width, 2) - @divFloor(str.len, 2) + i, self.margin + 5) catch {};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn calculateTimeout(self: *Lua, _: *anyopaque) !?usize {
|
||||
if (self.lua_error) return null;
|
||||
const lyType = self.lua.getGlobal("ly"); // +1
|
||||
_ = self.lua.pushString("frame_delay"); // + 1
|
||||
if (lyType != .table) {
|
||||
try self.log.err(self.io, "Lua", "global 'ly' must be a table: got {}", .{lyType});
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"global 'ly' must be a table: got {}",
|
||||
.{lyType},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
self.lua.pop(-1);
|
||||
self.lua.pop(-1);
|
||||
return null;
|
||||
}
|
||||
const frameDelayType = self.lua.getTable(-2); // neut
|
||||
if (frameDelayType != .number) {
|
||||
try self.log.err(self.io, "Lua", "'ly.frame_delay' must be a number: got {}", .{frameDelayType});
|
||||
self.lua_str = std.fmt.allocPrintSentinel(
|
||||
self.allocator,
|
||||
"'ly.frameDelayType' must be a table: got {}",
|
||||
.{frameDelayType},
|
||||
0,
|
||||
) catch unreachable;
|
||||
self.lua_error = true;
|
||||
self.lua.pop(-1);
|
||||
self.lua.pop(-1);
|
||||
return null;
|
||||
}
|
||||
const timeout = try self.lua.toNumeric(usize, -1);
|
||||
self.lua.pop(-1); // pop number from stack
|
||||
self.lua.pop(-1); // pop table 'ly' from stack
|
||||
return timeout;
|
||||
}
|
||||
|
||||
fn deinit(self: *Lua) void {
|
||||
if (self.lua_str) |str|
|
||||
self.allocator.free(str);
|
||||
self.lua.deinit();
|
||||
}
|
||||
|
||||
pub fn widget(self: *Lua) *Widget {
|
||||
if (self.instance) |*inst| return inst;
|
||||
self.instance = Widget.init(
|
||||
"Lua",
|
||||
null,
|
||||
self,
|
||||
deinit, //deinit
|
||||
null, //realloc
|
||||
draw, //draw
|
||||
null, //update
|
||||
null,
|
||||
calculateTimeout, //calculateTimeout
|
||||
);
|
||||
return &self.instance.?;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ lang: []const u8 = "en",
|
|||
login_cmd: ?[]const u8 = null,
|
||||
login_defs_path: []const u8 = "/etc/login.defs",
|
||||
logout_cmd: ?[]const u8 = null,
|
||||
lua_animation_file: ?[]const u8 = null,
|
||||
lua_animation_file: []const u8 = build_options.config_directory ++ "/ly/example.lua",
|
||||
ly_log: ?[]const u8 = "/var/log/ly.log",
|
||||
margin_box_h: u8 = 2,
|
||||
margin_box_v: u8 = 1,
|
||||
|
|
|
|||
|
|
@ -1107,6 +1107,10 @@ pub fn main(init: std.process.Init) !void {
|
|||
&state.buffer,
|
||||
state.config.lua_animation_file,
|
||||
state.config.edge_margin,
|
||||
state.config.animation_frame_delay,
|
||||
&state.info_line,
|
||||
state.config.error_fg,
|
||||
state.config.error_bg,
|
||||
);
|
||||
animation = lua.widget();
|
||||
},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue