feat(init): cache.__call metamethod for caching function results

See #385.
Included formatting changes (tabs->spaces).
This commit is contained in:
Linden
2023-08-02 15:16:37 +10:00
parent 05c9d335e8
commit b68da917be

View File

@@ -1,6 +1,7 @@
-- ox_lib <https://github.com/overextended/ox_lib>
-- Copyright (C) 2021 Linden <https://github.com/thelindat>
-- LGPL-3.0-or-later <https://www.gnu.org/licenses/lgpl-3.0.en.html>
---@meta
---ox_lib <https://github.com/overextended/ox_lib>
---Copyright (C) 2021 Linden <https://github.com/thelindat>
---LGPL-3.0-or-later <https://www.gnu.org/licenses/lgpl-3.0.en.html>
if not _VERSION:find('5.4') then
error('^1Lua 5.4 must be enabled in the resource manifest!^0', 2)
@@ -144,25 +145,51 @@ function ClearInterval(id)
intervals[id] = -1
end
-----------------------------------------------------------------------------------------------
-- Cache
-----------------------------------------------------------------------------------------------
--[[
lua language server doesn't support generics when using @overload
see https://github.com/LuaLS/lua-language-server/issues/723
this function stub allows the following to work
cache = { game = GetGameName(), resource = GetCurrentResourceName() }
local notify = ('__ox_notify_%s'):format(cache.resource)
local key = cache('key', function() return 'abc' end) -- fff: 'abc'
local game = cache.game -- game: string
]]
if context == 'client' then
setmetatable(cache, {
__index = function(self, key)
---@generic T
---@param key string
---@param func fun(...: any): T
---@param timeout? number
---@return T
---Caches the result of a function, optionally clearing it after timeout ms.
function cache(key, func, timeout) end
cache = setmetatable({ game = GetGameName(), resource = GetCurrentResourceName() }, {
__index = context == 'client' and function(self, key)
AddEventHandler(('ox_lib:cache:%s'):format(key), function(value)
self[key] = value
end)
return rawset(self, key, export.cache(nil, key) or false)[key]
end,
})
end or nil,
RegisterNetEvent(notify, function(data)
__call = function(self, key, func, timeout)
local value = rawget(self, key)
if not value then
value = func()
rawset(self, key, value)
if timeout then SetTimeout(timeout, function() self[key] = nil end) end
end
return value
end,
})
local notifyEvent = ('__ox_notify_%s'):format(cache.resource)
if context == 'client' then
RegisterNetEvent(notifyEvent, function(data)
if locale then
if data.title then
data.title = locale(data.title) or data.title
@@ -188,6 +215,6 @@ else
---@deprecated
---@diagnostic disable-next-line: duplicate-set-field
function lib.notify(playerId, data)
TriggerClientEvent(notify, playerId, data)
TriggerClientEvent(notifyEvent, playerId, data)
end
end