-
Notifications
You must be signed in to change notification settings - Fork 62
/
Copy pathclass.lua
60 lines (52 loc) · 1.64 KB
/
class.lua
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
---
-- Object oriented class creation and instance testing.
--
-- @module radio.class
local ffi = require('ffi')
---
-- Create a new class, optionally inheriting from an existing one.
--
-- This factory attaches a __call metamethod to the class, which wraps the
-- .new() static method, so the class can be instantiated by calling its name.
--
-- @internal
-- @function factory
-- @tparam[opt=nil] class Class to inherit
-- @treturn class Class
local function factory(cls)
cls = cls or {__call = function(self, ...) return self.new(...) end, _types = {}}
local dcls = setmetatable({}, cls)
dcls.__index = dcls
-- "Inherit" metamethods and cache other methods
for k, v in pairs(cls) do
if k ~= "__index" and type(v) == "function" then
dcls[k] = v
end
end
-- Inherit and update types
dcls._types = {}
for k, v in pairs(cls._types) do
dcls._types[k] = v
end
dcls._types[dcls] = true
return dcls
end
---
-- Test if an object is an instance of the specified class.
--
-- @internal
-- @function isinstanceof
-- @param obj Object
-- @tparam class|cdata|string Class, ctype, or type string
-- @treturn bool Result
local function isinstanceof(obj, cls)
if type(cls) == "string" then
return type(obj) == cls
elseif type(cls) == "table" then
return ((type(obj) == "cdata" or type(obj) == "table") and obj._types and obj._types[cls]) and true or false
elseif type(cls) == "cdata" then
return (type(obj) == "cdata" and obj._types and obj._types[cls.__index]) and true or false
end
return false
end
return {factory = factory, isinstanceof = isinstanceof}