diff options
| author | Alexander M Pickering <alex@cogarr.net> | 2025-01-12 22:45:37 -0600 |
|---|---|---|
| committer | Alexander M Pickering <alex@cogarr.net> | 2025-01-12 22:45:37 -0600 |
| commit | 90ee66a3a6aae10fd84f3f43844db55229933e37 (patch) | |
| tree | f723f918871c3296636ef2538a1a29a23050e520 /src/net.moon | |
| parent | decb72f936060a65bff18e9cbf33642ea3a71cd0 (diff) | |
| download | ggj25-90ee66a3a6aae10fd84f3f43844db55229933e37.tar.gz ggj25-90ee66a3a6aae10fd84f3f43844db55229933e37.tar.bz2 ggj25-90ee66a3a6aae10fd84f3f43844db55229933e37.zip | |
work
Diffstat (limited to 'src/net.moon')
| -rw-r--r-- | src/net.moon | 114 |
1 files changed, 93 insertions, 21 deletions
diff --git a/src/net.moon b/src/net.moon index b22d6f2..acd75c7 100644 --- a/src/net.moon +++ b/src/net.moon @@ -1,54 +1,103 @@ -- Handles the bridge to javascript to do peer-to-peer connections - log = require("log") +rng = require("rng") +util = require("util") + net = {} -net.initalize = () -> +initalized = false +initalize = () -> am.eval_js(require("js_bridge")) + initalized = true net.call = (method, args) -> - print("About to eval") + if not initalized + initalize! result = am.eval_js("window.PEER." .. method .. "(" .. am.to_json(args) .. ")") - print("Done evaling") result -net.pull = () -> - messages = am.eval_js("window.PEER.message_queue") - am.eval_js("window.PEER.message_queue = []") +net.pull_peers = () -> + if not initalized + initalize! + messages = am.eval_js("window.PEER.peer_message_queue") + am.eval_js("window.PEER.peer_message_queue = []") + messages + +net.pull_connections = () -> + if not initalized + initalize! + messages = am.eval_js("window.PEER.connection_message_queue") + am.eval_js("window.PEER.connection_message_queue = []") messages callbacks = {} peers = {} connections = {} +--Connections are always create js side, this is just it's lua representation class Connection + @connections = {} + @methods = util.reverse({"data","open","close","error"}) new: (source, dest) => @source = source @dest = dest + @get: (source, dest) => + key = table.concat({source,dest},",") + if @connections[key] + return @connections[key] + @@connections[key] = Connection(source,dest) + @@connections[key] on: (event, callback) => + if not @@methods[event] + error("Tried to set an unknown event (" .. event .. ") on a connection") newid = #callbacks + 1 callbacks[newid] = callback - net.call("conn_on", {name: @source, id: @dest, e: event, message: newid}) + while am.eval_js('window.PEER.connections[["' .. @source .. '","' .. @dest .. '"].sort()] == null') + print("Waiting for peer") + coroutine.yield("Waiting for peer") + --not backwards, "on" is always called on the incomming connection + net.call("conn_on", {source: @dest, dest: @source, e: event, message: newid}) send: (msgname, msg) => net.validate(msgname, msg) - net.call("send",{name: @source, id: @dest, data: msg}) + net.call("send",{source: @source, dest: @dest, data: {msgname, msg}}) class Peer + @methods = util.reverse({"open","connection","call","close","disconnected","error"}) new: (id) => - net.call("create",{name: id}) - if id - @id = id - peers[id] = @ + -- We can't create peers with peerjs-generated random ids, + -- their names are too hard to type. + -- Instead use (Year, Month), and append 4 random digits + -- to make a unique id (people can't join past midnight at the + -- end of the month, oh well) + -- Also needs to handle id-already-taken errors. + id = id or @generate_id! + while peers[id] + id = @generate_id! + @id = id + peers[@id] = @ + net.call("create",{name: @id}) + log.info("Creating peer: " .. @id, {"net"}) + generate_id: () => + os.date("%Y%e") .. rng.randomstring("ab",1) --.. rng.numstring(4) + replace_id: () => + log.info("Regenerating id for peer: " .. @id, {"net"}) + -- peers[@id] = nil TODO: uncomment, this breaks when running multiple peers from the same tab. + net.call("delete_peer",{name: @id}) + @id = @generate_id! + peers[@id] = @ + net.call("create", {name: @id}) on: (event, callback) => + if not @@methods[event] + error("Tried to set an unknown event (" .. event .. ") on a peer.") newid = #callbacks + 1 callbacks[newid] = callback net.call("on",{name: @id, message:newid, e: event}) connect: (id, options) => - conn = net.call("connect", {name: @id, id: id}) + conn = net.call("connect", {source: @id, dest: id}) log.info("Got connection: " .. tostring(conn), {"net"}) - Connection(conn[1],conn[2]) + Connection\get(conn[1],conn[2]) net.Peer = Peer @@ -84,9 +133,10 @@ net.register_message = (name, format) -> assert(type(format) == "table", "Format must be a table") format.required = format.required or {} format.optional = format.optional or {} - assert(next(format.required) or next(format.optional), "No fields found") + if not (next(format.required) or next(format.optional)) + log.warn("Message " .. name .. " registered with no fields.") for set in *({format.required, format.optional}) - for field, type_ in pairs(format.required) + for field, type_ in pairs(set) if type(type_) == "string" key = string.format("%s\0%s\0%s",name,field,type_) if not formatcache[key] @@ -97,6 +147,7 @@ net.register_message = (name, format) -> message_callbacks[name] = {} net.validate = (name, message) -> + log.info("Validating message:" .. tostring(message), {"net"}) assert(type(message) == "table", "Message must be a table") format = messages[name] required = {} @@ -122,27 +173,48 @@ net.listen = (name, callback, id) -> net.defen = (name, id) -> message_callbacks[name][id] = nil +-- net.route = (conn, name, data) -> +-- if message_callbacks[name] +-- for id, callback in pairs(message_callbacks[name]) +-- ret = message_callbacks[name](conn, + rewrite_events = { connection: (message) -> - message.data.data = Connection(message.data.data[1], message.data.data[2]) + conn = Connection\get(message.data.data[2], message.data.data[1]) + assert(conn, "Failed to build conn?") + assert(conn.source and conn.dest) + message.data.data = conn } net.pump = () -> - msg_ = net.pull! - log.info("Processing " .. tostring(#msg_) .. " messages", {"net"}) + msg_ = net.pull_peers! + log.info("Processing " .. tostring(#msg_) .. " peer messages", {"net"}) for message in *msg_ log.info(tostring(message), {"net", message.data.peer}) if rewrite_events[message.data.e] log.info("Rewriting data due to " .. message.data.e .. " event", {"net", message.data.peer}) rewrite_events[message.data.e](message) log.info(tostring(message), {"net", message.data.peer}) + if not message.data.peer and message.data.e == "open" + log.info("Setting peerid for a peer that didn't have one " ..tostring(message), {"net"}) peer = peers[message.data.peer] - assert(peer, "Failed to find peer:" .. message.data.peer) + assert(peer, "Failed to find peer:" .. message.data.peer .. " peers:" .. tostring(net.peers!)) callback = callbacks[message.message] assert(callback, "Failed to find callback " .. message.message .. " on peer " .. message.data.peer) callback(peer,message.data) + msg_ = net.pull_connections! + log.info("Processing " .. tostring(#msg_) .. " connection messages", {"net"}) + for message in *msg_ + log.info(tostring(message), {"net", message.data.peer}) + connection = Connection\get(message.dest, message.peer) + callback = callbacks[message.message] + assert(callback, "Fakled to find callback " .. message.message .. " for message" .. tostring(message)) + callback(connection, message.data) + net.peers = () -> peers +initalize! + net |
