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 when(k,v,cb) return function(kk,vv) if vv[k] == v then cb(kk,vv) 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 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("", 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 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) if key == nil then key = 'children' end foreach( arr, function(k,child) if type(child) == 'table' then cb(child) if type(child[key]) == 'table' then if child[key][1] then util.traverse( child[key], cb, key ) end end end end) end function util.traverseXML( parsedXml, cb) util.traverse( parsedXml, function(node) local struct = { tag = '?', prop = {} } if node['name'] ~= nil then struct['tag'] = node:name() end foreach( node['___props'], function(k,v) 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) cb(struct,raw) 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 vv[k] == v then cb(kk,vv) 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) return function() 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 end end return util