170 lines
6.1 KiB
Lua
170 lines
6.1 KiB
Lua
local args = table.pack(...)
|
|
local dir = fs.getDir(args[2] or "basalt")
|
|
local subDir = args[1]
|
|
if(dir==nil)then
|
|
error("Unable to find directory "..args[2].." please report this bug to our discord.")
|
|
end
|
|
|
|
local log = require("log")
|
|
local defaultPath = package.path
|
|
local format = "path;/path/?.lua;/path/?/init.lua;"
|
|
local main = format:gsub("path", dir)
|
|
|
|
--- This class manages elements and plugins. It loads elements and plugins from the elements and plugins directories
|
|
--- and then applies the plugins to the elements. It also provides a way to get elements and APIs.
|
|
--- @class ElementManager
|
|
local ElementManager = {}
|
|
ElementManager._elements = {}
|
|
ElementManager._plugins = {}
|
|
ElementManager._APIs = {}
|
|
local elementsDirectory = fs.combine(dir, "elements")
|
|
local pluginsDirectory = fs.combine(dir, "plugins")
|
|
|
|
log.info("Loading elements from "..elementsDirectory)
|
|
if fs.exists(elementsDirectory) then
|
|
for _, file in ipairs(fs.list(elementsDirectory)) do
|
|
local name = file:match("(.+).lua")
|
|
if name then
|
|
log.debug("Found element: "..name)
|
|
ElementManager._elements[name] = {
|
|
class = nil,
|
|
plugins = {},
|
|
loaded = false
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
log.info("Loading plugins from "..pluginsDirectory)
|
|
if fs.exists(pluginsDirectory) then
|
|
for _, file in ipairs(fs.list(pluginsDirectory)) do
|
|
local name = file:match("(.+).lua")
|
|
if name then
|
|
log.debug("Found plugin: "..name)
|
|
local plugin = require(fs.combine("plugins", name))
|
|
if type(plugin) == "table" then
|
|
for k,v in pairs(plugin) do
|
|
if(k ~= "API")then
|
|
if(ElementManager._plugins[k]==nil)then
|
|
ElementManager._plugins[k] = {}
|
|
end
|
|
table.insert(ElementManager._plugins[k], v)
|
|
else
|
|
ElementManager._APIs[name] = v
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
if(minified)then
|
|
if(minified_elementDirectory==nil)then
|
|
error("Unable to find minified_elementDirectory please report this bug to our discord.")
|
|
end
|
|
for name,v in pairs(minified_elementDirectory)do
|
|
ElementManager._elements[name:gsub(".lua", "")] = {
|
|
class = nil,
|
|
plugins = {},
|
|
loaded = false
|
|
}
|
|
end
|
|
if(minified_pluginDirectory==nil)then
|
|
error("Unable to find minified_pluginDirectory please report this bug to our discord.")
|
|
end
|
|
for name,_ in pairs(minified_pluginDirectory)do
|
|
local plugName = name:gsub(".lua", "")
|
|
local plugin = require(fs.combine("plugins", plugName))
|
|
if type(plugin) == "table" then
|
|
for k,v in pairs(plugin) do
|
|
if(k ~= "API")then
|
|
if(ElementManager._plugins[k]==nil)then
|
|
ElementManager._plugins[k] = {}
|
|
end
|
|
table.insert(ElementManager._plugins[k], v)
|
|
else
|
|
ElementManager._APIs[plugName] = v
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Loads an element by name. This will load the element and apply any plugins to it.
|
|
--- @param name string The name of the element to load
|
|
--- @usage ElementManager.loadElement("Button")
|
|
function ElementManager.loadElement(name)
|
|
if not ElementManager._elements[name].loaded then
|
|
package.path = main.."rom/?"
|
|
local element = require(fs.combine("elements", name))
|
|
package.path = defaultPath
|
|
ElementManager._elements[name] = {
|
|
class = element,
|
|
plugins = element.plugins,
|
|
loaded = true
|
|
}
|
|
log.debug("Loaded element: "..name)
|
|
|
|
if(ElementManager._plugins[name]~=nil)then
|
|
for _, plugin in pairs(ElementManager._plugins[name]) do
|
|
if(plugin.setup)then
|
|
plugin.setup(element)
|
|
end
|
|
|
|
if(plugin.hooks)then
|
|
for methodName, hooks in pairs(plugin.hooks) do
|
|
local original = element[methodName]
|
|
if(type(original)~="function")then
|
|
error("Element "..name.." does not have a method "..methodName)
|
|
end
|
|
if(type(hooks)=="function")then
|
|
element[methodName] = function(self, ...)
|
|
local result = original(self, ...)
|
|
local hookResult = hooks(self, ...)
|
|
return hookResult == nil and result or hookResult
|
|
end
|
|
elseif(type(hooks)=="table")then
|
|
element[methodName] = function(self, ...)
|
|
if hooks.pre then hooks.pre(self, ...) end
|
|
local result = original(self, ...)
|
|
if hooks.post then hooks.post(self, ...) end
|
|
return result
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
for funcName, func in pairs(plugin) do
|
|
if funcName ~= "setup" and funcName ~= "hooks" then
|
|
element[funcName] = func
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
--- Gets an element by name. If the element is not loaded, it will try to load it first.
|
|
--- @param name string The name of the element to get
|
|
--- @return table Element The element class
|
|
function ElementManager.getElement(name)
|
|
if not ElementManager._elements[name].loaded then
|
|
ElementManager.loadElement(name)
|
|
end
|
|
return ElementManager._elements[name].class
|
|
end
|
|
|
|
--- Gets a list of all elements
|
|
--- @return table ElementList A list of all elements
|
|
function ElementManager.getElementList()
|
|
return ElementManager._elements
|
|
end
|
|
|
|
--- Gets an Plugin API by name
|
|
--- @param name string The name of the API to get
|
|
--- @return table API The API
|
|
function ElementManager.getAPI(name)
|
|
return ElementManager._APIs[name]
|
|
end
|
|
|
|
return ElementManager |