-
-
Save Deco/1722329 to your computer and use it in GitHub Desktop.
Luvit module example (using local _M table) (my personal choice)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local OO = require"oo" | |
local _M = {} | |
do _M.Shape = OO.class({ | |
}) | |
function _M.Shape:__init() | |
error("attempt to instantiate abstract shape") | |
end | |
end | |
do _M.Rectangle = OO.class(_M.Shape, { | |
x = 0, y = 0, | |
w = 0, h = 0, | |
}) | |
function _M.Rectangle:__init(x, y, w, h) | |
return setmetatable({ | |
x = tonumber(x), y = tonumber(y), | |
w = tonumber(w), h = tonumber(h), | |
}, self) | |
end | |
function _M.Rectangle:getArea() | |
return math.sqrt(self.w^2+self.h^2) | |
end | |
end | |
do _M.Circle = OO.class(_M.Shape, { | |
--userdata = newproxy(), | |
radius = 0, | |
}) | |
function _M.Circle:__init(obj) | |
assert(type(obj.userdata) == "userdata", "attempt to construct Circle with invalid userdata") | |
-- the only reason setmetatable is preformed manually is that in the game engine I use it in I | |
-- use classes on userdata (created with newproxy). For these, debug.setmetatable must be called. | |
-- Hence, I never forced setmetatable to be used on the object internally. | |
return setmetatable(obj, self) | |
end | |
function _M.Circle:getArea(obj) | |
return math.pi*self.radius^2 | |
end | |
end | |
function _M.spawnCircle(radius) -- let's assume Circles are like processes | |
return _M.Circle{ | |
userdata = newproxy(), -- UV.get_circle | |
radius = radius | |
} | |
end | |
return _M |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require"oo" | |
require"geometry" | |
local rect = geometry.Rectangle(0, 0, 3, 4) | |
print(rect:getArea(), OO.instanceof(rect, geometry.Shape)) -- 5 true | |
local circ = geometry.spawnCircle(2) | |
print(circ:getArea()) -- 12.566370614359 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
local setmetatable = setmetatable | |
local table, debug = table, debug | |
local _M = {} | |
do --class | |
local function class_new(self, ...) | |
return setmetatable(self.__init and self:__init(...) or {}, self) | |
end | |
_M.class = function(...) | |
local supers = {...} | |
local class = table.remove(supers, #supers) | |
class.__index = ( | |
class.__index ~= nil and class.__index | |
or class.__index_def and class.__index_def(class) | |
or class | |
) | |
class[class] = true | |
local supers_len = #supers -- hopefully this will help LuaJIT unroll the loop statically | |
return setmetatable( | |
class, | |
{ | |
__supers = supers, | |
__class = class, | |
__call = class.__init or class_new, | |
__index = ( | |
supers_len == 0 and nil | |
or supers_len == 1 and supers[1] | |
or function(self, key) | |
for super_i = 1, supers_len do | |
local value = supers[super_i][key] | |
if value then return value end | |
end | |
end | |
), | |
} | |
) | |
end | |
end | |
do _M.classof | |
= debug.getmetatable -- hopefully this aliasing doesn't mess up the fast function optimisation | |
end | |
do _M.instanceof | |
= function(instance, class) | |
return debug.getmetatable(instance)[class] | |
end | |
end | |
do _M.supersof | |
= function(class) | |
return debug.getmetatable(class).__supers | |
end | |
end | |
do _M.supersofinstance -- == supersof(classof(instance)) | |
= function(instance) | |
return debug.getmetatable(debug.getmetatable(instance)).__supers | |
end | |
end | |
return _M |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment