1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
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
|