local isSimulator = playdate.isSimulator -- local function keysContain(key, allowedKeys) -- for _, allowedKey in pairs(allowedKeys) do -- if key == allowedKey then -- return true -- end -- end -- return false -- end ---@generic T ---@param shape T ---@param process fun(entity: T, dt: number, system: System) ---@return System | { entities: T[] } function filteredSystem(shape, process) local system = tiny.processingSystem() local keys = {} for key, value in pairs(shape) do if type(value) ~= "table" or value.maybe == nil then -- ^ Don't require any Maybe types keys[#keys + 1] = key end end system.filter = tiny.requireAll(table.unpack(keys)) if not process then return world:addSystem(system) end if isSimulator then -- local acceptableKeys = "" -- for _, key in ipairs(keys) do -- acceptableKeys = acceptableKeys .. "'" .. key .. "', " -- end -- acceptableKeys = acceptableKeys .. "]" function system:process(e, dt) -- local _e = e -- e = setmetatable({}, { -- __newindex = function() -- error("Do not attempt to mutate entity data!") -- end, -- __index = function(_, key) -- -- TODO: also assert their types -- assert( -- keysContain(key, keys), -- "Attempted to use key '" .. key .. "' - should be one of [ " .. acceptableKeys -- ) -- return _e[key] -- end, -- }) process(e, dt, self) end else function system:process(e, dt) process(e, dt, self) end end return world:addSystem(system) end