|
1 | 1 | --[[ |
2 | 2 | Author: https://github.com/lodsdev |
3 | | - Version: 1.0 |
4 | | - |
5 | | - MIT License |
6 | | -
|
7 | | - Copyright (c) 2012-2022 Scott Chacon and others |
8 | | -
|
9 | | - Permission is hereby granted, free of charge, to any person obtaining |
10 | | - a copy of this software and associated documentation files (the |
11 | | - "Software"), to deal in the Software without restriction, including |
12 | | - without limitation the rights to use, copy, modify, merge, publish, |
13 | | - distribute, sublicense, and/or sell copies of the Software, and to |
14 | | - permit persons to whom the Software is furnished to do so, subject to |
15 | | - the following conditions: |
16 | | -
|
17 | | - The above copyright notice and this permission notice shall be |
18 | | - included in all copies or substantial portions of the Software. |
19 | | -
|
20 | | - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
21 | | - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
22 | | - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
23 | | - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |
24 | | - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |
25 | | - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
26 | | - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| 3 | + Version: 2.0.0 |
27 | 4 | ]] |
28 | 5 |
|
29 | | - |
30 | 6 | local classes = {} |
31 | 7 | local interfaces = {} |
32 | 8 |
|
33 | | -local function tblCopy(t, mt) |
34 | | - local t2 = {} |
| 9 | +local function table_copy(t) |
| 10 | + local newTbl = {} |
35 | 11 | for i, v in pairs(t) do |
36 | | - if (not t2[i]) then |
37 | | - t2[i] = v |
| 12 | + if (not newTbl[i]) then |
| 13 | + newTbl[i] = v |
38 | 14 | end |
39 | 15 | end |
40 | | - if (mt) then |
41 | | - t2.super = mt |
42 | | - setmetatable(t2, { __index = t2.super.array }) |
| 16 | + return newTbl |
| 17 | +end |
| 18 | + |
| 19 | +local function table_implements(t, t2) |
| 20 | + local newTbl = {} |
| 21 | + for k, v in ipairs(t2) do |
| 22 | + t[#t+1] = v |
43 | 23 | end |
44 | | - return t2 |
| 24 | + newTbl = table_copy(t) |
| 25 | + return newTbl |
45 | 26 | end |
46 | 27 |
|
47 | | -function class(className) |
48 | | - return function(tbl, super) |
49 | | - local class = classes[className] |
50 | | - if (not class) then |
51 | | - if (super) then |
52 | | - super._name = super.name |
53 | | - end |
54 | | - tbl._name = className |
55 | | - classes[className] = { name = className, array = tbl, super = super } |
56 | | - end |
57 | | - return tbl |
| 28 | +local function createClass(className, structure, superClass) |
| 29 | + if (classes[className]) then |
| 30 | + error('Class ' .. className .. ' already exists.', 2) |
58 | 31 | end |
| 32 | + |
| 33 | + local newClass = structure |
| 34 | + newClass.__name = className |
| 35 | + |
| 36 | + if (superClass) then |
| 37 | + newClass.super = superClass |
| 38 | + setmetatable(newClass, { __index = newClass.super }) |
| 39 | + end |
| 40 | + |
| 41 | + classes[className] = newClass |
| 42 | + return newClass |
59 | 43 | end |
60 | 44 |
|
61 | | -function new(className) |
62 | | - return function(...) |
63 | | - local classe = classes[className] |
64 | | - if (not classe) then error('Class ' .. className .. ' not found') end |
| 45 | +function interface(interfaceName) |
| 46 | + local newInterface = {} |
65 | 47 |
|
66 | | - local super = (classe.super and classe.super or false) |
67 | | - local obj = tblCopy(classe.array, (super and super or false)) |
| 48 | + setmetatable(newInterface, { |
| 49 | + __call = function(self, ...) |
| 50 | + if (interfaces[interfaceName]) then |
| 51 | + error('Interface ' .. interfaceName .. ' already exists.', 2) |
| 52 | + end |
68 | 53 |
|
69 | | - obj.overload = function(tbl, ...) |
70 | | - local args = {...} |
71 | | - local func = tbl[#args] |
72 | | - func(obj, ...) |
| 54 | + local newInstance = ... |
| 55 | + interfaces[interfaceName] = newInstance |
| 56 | + return newInstance |
73 | 57 | end |
| 58 | + }) |
74 | 59 |
|
75 | | - if (obj.constructor) then |
76 | | - obj:constructor(...) |
| 60 | + newInterface.extends = function(self, superInterfaceName) |
| 61 | + return function(subInterface) |
| 62 | + local superInterface = interfaces[superInterfaceName] |
| 63 | + local newInstance = table_implements(subInterface, superInterface) |
| 64 | + |
| 65 | + if (interfaces[interfaceName]) then |
| 66 | + error('Interface ' .. interfaceName .. ' already exists.', 2) |
| 67 | + end |
| 68 | + |
| 69 | + interfaces[interfaceName] = newInstance |
| 70 | + return newInstance |
77 | 71 | end |
78 | | - return obj |
79 | 72 | end |
| 73 | + |
| 74 | + return newInterface |
80 | 75 | end |
81 | 76 |
|
82 | | -function extends(superObjName) |
83 | | - return function(tbl) |
84 | | - local super |
85 | | - |
86 | | - if (classes[superObjName]) then |
87 | | - super = classes[superObjName] |
88 | | - setmetatable(tbl, {__index = super.array}) |
89 | | - elseif (interfaces[superObjName]) then |
90 | | - super = interfaces[superObjName] |
91 | | - for i, v in pairs(super) do |
92 | | - tbl[i] = v |
| 77 | +function class(className) |
| 78 | + local newClasse = {} |
| 79 | + local modifiers = { |
| 80 | + extends = function(self, superClassName) |
| 81 | + return function(subClass) |
| 82 | + local superClass = classes[superClassName] |
| 83 | + local classCreated = createClass(className, subClass, superClass) |
| 84 | + return classCreated |
| 85 | + end |
| 86 | + end, |
| 87 | + |
| 88 | + implements = function(self, ...) |
| 89 | + local interfacesNames = {...} |
| 90 | + return function(subClass) |
| 91 | + local classeCreated = createClass(className, subClass) |
| 92 | + |
| 93 | + for _, v in pairs(interfacesNames) do |
| 94 | + if (not interfaces[v]) then |
| 95 | + error('Interface ' .. v .. ' not found', 2) |
| 96 | + end |
| 97 | + |
| 98 | + for _, method in pairs(interfaces[v]) do |
| 99 | + if (not subClass[method]) then |
| 100 | + error('Interface ' .. v .. ' not implemented, method ' .. method .. ' not found', 2) |
| 101 | + end |
| 102 | + end |
| 103 | + end |
| 104 | + |
| 105 | + return classeCreated |
93 | 106 | end |
94 | 107 | end |
| 108 | + } |
95 | 109 |
|
96 | | - return tbl, super |
97 | | - end |
98 | | -end |
| 110 | + setmetatable(newClasse, { |
| 111 | + __index = function (self, key) |
| 112 | + if (modifiers[key]) then |
| 113 | + return modifiers[key] |
| 114 | + end |
99 | 115 |
|
100 | | -function interface(interfaceName) |
101 | | - return function(tbl) |
102 | | - if (not interfaces[interfaceName]) then |
103 | | - interfaces[interfaceName] = {} |
104 | | - end |
| 116 | + if (classes[className]) then |
| 117 | + return classes[className][key] |
| 118 | + end |
| 119 | + |
| 120 | + error('Class ' .. className .. ' not found', 2) |
| 121 | + end, |
| 122 | + |
| 123 | + __call = function(self, ...) |
| 124 | + if (classes[className]) then |
| 125 | + error('Class ' .. className .. ' already exists.', 2) |
| 126 | + end |
105 | 127 |
|
106 | | - for i, v in pairs(tbl) do |
107 | | - interfaces[interfaceName][v] = v |
| 128 | + local newInstance = createClass(className, ...) |
| 129 | + return newInstance |
108 | 130 | end |
| 131 | + }) |
109 | 132 |
|
110 | | - return tbl |
111 | | - end |
| 133 | + return newClasse |
112 | 134 | end |
113 | 135 |
|
114 | | -function implements(interfaceName) |
115 | | - return function(tbl) |
116 | | - if (not interfaces[interfaceName]) then error('Interface ' .. interfaceName .. ' not found') end |
| 136 | +function new(className) |
| 137 | + return function(...) |
| 138 | + local classe = classes[className] |
| 139 | + if (not classe) then |
| 140 | + error('Class ' .. className .. ' not found', 2) |
| 141 | + end |
117 | 142 |
|
118 | | - for i, v in pairs(interfaces[interfaceName]) do |
119 | | - if (not tbl[v]) then |
120 | | - error('Interface ' .. interfaceName .. ' not implemented, method ' .. v .. ' not found') |
121 | | - end |
| 143 | + if (classe.constructor) then |
| 144 | + classe:constructor(...) |
122 | 145 | end |
123 | 146 |
|
124 | | - return tbl |
| 147 | + return classe |
125 | 148 | end |
126 | 149 | end |
127 | 150 |
|
128 | 151 | function instanceOf(instance, className) |
129 | 152 | local classe = classes[className] |
130 | | - if (not classe) then error('Class ' .. className .. ' not found', 2) end |
131 | | - |
132 | | - if (instance._name == className) then |
133 | | - return true |
| 153 | + if (not classe) then |
| 154 | + error('Class ' .. className .. ' not found', 2) |
134 | 155 | end |
135 | 156 |
|
136 | | - if (instance.super) then |
137 | | - return instanceOf(instance.super, className) |
| 157 | + if (instance.__name == className) then |
| 158 | + return true |
138 | 159 | end |
139 | 160 |
|
140 | 161 | return false |
|
0 commit comments