diff options
| author | Alex Pickering <alex@cogarr.net> | 2026-02-01 13:14:32 -0600 |
|---|---|---|
| committer | Alexander M Pickering <alex@cogarr.net> | 2026-02-01 13:14:32 -0600 |
| commit | 3a975db66a3711f34e8b64bb27a8eaca79fdeca9 (patch) | |
| tree | fcc12f8f9d638ff575c1963796de76b7628854b4 /src/util.lua | |
| download | ggj26-master.tar.gz ggj26-master.tar.bz2 ggj26-master.zip | |
Diffstat (limited to 'src/util.lua')
| -rw-r--r-- | src/util.lua | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/util.lua b/src/util.lua new file mode 100644 index 0000000..f74953a --- /dev/null +++ b/src/util.lua @@ -0,0 +1,142 @@ +--[[ +Various helpful functions +]] +local util = {} +function util.cartesian(...) + -- cartesian(tbl1, tbl2, tbl3, ...) + -- for each table, returns a permutation of key, value in tbl1, tbl2, ect. + local args = {...} + return coroutine.wrap(function() + local cursors = {} -- cursors[1], cursors[3], ect. are the keys + for k,v in ipairs(args) do + local a,b = next(v,nil) + cursors[(k*2) - 1] = a + cursors[(k*2)] = b + end + coroutine.yield(unpack(cursors)) + local any_left = true + while any_left do + while next(args[#args],cursors[#cursors - 1]) do + local a,b = next(args[#args],cursors[#cursors - 1]) + cursors[#cursors - 1] = a + cursors[#cursors] = b + coroutine.yield(unpack(cursors)) + end + any_left = false + for i = #args, 1, -1 do + if next(args[i],cursors[(i*2)-1]) then + cursors[(i*2)-1], cursors[i*2] = next(args[i],cursors[(i*2)-1]) + for j = i+1, #args do + cursors[(j*2)-1], cursors[j*2] = next(args[j],nil) + end + coroutine.yield(unpack(cursors)) + any_left = true + break + end + end + end + end) +end + +-- Override tostring to display more info about the table +local old_tostring = tostring +local numtabs = 0 +local printed_tables = {} +local function tostring_helper(el) + assert(type(el) == "table", "Tried to call helper with something that was not a table, it was a " .. type(el)) + local mt = getmetatable(el) + if mt and mt.__tostring then + return mt.__tostring(el) + elseif printed_tables[el] == true then + return old_tostring(el) + else + printed_tables[el] = true + numtabs = numtabs + 1 + local strbuilder = {"{"} + for k,v in pairs(el) do + local key,value + if type(k) == "table" then + key = tostring_helper(k) + else + key = old_tostring(k) + end + if type(v) == "table" then + value = tostring_helper(v) + else + value = old_tostring(v) + end + strbuilder[#strbuilder + 1] = string.format("%s%s : %s", string.rep("\t",numtabs), key, value) + end + strbuilder[#strbuilder + 1] = string.rep("\t",numtabs - 1) .. "}" + numtabs = numtabs - 1 + return table.concat(strbuilder,"\n") + end + +end +function tostring(el) + printed_tables = {} + if type(el) == "table" then + return tostring_helper(el) + end + return old_tostring(el) +end + +function util.reverse(tbl, val) + val = val or true + local ret = {} + for _,v in ipairs(tbl) do + ret[v] = val + end + return ret +end + +function util.typecheck(tbl, ...) + local args = {...} + assert(#args % 2 == 0,"Typecheck should have an odd number of arguments, found " .. tostring(#args + 1) .. ".") + for i = 1, #args, 2 do + assert(args[i] and type(args[i]) == "string", "Cannot check a field of type " .. type(args[i]) .. " at position " .. tostring(i + 1) .. ".") + assert(tbl[args[i]], "Failed to find a field: " .. args[i]) + assert(args[i+1] and type(args[i + 1]) == "string", "Cannot check for a type " .. type(args[i + 1]) .. " at position " .. tostring(i + 2) .. ".") + assert(type(tbl[args[i]]) == args[i+1], "Expected a " .. args[i+1] .. " at position " .. tostring(i+2) .. " but found a " .. type(tbl[args[i]])) + end + return true +end + +function util.peer_to_code(str) + -- Turn peerjs peer ids into shorter strings + -- Example: 0dbbe67a-5358-4ea2-910a-195754b556a7 + -- = 16 bytes + local buffer = am.buffer(16) + local view = buffer:view("ubyte") + local i = 0 + for byte in str:gmatch("%x%x") do + local n = tonumber(byte,16) + view[(i % 16) + 1] = n + i = i + 1 + end + local encoded = am.base64_encode(buffer) + return encoded:gsub("[/+]",{["/"] = "-",["+"] = "_"}):sub(1,22) -- chop the last 2 glyphs, assume 16 bytes +end + +function util.code_to_peer(str) + local padded = str:gsub("[_-]",{["-"] = "/", ["_"] = "+"}) .. "==" + local buffer = am.base64_decode(padded) + local view = buffer:view("ubyte") + local dashes = {4,2,2,2,6} + local builder = {} + local i = 1 + while #dashes > 0 do + local nbytes = table.remove(dashes,1) + for _ = 1, nbytes do + table.insert(builder, string.format("%02x",view[i])) + i = i + 1 + end + if #dashes > 0 then + table.insert(builder,"-") + end + end + ret = table.concat(builder) + return ret +end + +return util |
