diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/chunk.lua | 5 | ||||
| -rw-r--r-- | common/rle.lua | 50 | 
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}  | 
