- Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathclass.lua
More file actions
Latest commit
80 lines (67 loc) · 2.57 KB
/
Copy pathclass.lua
File metadata and controls
80 lines (67 loc) · 2.57 KB
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
localtable=require'ext.table'
-- classes
localfunctionnewmember(class, ...)
localobj=setmetatable({}, class)
ifobj.initthenreturnobj, obj:init(...) end
returnobj
end
localclassmeta= {
__call=function(self, ...)
-- [[ normally:
returnself:new(...)
--]]
--[[ if you want to keep track of all instances
local results = table.pack(self:new(...))
local obj = results[1]
self.instances[obj] = true
return results:unpack()
--]]
end,
}
-- usage: class:isa(obj)
-- so it's not really a member method, since the object doesn't come first, but this way we can use it as Class:isa(obj) and not worry about nils or local closures
localfunctionisa(cl, obj)
assert(cl, "isa: argument 1 is nil, should be the class object") -- isa(nil, anything) errors, because it should always have a class in the 1st arg
iftype(obj) ~='table' thenreturnfalseend-- class:isa(not a table) will return false
-- Check the metatable for an .isaSet first
-- This allows the object the ability to lose the 'isa' and 'isaSet' fields.
-- It also allows isa(class, subclass) to work.
localmt=getmetatable(obj)
localisaSet=mtandmt.isaSetorobj.isaSet
ifnotisaSetthenreturnfalseend-- not an object generated by class(), so it doesn't have a set of all classes that it "is-a"
returnisaSet[cl] orfalse-- returns true if the 'isaSet' of the object's metatable (its class) holds the calling class
end
localfunctionclass(...)
localcl=table(...)
-- TODO maybe, get rid of this and just use getmetatable()
cl.class=cl
cl.super=...-- .super only stores the first. the rest can be accessed by iterating .isaSet's keys
-- I was thinking of calling this '.superSet', but it is used for 'isa' which is true for its own class, so this is 'isaSet'
cl.isaSet= {[cl] =true}
fori=1,select('#', ...) do
localparent=select(i, ...)
ifparent~=nilthen
cl.isaSet[parent] =true
ifparent.isaSetthen
forgrandparent,_inpairs(parent.isaSet) do
cl.isaSet[grandparent] =true
end
end
end
end
-- store 'descendantSet' as well that gets appended when we call class() on this obj?
forancestor,_inpairs(cl.isaSet) do
ancestor.descendantSet=ancestor.descendantSetor {}
ancestor.descendantSet[cl] =true
end
cl.__index=cl
cl.new=newmember
cl.isa=isa-- usage: Class:isa(obj)
cl.subclass=class-- such that cl:subclass() or cl:subclass{...} will return a subclass of 'cl'
--[[ if you want to keep track of all instances
cl.instances = setmetatable({}, {__mode = 'k'})
--]]
setmetatable(cl, classmeta)
returncl
end
returnclass