Last active
September 4, 2022 12:30
-
-
Save orbyfied/e2309c4d1180b7e8364191bbba544898 to your computer and use it in GitHub Desktop.
Simple library for aid in object oriented programming in Lua.
This file contains 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
---@diagnostic disable: undefined-field | |
-- Check if the library has already been loaded | |
if _G.LIB_OBJECTS_LOADED then | |
return "already loaded" | |
end | |
------------------------------------------------ | |
----- Utilities | |
------------------------------------------------ | |
_G.tostringvalue = function(value) | |
if value == nil then | |
-- return nil | |
return "nil" | |
else | |
-- get and match type | |
local t = type(value) | |
if t == "string" then | |
return '"' .. value .. '"' | |
elseif t == "function" then | |
-- try and get function info with debug | |
if _G.debug and _G.debug.getinfo then | |
local data = debug.getinfo(value) | |
local fstr = "func: " | |
if data.name then | |
fstr = fstr .. data.name | |
end | |
print(table.tostring(data)) | |
return fstr .. " (args: " .. data.nups .. ")" | |
else | |
return 'func' | |
end | |
else | |
-- use default tostring function | |
return tostring(value) | |
end | |
end | |
end | |
table.fromvarargs = function(...) | |
local t = { } | |
for i = 1, select("#", ...) do | |
t[i] = select(i, ...) | |
end | |
return t | |
end | |
table.isarray = function(table) | |
for k, _ in pairs(table) do | |
if type(k) ~= "number" then | |
return false | |
end | |
end | |
return true | |
end | |
table.tostring = function(data) | |
-- test if it is an array | |
local isarray = table.isarray(data) | |
-- start string | |
local str | |
if isarray then | |
str = "[ " | |
else | |
str = "{ " | |
end | |
-- build content | |
local i = 0 | |
for k, v in pairs(data) do | |
-- add comma | |
if i ~= 0 then | |
str = str .. ", " | |
end | |
-- append key | |
str = str .. tostringvalue(k) | |
-- append = | |
str = str .. " = " | |
-- append value | |
str = str .. tostringvalue(v) | |
-- increment i | |
i = i + 1 | |
end | |
-- finish string | |
if isarray then | |
str = str .. " ]" | |
else | |
str = str .. " }" | |
end | |
-- return | |
return str | |
end | |
------------------------------------------------ | |
----- Objects | |
------------------------------------------------ | |
-- Class List By Name | |
local classes = { } | |
-- Class Metatable | |
local ClassType = { } | |
ClassType.__index = ClassType | |
--- Creates a new instance without calling the constructor | |
--- @return table The instance with metatable set. | |
function ClassType:allocate_instance() | |
-- create empty | |
local instance = setmetatable({ }, self._prototype) | |
-- return | |
return instance | |
end | |
local function failwhencalled(self, ...) | |
error("Constructor has already been called.", 0) | |
end | |
--- Allocates a new instance and calls the constructor | |
--- @vararg any The arguments to call the constructor with. | |
--- @return table The instance. | |
function ClassType:new_instance(...) | |
-- allocate | |
local instance = self:allocate_instance() | |
-- call constructor | |
if instance["__init"] then | |
instance:__init(...) | |
-- dont allow constructor call | |
instance.__init = failwhencalled | |
end | |
-- return instance | |
return instance | |
end | |
--- Get the static instance. | |
--- @return table The static instance. | |
function ClassType:static() | |
-- return static instance | |
return self._static | |
end | |
-- Class Builder Function | |
local ClassBuilderType = { } | |
ClassBuilderType.__index = ClassBuilderType | |
function ClassBuilderType.__call(builder) | |
local class = build_class(builder) | |
return class._static | |
end | |
--- Create a new class builder with a given name. | |
--- @param name string The name of the class. | |
--- @return table The class builder. | |
local function class_builder(name) | |
local instance = setmetatable({}, ClassBuilderType) | |
instance["$name"] = name | |
return instance | |
end | |
--- Takes in a class builder with a name field | |
--- and builds a class object and prototype for | |
--- creating new instances. | |
--- @param builder table The class builder | |
--- @return table The lass object. | |
local function build_class(builder) | |
-- create class | |
local class = setmetatable({ }, ClassType) | |
-- set properties | |
class._name = builder["$name"] | |
-- build static prototype | |
local static_prototype = { } | |
static_prototype.__index = static_prototype | |
function static_prototype.__call(_, ...) | |
return class:new_instance(...) | |
end | |
-- build static instance | |
class._static = setmetatable({ | |
["__class"] = class | |
}, static_prototype) | |
-- build prototype | |
class._prototype = builder | |
class._prototype.__index = class._prototype | |
class._prototype["__class"] = class | |
-- register class | |
classes[class._name] = class | |
-- return class | |
return class | |
end | |
--- @return table The class with the given name or nil. | |
local function get_class(name) | |
return classes[name] | |
end | |
--- @return table The class of the instance. | |
local function get_class_of(inst) | |
return inst["__class"] | |
end | |
-- Set Globals | |
_G.class_builder = class_builder | |
_G.build_class = build_class | |
_G.create_class = create_class | |
_G.get_class = get_class | |
_G.get_class_of = get_class_of | |
_G.classes = classes | |
-- Return Loaded | |
_G.LIB_OBJECTS_LOADED = true | |
return "loaded" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment