216 lines
5.2 KiB
Lua
216 lines
5.2 KiB
Lua
local util = { ext = {} }
|
|
|
|
util.loaddir = function( path, api, target)
|
|
local dir = api.filesystem.getDirectoryItems(path)
|
|
foreach( dir, function(k,v)
|
|
local ext = path .. '/' .. v .. "/main.lua"
|
|
if api.filesystem.isFile(ext) then
|
|
print("[i] loading '" .. v .. "'")
|
|
target[ v ] = api.filesystem.load( ext )(api)
|
|
end
|
|
end)
|
|
end
|
|
|
|
util.exec = function(obj, fn,a,b,c,d,e,f)
|
|
foreach( obj,
|
|
when('enabled',true, util.call(fn,a,b,c,d,e,f) )
|
|
)
|
|
end
|
|
|
|
function util.merge(t1,t2)
|
|
local t3 = {}
|
|
foreach( t1, function(k,v) t3[k] = v end)
|
|
foreach( t2, function(k,v) t3[k] = v end)
|
|
return t3
|
|
end
|
|
|
|
function util.dump(value, indent, seen)
|
|
indent = indent or ""
|
|
seen = seen or {}
|
|
local t = type(value)
|
|
if t == "string" then
|
|
return string.format("%q", value)
|
|
elseif t == "boolean" or t == "number" or t == "nil" then
|
|
return tostring(value)
|
|
elseif t == "function" or t == "userdata" or t == "thread" then
|
|
return string.format("<%s: %s>", t, tostring(value))
|
|
elseif t == "table" then
|
|
if seen[value] then
|
|
return string.format("<Circular Reference: %s>", tostring(value))
|
|
end
|
|
seen[value] = true
|
|
|
|
local result = "{\n"
|
|
local next_indent = indent .. " "
|
|
local seen_keys = {}
|
|
for i, v in ipairs(value) do
|
|
seen_keys[i] = true
|
|
result = result .. next_indent .. util.dump(v, next_indent, seen) .. ",\n"
|
|
end
|
|
|
|
for k, v in pairs(value) do
|
|
if not seen_keys[k] then
|
|
local key_str
|
|
if type(k) == "string" and k:match("^[%a_][%w_]*$") then
|
|
key_str = k
|
|
else
|
|
key_str = "[" .. util.dump(k, next_indent, seen) .. "]"
|
|
end
|
|
|
|
result = result .. next_indent .. key_str .. " = " .. util.dump(v, next_indent, seen) .. ",\n"
|
|
end
|
|
end
|
|
|
|
if result:sub(-2) == ",\n" then
|
|
result = result:sub(1, -3) .. "\n"
|
|
end
|
|
|
|
return result .. indent .. "}"
|
|
end
|
|
end
|
|
|
|
-- error on undefined variable access
|
|
local function err(t,k,v) error("Accessed an undefined variable: " .. tostring(k)) end
|
|
setmetatable(_G, { __index = err })
|
|
|
|
function util.count(self)
|
|
local i = 0
|
|
if self == nil then return i end
|
|
if type(self) == 'table' then
|
|
for _, _ in pairs(self) do
|
|
i = i + 1
|
|
end
|
|
return i
|
|
else
|
|
return #self
|
|
end
|
|
end
|
|
|
|
function util.traverse(arr, cb, key, parent)
|
|
if key == nil then key = 'children' end
|
|
foreach( arr, function(k,child)
|
|
if type(child) == 'table' then
|
|
cb(child,parent)
|
|
if type(child[key]) == 'table' then
|
|
if child[key][1] then
|
|
util.traverse( child[key], cb, key, child )
|
|
end
|
|
end
|
|
end
|
|
end)
|
|
end
|
|
|
|
function util.traverseXML( parsedXml, cb)
|
|
util.traverse( parsedXml,
|
|
function(node, parent)
|
|
local struct = { tag = '?', prop = {} }
|
|
if node['name'] ~= nil then struct['tag'] = node:name():lower() end
|
|
foreach( node['___props'], function(k,v) -- move to props array
|
|
local val = node[ '@' .. v['name'] ]
|
|
if type(val) == "table" then
|
|
foreach( val, function(k,v) val = v end) -- pick last
|
|
end
|
|
struct['prop'][ v['name'] ] = val
|
|
end)
|
|
if parent ~= nil then
|
|
struct['parent'] = (function(parent)
|
|
return function() return parent end
|
|
end)(parent)
|
|
end
|
|
cb(struct,node)
|
|
end,
|
|
'___children'
|
|
)
|
|
end
|
|
|
|
util.call = function(fn,a,b,c,d,e,f)
|
|
return function(k,v)
|
|
if v ~= nil and v[fn] then
|
|
v[fn](a,b,c,d,e,f)
|
|
end
|
|
end
|
|
end
|
|
|
|
function foreach(table, f)
|
|
if table ~= nil then
|
|
for k, v in pairs(table) do f(k, v) end
|
|
end
|
|
end
|
|
|
|
function when(k,v,cb)
|
|
return function(kk,vv)
|
|
if type(vv) == 'table' then
|
|
if vv[k] == v then cb(kk,vv) end
|
|
end
|
|
end
|
|
end
|
|
|
|
function trace(o)
|
|
if os.getenv('DEBUG') then
|
|
if type(o) == 'table' then
|
|
print_r(o)
|
|
else
|
|
print(o)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function util.merge(t1,t2)
|
|
local t3 = {}
|
|
foreach( t1, function(k,v) t3[k] = v end)
|
|
foreach( t2, function(k,v) t3[k] = v end)
|
|
return t3
|
|
end
|
|
|
|
function print_r(t)
|
|
print( util.dump(t) )
|
|
end
|
|
|
|
util.match = function(list,k,v)
|
|
local ret = false
|
|
foreach( list, function(K,V)
|
|
if k == V then ret = true end
|
|
end)
|
|
return ret
|
|
end
|
|
|
|
-- recalculate filters for tiny-ecs systems
|
|
-- usage: entity.commit = util.commit(api.world) -- once
|
|
-- entity.commit() -- this recalculates the filtercache of systems
|
|
util.commit = function(world, obj, api)
|
|
return function(extCb)
|
|
for j = 1, #world.entities do
|
|
local system = world.systems[j]
|
|
system.entities = {}
|
|
for j = 1, #world.entities do
|
|
local entity = world.entities[j]
|
|
if system.filter(system, entity) then
|
|
table.insert( system.entities, entity)
|
|
end
|
|
end
|
|
end
|
|
api.ext.exec(extCb, obj)
|
|
end
|
|
end
|
|
|
|
util.addHooks = function(fn, cb )
|
|
return function(...)
|
|
fn = (fn:gsub("^%l", string.upper)) -- uppercase first char
|
|
trace("api.ext.exec('before" .. fn .. "')")
|
|
api.ext.exec( "before" .. fn, ... )
|
|
local result = cb(...)
|
|
trace("api.ext.exec('after" .. fn .. "')")
|
|
api.ext.exec( "after" .. fn, ... )
|
|
return result
|
|
end
|
|
end
|
|
|
|
util.addModuleHooks = function(mod)
|
|
foreach( mod, function(k,v)
|
|
mod[k] = util.addHooks(k, v )
|
|
end)
|
|
return mod
|
|
end
|
|
|
|
return util
|