Skip to content

Instantly share code, notes, and snippets.

@Python1320
Created August 20, 2014 17:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Python1320/5c38468949e1f3322216 to your computer and use it in GitHub Desktop.
Save Python1320/5c38468949e1f3322216 to your computer and use it in GitHub Desktop.
testing luadata prettier printing, although more expensive :(
local luadata = {}
local encode_table
local typex=type
function table.isarray(t)
local i = 0
for _ in pairs(t) do
i = i + 1
if t[i] == nil then return false end
end
return true
end
luadata.Types =
{
number = function(var)
return ("%s"):format(var)
end,
string = function(var)
return ("%q"):format(var)
end,
boolean = function(var)
return var and "true" or "false"
end,
Vector = function(var)
return ("Vector(%s, %s, %s)"):format(var.x, var.y, var.z)
end,
Angle = function(var)
return ("Angle(%s, %s, %s)"):format(var.p, var.y, var.r)
end,
table = function(tbl, context)
local str
context.tab = context.tab + 1
if context.tab == 0 then
str = {}
else
str = {"{\n"}
end
local maxnum = 0
for i = 1, 99999999 do
local v = tbl[i]
if v==nil then
maxnum = i-1
break
end
str[#str+1] = ("%s%s,\n"):format(("\t"):rep(context.tab), luadata.ToString(tbl[i], context))
if context.yield then
coroutine.yield()
end
end
for key, value in pairs(tbl) do
local skip = isnumber(key) and key<=maxnum and key>=1
if not skip then
value = luadata.ToString(value, context)
if value then
local k,quoted = luadata.CanBareKeyName(key)
print("q",k,quoted)
if k then
k = key
elseif quoted then
k = ("[%s]"):format(quoted)
else
k = luadata.ToString(key, context)
if not k then print("UH",k) end
k = k and ("[%s]"):format(k)
end
if k then
str[#str+1] = ("%s%s = %s,\n"):format(("\t"):rep(context.tab), k, value)
--else -- error?
end
end
if context.yield then
coroutine.yield()
end
end
end
if context.tab == 0 then
str[#str+1] = "\n"
else
str[#str+1] = ("%s}"):format(("\t"):rep(context.tab))
end
context.tab = context.tab - 1
return table.concat(str, "")
end,
cdata = function(var)
return tostring(var)
end,
}
function luadata.SetModifier(type, callback)
luadata.Types[type] = callback
end
function luadata.Type(var)
local t = typex(var)
if t == "table" then
if var.LuaDataType then
t = var.LuaDataType
end
end
return t
end
local CheckCyclic CheckCyclic =
function(tbl,tables)
for k,v in next,tbl do
if istable(k) then
if tables[k] then
return true
end
tables[k] = true
if CheckCyclic(tbl,tables) then return true end
end
if istable(v) then
if tables[k] then
return true
end
tables[k] = true
if CheckCyclic(tbl,tables) then return true end
end
end
end
-- todo test
function luadata.CheckCyclic(tbl)
return CheckCyclic(tbl,{tbl})
end
function luadata.CanBareKeyName(key)
if not isstring(key) or key:find("%s") or key=="" then
return false
end
local q = ("%q"):format(key)
local result = CompileString(("local %s = true"):format(key),"",false)
return isfunction(result),q
end
print(luadata.CheckCyclic{{},[{}]={}})
function luadata.ToString(var, context)
context = context or {}
context.tab = context.tab or -1
context.out = context.out or {}
local func = luadata.Types[luadata.Type(var)]
return func and func(var, context)
end
function luadata.FromString(str)
local func = assert(loadstring("return " .. str))
return func()
end
function luadata.Encode(tbl, callback, speed)
if callback then
local co = coroutine.create(function()
return luadata.ToString(tbl, {yield = true})
end)
event.CreateThinker(function()
local ok, data = coroutine.resume(co)
if ok then
if data then
xpcall(callback, system.OnError, data)
return true
end
else
xpcall(callback, system.OnError, false, data)
return true
end
end, speed)
else
return luadata.ToString(tbl)
end
end
function luadata.Decode(str)
if not str then return {} end
local func, err = loadstring("return {\n" .. str .. "\n}")
if not func then
logn("luadata syntax error:")
logn(err)
return {}
end
local ok, err = xpcall(func, system.OnError)
if not ok then
logn("luadata runtime error:")
logn(err)
return {}
end
return err
end
--print(luadata.Encode(_G.luadata.Decode(luadata.Encode{{a=Vector(1,2,3)},{[""]="eek",a=Vector(1,2,3)},{"a","b","c"}} )))
_G.lau=luadata
function bork(key)
local t={[key]=true}
local s = luadata.Encode(t)
local ret,err = _G.luadata.Decode(s)
if not ret then error(tostring(err)) end
print(s)
end
--bork"end"
print((luadata.Encode{{1,2,3,4,[3]=nil,q=true,["end"]=false}}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment