mgba icon indicating copy to clipboard operation
mgba copied to clipboard

Script bindings for sockets

Open ahigerd opened this issue 2 years ago • 6 comments

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.

ahigerd avatar Aug 07 '22 04:08 ahigerd

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,

endrift avatar Aug 20 '22 22:08 endrift

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.

ahigerd avatar Aug 21 '22 01:08 ahigerd

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 avatar Aug 21 '22 05:08 endrift

@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.

ahigerd avatar Sep 05 '22 05:09 ahigerd

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.

ahigerd avatar Sep 21 '22 20:09 ahigerd

The heck? I did that. O.o Did I manage to miss committing something? Fixed.

ahigerd avatar Sep 21 '22 23:09 ahigerd

I'm ready to merge this unless you have any last-minute changes you want to make.

endrift avatar Sep 22 '22 01:09 endrift

No complaints from me!

ahigerd avatar Sep 22 '22 01:09 ahigerd