mirror of
https://github.com/MezzalunaWM/Mezzaluna.git
synced 2026-03-07 19:49:53 -05:00
84 lines
2.4 KiB
Zig
84 lines
2.4 KiB
Zig
const RemoteLua = @This();
|
|
|
|
const std = @import("std");
|
|
const zlua = @import("zlua");
|
|
const wayland = @import("wayland");
|
|
const Utils = @import("utils.zig");
|
|
const Lua = @import("lua/lua.zig");
|
|
const wl = wayland.server.wl;
|
|
const mez = wayland.server.zmez;
|
|
|
|
const gpa = std.heap.c_allocator;
|
|
const server = &@import("main.zig").server;
|
|
|
|
node: std.DoublyLinkedList.Node,
|
|
remote_lua_v1: *mez.RemoteLuaV1,
|
|
L: *zlua.Lua,
|
|
|
|
pub fn sendNewLogEntry(str: [*:0]const u8) void {
|
|
var node = server.remote_lua_clients.first;
|
|
while (node) |n| {
|
|
const data: ?*RemoteLua = @fieldParentPtr("node", n);
|
|
if (data) |d| d.remote_lua_v1.sendNewLogEntry(str);
|
|
node = n.next;
|
|
}
|
|
}
|
|
|
|
pub fn create(client: *wl.Client, version: u32, id: u32) !void {
|
|
const remote_lua_v1 = try mez.RemoteLuaV1.create(client, version, id);
|
|
|
|
const node = try gpa.create(RemoteLua);
|
|
errdefer gpa.destroy(node);
|
|
node.* = .{
|
|
.remote_lua_v1 = remote_lua_v1,
|
|
.node = .{},
|
|
.L = try zlua.Lua.init(gpa),
|
|
};
|
|
errdefer node.L.deinit();
|
|
node.L.openLibs();
|
|
Lua.openLibs(node.L);
|
|
// TODO: replace stdout and stderr with buffers we can send to the clients
|
|
|
|
server.remote_lua_clients.prepend(&node.node);
|
|
|
|
remote_lua_v1.setHandler(*RemoteLua, handleRequest, handleDestroy, node);
|
|
}
|
|
|
|
fn handleRequest(
|
|
remote_lua_v1: *mez.RemoteLuaV1,
|
|
request: mez.RemoteLuaV1.Request,
|
|
remote: *RemoteLua,
|
|
) void {
|
|
switch (request) {
|
|
.destroy => remote_lua_v1.destroy(),
|
|
.push_lua => |req| {
|
|
const chunk = std.mem.sliceTo(req.lua_chunk, 0);
|
|
remote.L.loadString(chunk) catch catchLuaFail(remote);
|
|
remote.L.protectedCall(.{}) catch catchLuaFail(remote);
|
|
},
|
|
}
|
|
}
|
|
|
|
fn handleDestroy(_: *mez.RemoteLuaV1, remote_lua: *RemoteLua) void {
|
|
if (remote_lua.node.prev) |p| {
|
|
if (remote_lua.node.next) |n| n.prev.? = p;
|
|
p.next = remote_lua.node.next;
|
|
} else server.remote_lua_clients.first = remote_lua.node.next;
|
|
|
|
remote_lua.L.deinit();
|
|
gpa.destroy(remote_lua);
|
|
}
|
|
|
|
fn catchLuaFail(remote: *RemoteLua) void {
|
|
const err_txt: []const u8 = remote.L.toString(-1) catch unreachable;
|
|
const txt = std.mem.concat(gpa, u8, &[_][]const u8{ "repl: ", err_txt }) catch Utils.oomPanic();
|
|
defer gpa.free(txt);
|
|
|
|
// must add the sentinel back to pass the data over the wire
|
|
const w_sentinel = gpa.allocSentinel(u8, txt.len, 0) catch Utils.oomPanic();
|
|
defer gpa.free(w_sentinel);
|
|
std.mem.copyForwards(u8, w_sentinel, txt[0..txt.len]);
|
|
|
|
sendNewLogEntry(w_sentinel);
|
|
return;
|
|
}
|