summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/chunk.lua5
-rw-r--r--common/rle.lua50
2 files changed, 53 insertions, 2 deletions
diff --git a/common/chunk.lua b/common/chunk.lua
index 39fcaaf..563723e 100644
--- a/common/chunk.lua
+++ b/common/chunk.lua
@@ -1,6 +1,7 @@
local json = require"common.dkjson"
local class = require"common.class"
local coords = require"common.coords"
+local rle = require"common.rle"
local CHUNK_SIZE = require"common.constants".CHUNK_SIZE
@@ -32,14 +33,14 @@ function Chunk.set_at(self,hoffs,tile)
end
function Chunk.data_packet(self)
- return json.encode{t="chunk",tiles=self.tiles,u=self.cp.u,v=self.cp.v}
+ return json.encode{t="chunk",tiles=rle.encode(self.tiles),u=self.cp.u,v=self.cp.v}
end
function Chunk.from_packet_data(cls,packet)
-- assuming packet has already been json.decoded
-- since otherwise how would we know it's a chunk packet
local cp = coords.ChunkPos:make(packet.u,packet.v)
- return cls:make(cp,packet.tiles)
+ return cls:make(cp,rle.decode(packet.tiles))
end
return {
diff --git a/common/rle.lua b/common/rle.lua
new file mode 100644
index 0000000..2944c4c
--- /dev/null
+++ b/common/rle.lua
@@ -0,0 +1,50 @@
+-- run length encoding
+
+local function encode(l)
+ local out = {}
+
+ local last = l[1]
+ local count = 1
+
+ local function ap()
+ if count == 1 then
+ table.insert(out,last)
+ elseif count == 2 then
+ table.insert(out,last)
+ table.insert(out,last)
+ else
+ table.insert(out,{count,last})
+ end
+ end
+
+ for ix=2,#l do
+ local val = l[ix]
+ if val == last then
+ count = count + 1
+ else
+ ap()
+ last = val
+ count = 1
+ end
+ end
+
+ ap()
+
+ return out
+end
+
+local function decode(l)
+ local out = {}
+ for _,r in ipairs(l) do
+ if type(r) == "table" and #r == 2 then
+ for i = 1,r[1] do
+ table.insert(out,r[2])
+ end
+ else
+ table.insert(out,r)
+ end
+ end
+ return out
+end
+
+return {encode=encode,decode=decode}