mirror of
https://github.com/MezzalunaWM/Mezzaluna.git
synced 2026-03-07 19:49:53 -05:00
Merge branch 'mez_remote_lua' into dev
This commit is contained in:
commit
1f2e333846
7 changed files with 293 additions and 39 deletions
103
src/RemoteLua.zig
Normal file
103
src/RemoteLua.zig
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
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 {
|
||||
const L = remote.L;
|
||||
switch (request) {
|
||||
.destroy => remote_lua_v1.destroy(),
|
||||
.push_lua => |req| {
|
||||
const chunk: [:0]const u8 = std.mem.sliceTo(req.lua_chunk, 0);
|
||||
|
||||
const str = std.mem.concatWithSentinel(gpa, u8, &[_][]const u8{
|
||||
"return ",
|
||||
chunk,
|
||||
";",
|
||||
}, 0) catch return catchLuaFail(remote);
|
||||
defer gpa.free(str);
|
||||
|
||||
zlua.Lua.loadBuffer(L, str, "=repl", zlua.Mode.text) catch {
|
||||
L.pop(L.getTop());
|
||||
L.loadString(chunk) catch {
|
||||
catchLuaFail(remote);
|
||||
L.pop(-1);
|
||||
};
|
||||
return;
|
||||
};
|
||||
|
||||
L.protectedCall(.{ .results = zlua.mult_return, }) catch {
|
||||
catchLuaFail(remote);
|
||||
L.pop(1);
|
||||
};
|
||||
|
||||
var i: i32 = 1;
|
||||
const nresults = L.getTop();
|
||||
while (i <= nresults) : (i += 1) {
|
||||
// TODO: support lua5.1 and luajit?
|
||||
sendNewLogEntry(L.toStringEx(i));
|
||||
L.pop(-1);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
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: [:0]const u8 = remote.L.toStringEx(-1);
|
||||
sendNewLogEntry(std.mem.sliceTo(err, 0));
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue