local module = {} setmetatable(module, {__index=_G}) setfenv(1, module) --===== filters =====-- Filter = {} -- base filter creation function Filter.new(_, operation, tbl) local self = {} self.keys = {} self.filters = {} self.op = operation for _, v in ipairs(tbl) do if type(v) == "function" then table.insert(self.filters, v) elseif type(v) == "string" then table.insert(self.keys, v) end end return function(entity) return Filter.check(self, entity) end end setmetatable(Filter, {__call=Filter.new}) -- base filter checking function Filter.check(self, entity) local funcname = "check" .. self.op return Filter[funcname](self, entity) end -- AND filter (all keys and subfilters must match) function Filter.AND(tbl) return Filter("AND", tbl) end function Filter.checkAND(self, entity) for _, subfilter in ipairs(self.filters) do if not subfilter(entity) then return false end end for _, key in ipairs(self.keys) do if entity[key] == nil then return false end end return true end -- OR filter (at least one key or subfilter must match) function Filter.OR(tbl) return Filter("OR", tbl) end function Filter.checkOR(self, entity) for _, subfilter in ipairs(self.filters) do if subfilter(entity) then return true end end for _, key in ipairs(self.keys) do if entity[key] ~= nil then return true end end return false end -- NAND filter (at least one key or subfilter must NOT match) function Filter.NAND(tbl) return Filter("NAND", tbl) end function Filter.checkNAND(self, entity) for _, subfilter in ipairs(self.filters) do if not subfilter(entity) then return true end end for _, key in ipairs(self.keys) do if entity[key] == nil then return true end end return false end -- NOR filter (no keys or subfilters may match) function Filter.NOR(tbl) return Filter("NOR", tbl) end function Filter.checkNOR(self, entity) for _, subfilter in ipairs(self.filters) do if subfilter(entity) then return false end end for _, key in ipairs(self.keys) do if entity[key] ~= nil then return false end end return true end return module