diff --git a/init.lua b/init.lua index 6a1c9cc..8db2673 100644 --- a/init.lua +++ b/init.lua @@ -22,7 +22,7 @@ function Bridge.RegisterModule(moduleName, moduleTable) end Bridge[moduleName] = wrappedModule _ENV[moduleName] = wrappedModule -- Add to the ENV table the modules so is more easy and safe to call from inside - + _ENV.Bridge = Bridge -- Add the bridge too to the _ENV exports(moduleName, function() return wrappedModule @@ -31,38 +31,19 @@ function Bridge.RegisterModule(moduleName, moduleTable) --trigger update object event TriggerEvent("Bridge:Refresh", moduleName, wrappedModule) end - -CreateThread(function() -- lets try to load the lib first to use it on the rest of the modules - for k, v in pairs(cLib) do - if v then - Bridge.RegisterModule(k, v) - end - end -end) - ---- @module GlobalEnvironment ---- @field cLib table # Core library utilities, available globally after initialization. ---- @field Require fun(module: string): any # Function to require/load modules by name. - ---- Global environment setup. --- The following assignments expose core utilities globally, --- making them accessible in all subsequently loaded modules. - -_ENV.cLib = cLib ~= nil and cLib or export.community_lib.cLib() ---@type table -_ENV.Require = Require ---@type fun(module: string): any exports("RegisterModule", Bridge.RegisterModule) --TODO: Create a way to overide functions or create a new functions for module function Bridge.RegisterModuleFunction(moduleName, functionName, func) - assert(moduleName and functionName and func, - string.format("Bridge.RegisterModuleFunction(%s, %s, %s) - Invalid arguments", moduleName, functionName, func)) + assert(moduleName and functionName and func, string.format("Bridge.RegisterModuleFunction(%s, %s, %s) - Invalid arguments", moduleName, functionName, func)) Bridge[moduleName] = Bridge[moduleName] or {} Bridge[moduleName][functionName] = func --trigger update object event TriggerEvent("Bridge:Refresh", moduleName, Bridge[moduleName]) end + --Bridge Bridge.RegisterModule("Framework", Framework) Bridge.RegisterModule("Inventory", Inventory) @@ -94,27 +75,23 @@ Bridge.RegisterModule("Require", Require) -- Bridge.RegisterModule("Skills", Skills) - - ---[[ CreateThread(function() -- using metatables - for k, v in pairs(cLib.loaded) do - if v then - Bridge.RegisterModule(k, v) - end +for k, v in pairs(cLib) do + if v then + Bridge.RegisterModule(k, v) end -end) ]] +end exports('Bridge', function() return Bridge end) --- ▄▀▀ ██▀ █▀▄ █ █ ██▀ █▀▄ --- ▄█▀ █▄▄ █▀▄ ▀▄▀ █▄▄ █▀▄ +-- ▄▀▀ ██▀ █▀▄ █ █ ██▀ █▀▄ +-- ▄█▀ █▄▄ █▀▄ ▀▄▀ █▄▄ █▀▄ if not IsDuplicityVersion() then goto client end Bridge.RegisterModule('Version', Version) --- ▄▀▀ █ █ ██▀ █▄ █ ▀█▀ --- ▀▄▄ █▄▄ █ █▄▄ █ ▀█ █ +-- ▄▀▀ █ █ ██▀ █▄ █ ▀█▀ +-- ▀▄▄ █▄▄ █ █▄▄ █ ▀█ █ if IsDuplicityVersion() then return end ::client:: diff --git a/lib/cache/client/cache.lua b/lib/cache/client/cache.lua index b9aefdc..df493c8 100644 --- a/lib/cache/client/cache.lua +++ b/lib/cache/client/cache.lua @@ -54,10 +54,10 @@ local function GetWeapon() return GetSelectedPedWeapon(ped) end -Cache.Create("Ped", GetPed, nil) -- Check ped every second (adjust as needed) -Cache.Create("Vehicle", GetVehicle, 500) -- Check vehicle every 500ms -Cache.Create("Seat", GetVehicleSeat, 500) -- Check if in vehicle every 500ms -Cache.Create("Weapon", GetWeapon, 250) -- Check weapon every 250ms -Cache.Create("ServerId", GetServerId, nil) -- Check server ID every second +Cache.Create("Ped", GetPed, 1000) -- Check ped every second (adjust as needed) +Cache.Create("Vehicle", GetVehicle, 500) -- Check vehicle every 500ms +Cache.Create("Seat", GetVehicleSeat, 500) -- Check if in vehicle every 500ms +Cache.Create("Weapon", GetWeapon, 250) -- Check weapon every 250ms +Cache.Create("ServerId", GetServerId, 1000) -- Check server ID every second return Cache diff --git a/lib/cache/shared/cache.lua b/lib/cache/shared/cache.lua index 05b5359..ed42a50 100644 --- a/lib/cache/shared/cache.lua +++ b/lib/cache/shared/cache.lua @@ -1,54 +1,29 @@ ----@class CacheEntry ----@field Name string ----@field Compare fun(): any ----@field WaitTime integer ----@field LastChecked integer|nil ----@field OnChange fun(new:any, old:any)[] ----@field Value any - ----@class CacheModule ----@field Caches table ----@field LoopRunning boolean ----@field Create fun(name:string, compare:fun():any, waitTime?:integer): CacheEntry ----@field Get fun(name:string): any ----@field OnChange fun(name:string, onChange:fun(new:any, old:any)) ----@field Remove fun(name:string) -local Cache = {} ---@type CacheModule - +local Cache = {} local Config = Require("settings/sharedConfig.lua") local max = 5000 local CreateThread = CreateThread local Wait = Wait local GetGameTimer = GetGameTimer + Cache.Caches = Cache.Caches or {} Cache.LoopRunning = Cache.LoopRunning or false ----@param ... any -local function debugPrint(...) +local function print(...) if Config.DebugLevel == 0 then return end print("^2[Cache]^0", ...) end -local function HasActiveCaches() - for _, cache in pairs(Cache.Caches) do - if cache.WaitTime ~= nil then - return true - end - end - return false -end - local function StartLoop() if Cache.LoopRunning then return end - if not HasActiveCaches() then return end Cache.LoopRunning = true CreateThread(function() while Cache.LoopRunning do local now = GetGameTimer() local minWait = nil - for name, cache in pairs(Cache.Caches) do - if cache.Compare and cache.WaitTime ~= nil then + local caches = Cache.Caches + for name, cache in pairs(caches) do + if cache.Compare then cache.LastChecked = cache.LastChecked or now cache.WaitTime = cache.WaitTime or max local elapsed = now - cache.LastChecked @@ -57,8 +32,8 @@ local function StartLoop() local oldValue = cache.Value cache.Value = cache.Compare() if cache.Value ~= oldValue and cache.OnChange then - for i = 1, #cache.OnChange do - cache.OnChange[i](cache.Value, oldValue) + for _, onChange in pairs(cache.OnChange) do + onChange(cache.Value, oldValue) end end cache.LastChecked = now @@ -75,53 +50,44 @@ local function StartLoop() else Wait(max) end - -- if there is no cache valid, stop the loop - if not HasActiveCaches() then - Cache.LoopRunning = false - end end end) end ----@param name string ----@param compare fun():any ----@param waitTime? integer ----@return CacheEntry function Cache.Create(name, compare, waitTime) assert(name, "Cache name is required.") assert(compare, "Comparison function is required.") assert(type(compare) == "function", "Comparison function must be a function.") - local _name = tostring(name) + local _name = tostring(name) -- Ensure name is a string local cache = Cache.Caches[_name] if cache and cache.Compare == compare then - debugPrint(_name .. " already exists with the same comparison function.") + print(name .. " already exists with the same comparison function.") return cache end - local ok, result = pcall(compare) - if not ok then - debugPrint("Error creating cache '" .. _name .. "': " .. tostring(result)) + cache = nil -- clean variable, so we can use the same name for the new cache + local s, r = pcall(function() -- Try to create the cache and catch any errors + local _cache = { + Name = _name, + Compare = compare, + WaitTime = waitTime or max, + LastChecked = nil, + OnChange = {}, + Value = compare() + } + Cache.Caches[_name] = _cache + print(_name .. " created with initial value: " .. tostring(Cache.Caches[_name].Value)) + for _, onChange in pairs(_cache.OnChange) do + onChange(_cache.Value, nil) + end + end) + if not s then + print("Error creating cache '" .. _name .. "': " .. tostring(r)) return nil end - ---@type CacheEntry - local newCache = { - Name = _name, - Compare = compare, - WaitTime = waitTime, -- can be nil - LastChecked = nil, - OnChange = {}, - Value = result - } - Cache.Caches[_name] = newCache - debugPrint(_name .. " created with initial value: " .. tostring(result)) - for i = 1, #newCache.OnChange do - newCache.OnChange[i](newCache.Value, nil) - end - StartLoop() - return newCache + + return StartLoop() end ----@param name string ----@return any function Cache.Get(name) assert(name, "Cache name is required.") local _name = tostring(name) @@ -129,60 +95,25 @@ function Cache.Get(name) return cache and cache.Value or nil end ----@param name string ----@param onChange fun(new:any, old:any) function Cache.OnChange(name, onChange) assert(name, "Cache name is required.") - local _name = tostring(name) + local _name = tostring(name) -- Ensure name is a string local cache = Cache.Caches[_name] assert(cache, "Cache with name '" .. _name .. "' does not exist.") cache.OnChange[#cache.OnChange + 1] = onChange end ----@param name string ----@param newValue any -function Cache.Update(name, newValue) - assert(name, "Cache name is required.") - local _name = tostring(name) - local cache = Cache.Caches[_name] - assert(cache, "Cache with name '" .. _name .. "' does not exist.") - local oldValue = cache.Value - if oldValue ~= newValue then - cache.Value = newValue - for i = 1, #cache.OnChange do - cache.OnChange[i](newValue, oldValue) - end - end -end - ----@param name string function Cache.Remove(name) assert(name, "Cache name is required.") - local _name = tostring(name) + local _name = tostring(name) -- Ensure name is a string local cache = Cache.Caches[_name] if cache then Cache.Caches[_name] = nil - debugPrint(_name .. " removed from cache.") + print(_name .. " removed from cache.") if next(Cache.Caches) == nil then - Cache.LoopRunning = false + Cache.LoopRunning = false -- Stop the loop if no caches are left end end end -setmetatable(Cache, { - __index = function(self, key) - local cache = self.Caches[key] - if cache then - return cache.Value - else - return rawget(self, key) - end - end, - __call = function(self, key) - return self.Get(self, key) - end, -}) - --- with this change now we can use Cache("name") to get the value or simple Cache.name (Cache.Get("name")) - return Cache diff --git a/lib/init.lua b/lib/init.lua index 4003b66..7aa6a34 100644 --- a/lib/init.lua +++ b/lib/init.lua @@ -1,5 +1,4 @@ loadedModules = {} -local cLib = {} function Require(modulePath, resourceName) if resourceName and type(resourceName) ~= "string" then @@ -36,93 +35,23 @@ function Require(modulePath, resourceName) return result end -local function getServerLib() - return { - SQL = SQL or Require("lib/sql/server/sqlHandler.lua"), - Logs = Logs or Require("lib/logs/server/logs.lua"), - ItemsBuilder = ItemsBuilder or Require("lib/generators/server/ItemsBuilder.lua"), - LootTables = LootTables or Require("lib/generators/server/lootTables.lua"), - Cache = Cache or Require("lib/cache/shared/cache.lua"), - ServerEntity = ServerEntity or Require("lib/entities/server/server_entity.lua"), - Marker = Marker or Require("lib/markers/server/server.lua"), - Particle = Particle or Require("lib/particles/server/particles.lua"), - } -end -local function getClientLib() - return { - Require = Require, - Gizmo = Gizmo or Require("lib/placers/client/gizmo.lua"), - Scaleform = Scaleform or Require("lib/scaleform/client/scaleform.lua"), - Placeable = Placeable or Require("lib/placers/client/object_placer.lua"), - Utility = Utility or Require("lib/utility/client/utility.lua"), - PlaceableObject = PlaceableObject or Require("lib/placers/client/placeable_object.lua"), - Raycast = Raycast or Require("lib/raycast/client/raycast.lua"), - Point = Point or Require("lib/points/client/points.lua"), - Particle = Particle or Require("lib/particles/client/particles.lua"), - Cache = Cache or Require("lib/cache/client/cache.lua"), - ClientEntity = ClientEntity or Require("lib/entities/client/client_entity.lua"), - ClientEntityActions = ClientEntityActions or Require("lib/entities/client/client_entity_actions.lua"), - ClientStateBag = ClientStateBag or Require("lib/statebags/client/client.lua"), - Marker = Marker or Require("lib/markers/client/markers.lua"), - Anim = Anim or Require("lib/anim/client/client.lua"), - Cutscene = Cutscene or Require("lib/cutscenes/client/cutscene.lua"), - DUI = DUI or Require("lib/dui/client/dui.lua"), - } -end -local function getSharedLib() - return { - Require = Require, - Callback = Callback or Require("lib/utility/shared/callbacks.lua"), - Ids = Ids or Require("lib/utility/shared/ids.lua"), - ReboundEntities = ReboundEntities or Require("lib/utility/shared/rebound_entities.lua"), - Tables = Tables or Require("lib/utility/shared/tables.lua"), - Prints = Prints or Require("lib/utility/shared/prints.lua"), - Math = Math or Require("lib/utility/shared/math.lua"), - LA = LA or Require("lib/utility/shared/la.lua"), - Perlin = Perlin or Require("lib/utility/shared/perlin.lua"), - -- Action = Action or Require("lib/entities/shared/actions.lua"), - } -end +cLib = { + Require = Require, + Callback = Callback or Require("lib/utility/shared/callbacks.lua"), + Ids = Ids or Require("lib/utility/shared/ids.lua"), + ReboundEntities = ReboundEntities or Require("lib/utility/shared/rebound_entities.lua"), + Tables = Tables or Require("lib/utility/shared/tables.lua"), + Prints = Prints or Require("lib/utility/shared/prints.lua"), + Math = Math or Require("lib/utility/shared/math.lua"), + LA = LA or Require("lib/utility/shared/la.lua"), + Perlin = Perlin or Require("lib/utility/shared/perlin.lua"), + -- Action = Action or Require("lib/entities/shared/actions.lua"), +} -cLib = setmetatable(getSharedLib(), { __index = IsDuplicityVersion() and getServerLib() or getClientLib() }) -exports('cLib', function() - return cLib -end) +exports('cLib', cLib) ---[[ _ENV.cLib = setmetatable({ - context = not IsDuplicityVersion() and "client" or "server", - resource = GetCurrentResourceName(), - loaded = {} -}, { - __newindex = function(self, key, value) - return error("Attempt to modify read-only table: " .. key) - end, - __index = function(self, key) -- modify the index function to load the library modules - if self.context == "server" then - return rawget(self.loaded, key) - else - return rawget(self.loaded, key) - end - end, - __call = function(self) -- modify the call function to load the library modules - if self.context == "server" then - if not next(self.loaded) then - self.loaded = getServerLib() - return true - end - else - if not next(self.loaded) then - self.loaded = getClientLib() - return true - end - end - end, -}) -cLib() -- load the library modules ]] - ---[[ if not IsDuplicityVersion() then goto client end cLib.SQL = SQL or Require("lib/sql/server/sqlHandler.lua") @@ -155,4 +84,3 @@ cLib.DUI = DUI or Require("lib/dui/client/dui.lua") cLib.Particle = Particle or Require("lib/particles/client/particles.lua") return cLib - ]]