mirror of
https://codeberg.org/fairyglade/ly.git
synced 2026-08-18 03:29:13 +02:00
opt: lua API optimizations, buffer-based drawing, LuaJIT
This commit is contained in:
parent
1019acfa9e
commit
e4a945f925
3 changed files with 112 additions and 55 deletions
|
|
@ -74,6 +74,7 @@ pub fn build(b: *std.Build) !void {
|
|||
const zlua = b.dependency("zlua", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.lang = .luajit
|
||||
});
|
||||
exe.root_module.addImport("zlua", zlua.module("zlua"));
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ instance: ?Widget = null,
|
|||
lua: *zlua.Lua,
|
||||
log: *LogFile,
|
||||
terminal_buffer: *TerminalBuffer,
|
||||
width: usize,
|
||||
height: usize,
|
||||
io: std.Io,
|
||||
|
||||
lua_error: bool = false,
|
||||
|
|
@ -33,53 +35,110 @@ pub fn init(
|
|||
.terminal_buffer = buf,
|
||||
.instance = null,
|
||||
.log = log,
|
||||
.width = 0,
|
||||
.height = 0,
|
||||
.io = io,
|
||||
};
|
||||
self.lua.openLibs();
|
||||
|
||||
// exclude IO and debug libraries
|
||||
self.lua.openBase();
|
||||
self.lua.openBit();
|
||||
self.lua.openMath();
|
||||
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;
|
||||
defer alloc.free(zf);
|
||||
self.lua.doString(LyLua) catch {
|
||||
const errorStr = self.lua.toString(-1) catch unreachable;
|
||||
self.log.err(self.io, "Lua", "Lua Error: {s}", .{errorStr}) catch unreachable;
|
||||
self.lua.setGlobal("_ERROR");
|
||||
self.lua_error = true;
|
||||
};
|
||||
self.lua.doFile(zf) catch {
|
||||
const errorStr = self.lua.toString(-1) catch unreachable;
|
||||
self.log.err(self.io, "Lua", "Lua Error: {s}", .{errorStr}) catch unreachable;
|
||||
self.lua.setGlobal("_ERROR");
|
||||
self.lua_error = true;
|
||||
};
|
||||
}
|
||||
_ = self.lua.getGlobal("ly");
|
||||
addFuncToTable(self.lua, "putCell", luaPutCell);
|
||||
self.lua.setGlobal("ly");
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
fn draw(self: *Lua) void {
|
||||
_ = 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");
|
||||
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");
|
||||
}
|
||||
if (!self.lua_error) {
|
||||
self.lua.doString(
|
||||
"draw()"
|
||||
) catch {
|
||||
_ = self.lua.getGlobal("draw");
|
||||
self.lua.protectedCall(.{}) catch {
|
||||
const errorStr = self.lua.toString(-1) catch unreachable;
|
||||
self.log.err(self.io, "Lua", "Lua Error: {s}", .{errorStr}) catch unreachable;
|
||||
self.lua.setGlobal("_ERROR");
|
||||
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_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_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_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_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_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(fg), @intCast(bg))
|
||||
.put(@rem(@as(usize, @intCast(pos)), self.width), @divFloor(@as(usize, @bitCast(pos)), self.width)) catch {};
|
||||
}
|
||||
} else {
|
||||
// set the entire background to red
|
||||
// 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|
|
||||
|
|
@ -88,13 +147,24 @@ fn draw(self: *Lua) void {
|
|||
}
|
||||
|
||||
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)
|
||||
std.debug.panic("Lua: global 'ly' must be a table: got {}", .{lyType});
|
||||
if (lyType != .table) {
|
||||
try self.log.err(self.io, "Lua", "global 'ly' must be a table: got {}", .{lyType});
|
||||
self.lua_error = true;
|
||||
self.lua.pop(-1);
|
||||
self.lua.pop(-1);
|
||||
return null;
|
||||
}
|
||||
const frameDelayType = self.lua.getTable(-2); // neut
|
||||
if (frameDelayType != .number)
|
||||
std.debug.panic("Lua: 'ly.frame_delay' must be a number: got {}", .{frameDelayType});
|
||||
if (frameDelayType != .number) {
|
||||
try self.log.err(self.io, "Lua", "'ly.frame_delay' must be a number: got {}", .{lyType});
|
||||
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
|
||||
|
|
@ -120,32 +190,3 @@ pub fn widget(self: *Lua) *Widget {
|
|||
);
|
||||
return &self.instance.?;
|
||||
}
|
||||
|
||||
fn luaPutCell(lua: ?*zlua.LuaState) callconv(.c) c_int {
|
||||
var vm = @as(*zlua.Lua, @ptrCast(lua));
|
||||
const cell = vm.checkNumeric(u32, 1);
|
||||
const fg = vm.checkNumeric(u32, 2);
|
||||
const bg = vm.checkNumeric(u32, 3);
|
||||
const x = vm.checkNumeric(usize, 4);
|
||||
const y = vm.checkNumeric(usize, 5);
|
||||
Cell.init(cell, fg, bg).put(x, y) catch {};
|
||||
|
||||
return 0; // This function doesnt return anything
|
||||
}
|
||||
|
||||
/// Adds member function `name` to table at the top of the stack
|
||||
///
|
||||
/// Pushes: 0
|
||||
/// Pops: 0, this function can be called continuously
|
||||
/// Errors: unknown
|
||||
fn addFuncToTable(
|
||||
vm: *zlua.Lua,
|
||||
comptime name: []const u8,
|
||||
func: zlua.CFn,
|
||||
) void
|
||||
{
|
||||
_ = vm.pushString(name);
|
||||
vm.pushFunction(func);
|
||||
vm.setTable(-3);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,18 @@
|
|||
ly = {
|
||||
frame_delay = 0,
|
||||
width = 0,
|
||||
height = 0,
|
||||
}
|
||||
_BUFFER = {}
|
||||
|
||||
function ly.putCell(byte, fg, bg, x, y)
|
||||
_BUFFER[x + (y * ly.width)] = {
|
||||
char = math.floor(byte),
|
||||
fg = math.floor(fg),
|
||||
bg = math.floor(bg),
|
||||
}
|
||||
end
|
||||
|
||||
function ly.clear()
|
||||
_BUFFER = {}
|
||||
end
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue