From 71be624697dcce392991ac57e5e9c71221e049ba Mon Sep 17 00:00:00 2001 From: Kenshin13 <63159154+Kenshiin13@users.noreply.github.com> Date: Wed, 1 Jan 2025 19:35:15 +0100 Subject: [PATCH] feat(es_extended/imports): add require --- [core]/es_extended/imports.lua | 64 ++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/[core]/es_extended/imports.lua b/[core]/es_extended/imports.lua index 2727995d3..80f1438aa 100644 --- a/[core]/es_extended/imports.lua +++ b/[core]/es_extended/imports.lua @@ -1,4 +1,5 @@ ESX = exports["es_extended"]:getSharedObject() +_resourceName = GetCurrentResourceName() OnPlayerData = function (key, val, last) end @@ -42,3 +43,66 @@ if not IsDuplicityVersion() then -- Only register this event for the client end end end + +local cachedModules = {} ---@type table +local loadingModules = {} ---@type table + +---@param modulePath string +---@return string +local function getResourceNameFromModulePath(modulePath) + local externalResourceName = modulePath:match("^@(.-)%.") + if externalResourceName then + return externalResourceName + end + + return _resourceName +end + +---@param modulePath string +---@return string, number +local function getModuleFilePath(modulePath) + if modulePath:sub(1, 1) == "@" then + modulePath = modulePath:sub(modulePath:find("%.") + 1) + end + + return modulePath:gsub("%.", "/") +end + +---@param modulePath string +---@return any +function require(modulePath) + assert(type(modulePath) == "string", "Module name must be a string") + + if loadingModules[modulePath] then + error(("Circular dependency detected for module '%s'."):format(modulePath)) + end + + if cachedModules[modulePath] then + return cachedModules[modulePath] + end + + loadingModules[modulePath] = true + + local resourceName = getResourceNameFromModulePath(modulePath) + local moduleFilePath = getModuleFilePath(modulePath) + local moduleFileContent = LoadResourceFile(resourceName, moduleFilePath .. ".lua") + + if not moduleFileContent then + loadingModules[modulePath] = nil + error(("Module '%s' not found in resource '%s'."):format(moduleFilePath, resourceName)) + end + + local chunk, err = load(moduleFileContent, ("@%s/%s"):format(resourceName, moduleFilePath), "t") + + if not chunk then + loadingModules[modulePath] = nil + error(("Failed to load module '%s': %s"):format(moduleFilePath, err)) + end + + local result = chunk() + + cachedModules[modulePath] = result ~= nil and result or true + loadingModules[modulePath] = nil + + return result +end