View difference between Paste ID: zQsFDW2g and gQ0Mwtdp
SHOW: | | - or go back to the newest paste.
1
function class(def)
2
    local class = {}
3
    local parents = {}
4
    
5
    local upv
6
    local env = _G
7
    
8
    local wraps
9
    local function super(parent_class)
10
        if not parent_class then
11
            parent_class = parents[1]
12
        end
13
        
14
        local this = this
15
        local that = {}
16
        for k,v in pairs(parent_class) do
17
            that[k] = type(v) == 'function' and wraps(this, v) or v
18
        end
19
        
20
        return setmetatable(that, that)
21
    end
22
    
23
    function wraps(this, func)
24
        return function(...)
25
                local t = env.this
26
                local s = env.super
27
                
28
                env.this  = this
29
                env.super = super
30
                
31
                local ret  = pcall(func, ...)
32
33
                env.this  = t
34
                env.super = s
35
                
36
                return ret
37
            end
38
    end
39
    
40
    function class.__init()end
41
42
    for i=1,math.huge do
43
        inherit, v = debug.getlocal(def, i)
44
        if not inherit then break end
45
        
46
        local parent_class = _G[inherit]
47
        for i=1,math.huge do
48
            local  name, pclass = debug.getlocal(2,i,1)
49
            if not name then break
50
            elseif name == inherit then
51
                parent_class  = pclass
52
                break
53
            end
54
        end
55
56
        if parent_class  and type(parent_class) == 'table' then
57
            table.insert(parents, parent_class)
58
            for k,v in pairs(parent_class) do
59
                class[k] = v
60
            end
61
        else
62
            error(string.format('Class "%s" not valid.', name))
63
        end
64
    end
65
    
66
    
67
    for i=1,math.huge do
68
        local  name, value = debug.getupvalue(def, i)
69
        if not name then break
70
        elseif name == '_ENV' then
71
            env = value
72
            upv = i
73
            break
74
        end
75
    end
76
77
    local _env = setmetatable({}, {
78
        __index= function(t, name)
79
            local  value  = class[name]
80
            return value ~= nil and value or env[name]
81
        end,
82
        __newindex = function(t, name, value)
83
                class[name] = value
84
            end
85
    })
86
    
87
    local function senv(env)
88
        if upv then debug.setupvalue(def, upv, env)
89
        else _G = env end
90
    end
91
    
92
    senv(_env)
93
    env.pcall(def, env.table.unpack(parents))
94
    senv(env)
95
    
96
    return setmetatable({}, {
97
        __ipairs    = function()        return ipairs(class)              end,
98
        __pairs     = function()        return  pairs(class)              end,
99
        __index     = function(t, name) return        class[name]         end,
100
        __index_new = function(t, name, value)        class[name] = value end,
101
        __call      = function(...)
102
            local this = {}
103
            for k,v in pairs(class) do
104
                this[k] = type(v) == 'function' and wraps(this, v) or v
105
            end
106
            this.__class = class
107
            this.__init(...)
108
            
109
            return setmetatable(this, this)
110
        end
111
    })
112-
end
112+
end
113
114
return class