modlib/init.lua
2020-02-09 01:39:54 +01:00

114 lines
3.0 KiB
Lua

-- Lua version check
if _VERSION then
if _VERSION < "Lua 5" then
error("Outdated Lua version! modlib requires Lua 5 or greater.")
end
if _VERSION > "Lua 5.1" then -- TODO automatically use _ENV instead of s/getfenv if _VERSION > 5.1
-- not throwing error("Too new Lua version! modlib requires Lua 5.1 or smaller.") anymore
loadstring = load
function setfenv(fn, env)
local i = 1
while true do
name = debug.getupvalue(fn, i)
if name == "_ENV" then
debug.setupvalue(fn, i, env)
break
elseif not name then
break
end
end
return fn
end
function getfenv(fn)
local i = 1
local name, val
repeat
name, val = debug.getupvalue(fn, i)
if name == "_ENV" then
return val
end
i = i + 1
until not name
end
end
end
-- MT shorthands
mt = minetest
MT = mt
-- TODO automatically know current mod
-- get modpath wrapper
function get_resource(modname, resource)
return minetest.get_modpath(modname) .. "/" .. resource
end
-- get resource + dofile
function include(modname, file)
dofile(get_resource(modname, file))
end
function loadfile_exports(filename)
local env = setmetatable({}, {__index = _G, __call = _G})
local file = assert(loadfile(filename))
setfenv(file, env)
file()
return env
end
-- loadfile with table env
function include_class(classname, filename)
_G[classname] = setmetatable(_G[classname] or {}, {__index = _G, __call = _G})
local class = assert(loadfile(filename))
setfenv(class, _G[classname])
class()
return _G[classname]
end
-- runs main.lua in table env
function include_mod(modname)
include_class(modname, get_resource(modname, "main.lua"))
end
function extend_mod(modname, filename)
include_class(modname, get_resource(modname, filename .. ".lua"))
end
function extend_mod_string(modname, string)
_G[modname] = setmetatable(_G[modname] or {}, {__index = _G, __call = _G})
local string = assert(loadstring(string))
setfenv(string, _G[modname])
string()
return _G[modname]
end
local components = {
class = {class = "global"},
conf = {conf = "global"},
data = {data = "global"},
file = {file_ext = "global"},
log = {log = "global"},
minetest = {mt_ext = "global"},
number = {number_ext = "global"},
player = {player_ext = "global"},
table = {table_ext = "global"},
text = {string_ext = "global"},
threading = {threading_ext = "global"}
}
modlib = {}
for component, additional in pairs(components) do
local comp = loadfile_exports(get_resource("modlib", component .. ".lua"))
modlib[component] = comp
for alias, scope in pairs(additional) do
if scope == "global" then
_G[alias] = comp
else
modlib[alias] = comp
end
end
end
_ml = modlib