diff options
| author | Alexander M Pickering <alex@cogarr.net> | 2024-12-09 16:44:32 -0600 |
|---|---|---|
| committer | Alexander M Pickering <alex@cogarr.net> | 2024-12-09 16:44:32 -0600 |
| commit | 541ef6aaee248626c1a1c6e0db05f5980d09c7a5 (patch) | |
| tree | 44ff154cb2f33843bb4ded69bdaa2e6461674173 | |
| download | ggj25-541ef6aaee248626c1a1c6e0db05f5980d09c7a5.tar.gz ggj25-541ef6aaee248626c1a1c6e0db05f5980d09c7a5.tar.bz2 ggj25-541ef6aaee248626c1a1c6e0db05f5980d09c7a5.zip | |
Inital commit
| -rw-r--r-- | Makefile | 51 | ||||
| -rw-r--r-- | data/.gitignore | 1 | ||||
| -rw-r--r-- | data_src/.gitignore | 0 | ||||
| -rw-r--r-- | spec/channel_spec.lua | 105 | ||||
| -rw-r--r-- | spec/ui_spec.lua | 0 | ||||
| -rw-r--r-- | src/channel.moon | 73 | ||||
| -rw-r--r-- | src/conf.lua | 1 | ||||
| -rw-r--r-- | src/main.lua | 0 | ||||
| -rw-r--r-- | tools/luastr.sh | 5 | ||||
| -rw-r--r-- | tools/rewrite.lua | 31 |
10 files changed, 267 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..9c4bcf4 --- /dev/null +++ b/Makefile @@ -0,0 +1,51 @@ + +LUA?="$(shell where lua | head -n 1)" +CP?=cp +AMULET?="$(shell where amulet | head -n 1)" +RM?=rm +UNZIP?=7z x -y +CD?=cd +MOONC?="$(shell where moonc | head -n 1)" +BUSTED?="$(shell where busted | head -n 1)" + +src_moon=$(wildcard src/*.moon) +built_moon=$(src_moon:src/%.moon=data/%.lua) +dbg_moon=$(src_moon:src/%.moon=data/%.lua.X) + +src_tl=$(wildcard src/*.tl) +built_tl=$(src_tl:src/%.tl=data/%.lua) + +src_lua=$(wildcard src/*.lua) +built_lua=$(src_lua:src/%.lua=data/%.lua) + +src_js=$(wildcard src/*.js) +built_js=$(src_js:src/%.js=data/%.lua) + +built=$(built_moon) $(built_tl) $(built_lua) $(built_js) +built_dbg=$(built) $(dbg_moon) + +all: $(built_dbg) + $(AMULET) export -html -a data + $(UNZIP) *.zip + $(CD) ggj25 && python3 -m http.server + +clean: + $(RM) $(built) + +test: $(built_dbg) + $(BUSTED) -m "./data/?.lua" -o utfTerminal -v spec | $(LUA) tools/rewrite.lua + +$(built_lua) : data/%.lua : src/%.lua + $(CP) $< $@ + +$(built_moon) : data/%.lua : src/%.moon + $(MOONC) -p $< > $@ + +$(dbg_moon) : data/%.lua.X : src/%.moon + $(MOONC) -X $< > $@ + +$(test_lua) : spec/%.lua : src/%.lua + $(CP) $< $@ + +$(test_moon) : spec/%.lua : src/%.moon + $(MOONC) -p $< > $@ diff --git a/data/.gitignore b/data/.gitignore new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/data/.gitignore @@ -0,0 +1 @@ +* diff --git a/data_src/.gitignore b/data_src/.gitignore new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/data_src/.gitignore diff --git a/spec/channel_spec.lua b/spec/channel_spec.lua new file mode 100644 index 0000000..252c12e --- /dev/null +++ b/spec/channel_spec.lua @@ -0,0 +1,105 @@ + +describe("channel module", function() + it("should load",function() + require("channel") + end) + describe("SimpleChannel",function() + local channel = require("channel") + it("should exist",function() + assert(channel.SimpleChannel) + assert(channel.SimpleChannel()) + end) + it("should send messages",function() + local sc = channel.SimpleChannel() + assert(not sc:poll()) + sc:send("Hello") + assert(sc:poll()) + assert(sc:recv() == "Hello") + end) + it("should send any string",function() + local sc = channel.SimpleChannel() + local rng = tostring(math.random()) + sc:send(rng) + assert(sc:recv() == rng) + end) + end) + describe("FaultyChannel",function() + local channel = require("channel") + it("should exist",function() + assert(channel.FaultyChannel) + assert(channel.FaultyChannel()) + end) + it("can has a .time that allows it to time travel",function() + channel.FaultyChannel.time = 0 + local fc = channel.FaultyChannel({ + loss_std = 0, + avg_latency = 5 + }) + fc:send("a") + assert(#fc.to_deliver == 1) + assert(#fc.buffer == 0) + channel.FaultyChannel.time = 10 + fc:pump() + assert(#fc.to_deliver == 0) + assert(#fc.buffer == 1) + assert(fc:recv() == "a") + end) + it("can pump() with no side effects if time has not changed", function() + channel.FaultyChannel.time = 0 + local fc = channel.FaultyChannel({ + loss_std = 0, + avg_latency = 5 + }) + fc:send("a") + assert(#fc.to_deliver == 1) + assert(#fc.buffer == 0) + fc:pump() + assert(#fc.to_deliver == 1) + assert(#fc.buffer == 0) + + end) + --[[ + it("can be configured to not drop messages", function() + channel.FaultyChannel.time = 0 + local fc = channel.FaultyChannel({ + avg_latency = 5, + loss_std = 0 + }) + local i = 100 + for _ = 1,i do + fc:send("a") + end + print(#fc.to_deliver) + print(#fc.buffer) + fc:pump() + print(#fc.to_deliver) + print(#fc.buffer) + channel.FaultyChannel.time = 10 + fc:pump() + print(#fc.to_deliver) + print(#fc.buffer) + local j = 0 + while fc:poll() do + j = j + 1 + fc:recv() + end + assert(j == i) + end) + it("should drop messages sometimes",function() + local fc = channel.FaultyChannel() + local i = 100 + for _ = 1, i do + fc:send("a") + end + -- Time forward + --channel.FaultyChannel.time = math.huge + local j = 0 + while fc:poll() do + j = j + 1 + fc:recv() + end + assert(j < i) + end) + ]] + end) +end) diff --git a/spec/ui_spec.lua b/spec/ui_spec.lua new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/spec/ui_spec.lua diff --git a/src/channel.moon b/src/channel.moon new file mode 100644 index 0000000..968ae09 --- /dev/null +++ b/src/channel.moon @@ -0,0 +1,73 @@ + +-- Implements a channels, an abstraction for sending data + +class Channel + new: (settings) => + settings = settings or {} + --Every channel has at least a buffer, the messages to be read on recv() + @buffer = {} + for setting_name, setting_value in pairs settings + @[setting_name] = setting_value + poll: => + error("Channel must implement poll") + send: (message) => + error("Channel must implement message") + recv: => + error("Channel must implement recv") + +class SimpleChannel extends Channel + @time = 0 + new: (settings) => + super(settings) + poll: => + #@buffer > 0 + send: (message) => + table.insert(@buffer, message) + recv: => + table.remove(@buffer, 1) + +class FaultyChannel extends Channel + -- Mock channel for testing + @time = 0 + new: (settings) => + @to_deliver = {} + @avg_latency = 0 -- in ms + @latency_std = 0 + -- Latency can never be below 0, but can go up as much as it likes + @avg_loss = 0 -- between 0 (never) and 1 (always) + @loss_std = 0.1 + -- Loss is always a percentage between 0 and 1 + super(settings) + normal: (avg, std, n) => + assert(avg and std and n, string.format("normal(avg, std, n) called with %q %q %q", tostring(avg), tostring(std), tostring(n))) + -- Normal curve probability at N + (1/ (math.sqrt(2*math.pi) * avg)) * math.exp(-(n - avg)^2 / (2 * (std^2))) + poll: => + @pump! + #@buffer > 0 + send: (message) => + -- Do we deliver? + if @normal(@avg_loss, @loss_std, math.random()) < 0.5 + return + -- How long does it take? + time = @normal(@avg_latency, @latency_std, math.random()) + if time < 0 then + time = 0 -- We can't deliver messages in the past + table.insert(@to_deliver, {message,time}) + recv: => + @pump! + table.remove(@buffer, 1) + pump: => + defrag = 1 + deliver_len = #@to_deliver + for k,tbl in ipairs(@to_deliver) + {m, t} = tbl + if @@time > t + @to_deliver[k] = nil + table.insert(@buffer, m) + if @to_deliver[defrag] == nil + @to_deliver[defrag] = tbl + for i = defrag, deliver_len do + @to_deliver[i] = nil + +{:Channel, :SimpleChannel, :FaultyChannel} diff --git a/src/conf.lua b/src/conf.lua new file mode 100644 index 0000000..662a017 --- /dev/null +++ b/src/conf.lua @@ -0,0 +1 @@ +shortname="ggj25" diff --git a/src/main.lua b/src/main.lua new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/main.lua diff --git a/tools/luastr.sh b/tools/luastr.sh new file mode 100644 index 0000000..5b50c7d --- /dev/null +++ b/tools/luastr.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +echo "return [=====[" +echo "$(cat $1)" +echo "]=====]" diff --git a/tools/rewrite.lua b/tools/rewrite.lua new file mode 100644 index 0000000..503a0c8 --- /dev/null +++ b/tools/rewrite.lua @@ -0,0 +1,31 @@ +--[[Script to rewrite a stack traceback in terms of moonscript instead of lua]] + +for data in io.lines() do + local filename, linenum, rest = data:gmatch("%s+(.*%.lua):(%d+):(.*)")() + if filename and linenum and rest then + local moonfilename = filename:gsub(".lua$",".moon") + + --If our file is not moonscript, we won't have a debug file + local debugfile, err = io.open(filename .. ".X", "r") + if not debugfile then + --print("not debugfile" .. filename .. ":" .. err) + print(data) + goto next + end + + --Skip first line + debugfile:read("*l") + for line in debugfile:lines() do + _,_,pos,lua,moon = line:find("(%d+)%s+(%d+):%b[] >> (%d+)") + if tonumber(linenum) == tonumber(lua) then + print(string.format("\t%s:%d: %s",moonfilename,moon,rest)) + goto next + end + end + debugfile:close() + else + print(data) + end + ::next:: +end + |
