mgba
mgba copied to clipboard
Script bindings for sockets
This PR provides an event-driven TCP socket API for mGBA scripting. Where the behaviors overlap, it roughly imitates the LuaSocket API, but due to the mGBA scripting core not being yieldable, it can't be a perfect match.
Also included are two sample scripts. Both scripts will log messages received over the socket to the console and will send an input viewer. One script will connect to a server; the other will open a server and listen for incoming connections.
Documentation still needs to be written.
Seems to be decent so far, but I'm curious what about it doesn't match, and uh, how the doc generator would handle it. I'm not really sure what the surface API would look like, to be honest. An example script is probably a good idea,
LuaSocket's receive
API also has some oddly specific behaviors: https://w3.impa.br/~diego/software/luasocket/tcp.html#receive -- *l
is useful for line-based protocols, sure, but *a
is asking for a headache thanks to blocking. It also supports a second parameter that's just prefixed onto the return value. I chose not to implement any of these.
Also, LuaSocket isn't event-driven, so there's no callback API at all.
As far as the doc generator is concerned... Yeah, I have no idea.
I sent an example script in Discord, but I'll reproduce it here:
s = socket.tcp()
s:on("received", function()
while true do
local p, err = s:receive(1024)
if p then
console:log(p:match("^(.-)%s*$"))
else
if err ~= "temporary failure" then
console:error(err)
end
return
end
end
end)
if s:connect("127.0.0.1", 8888) then
console:log("Connected")
else
console:log("Failed to connect")
end
It connects to a server and echoes anything it receives to the console.
I meant putting an example script in the repo (res/scripts). Also if you could build the doc generator and give me the yaml output I could see how it does.
@endrift By the way, I noticed that resetting the scripting state leaves any open socket resources orphaned. We should probably figure something out for that...
Also we should discuss whether or not we want SO_REUSEADDR.
I switched the example scripts over to use socket.ERRORS
instead of literal strings. As a quality-of-life tweak I also made the socket.ERRORS
table respond to both numeric and string keys.
The heck? I did that. O.o Did I manage to miss committing something? Fixed.
I'm ready to merge this unless you have any last-minute changes you want to make.
No complaints from me!