147 lines
4.0 KiB
Lua
147 lines
4.0 KiB
Lua
---@diagnostic disable: duplicate-set-field
|
|
|
|
-- =============================================
|
|
-- MARK: Variables
|
|
-- =============================================
|
|
|
|
Callbacks = {}
|
|
|
|
Callbacks.requests = {}
|
|
Callbacks.storage = {}
|
|
Callbacks.id = 0
|
|
|
|
-- =============================================
|
|
-- MARK: Internal Functions
|
|
-- =============================================
|
|
|
|
|
|
function Callbacks:Register(name, resource, cb)
|
|
self.storage[name] = {
|
|
resource = resource,
|
|
cb = cb
|
|
}
|
|
end
|
|
|
|
function Callbacks:Execute(cb, id, ...)
|
|
local success, errorString = pcall(cb, ...)
|
|
|
|
if not success then
|
|
print(("[^1ERROR^7] Failed to execute Callback with RequestId: ^5%s^7"):format(id))
|
|
error(errorString)
|
|
return
|
|
end
|
|
end
|
|
|
|
function Callbacks:Trigger(event, cb, invoker, ...)
|
|
self.requests[self.id] = {
|
|
await = type(cb) == "boolean",
|
|
cb = cb or promise:new()
|
|
}
|
|
local table = self.requests[self.id]
|
|
|
|
TriggerServerEvent("esx:triggerServerCallback", event, self.id, invoker, ...)
|
|
|
|
self.id += 1
|
|
|
|
return table.cb
|
|
end
|
|
|
|
function Callbacks:ServerRecieve(requestId, invoker, ...)
|
|
if not self.requests[requestId] then
|
|
return error(("Server Callback with requestId ^5%s^1 Was Called by ^5%s^1 but does not exist."):format(requestId, invoker))
|
|
end
|
|
|
|
local callback = self.requests[requestId]
|
|
|
|
self.requests[requestId] = nil
|
|
|
|
if callback.await then
|
|
callback.cb:resolve({ ... })
|
|
else
|
|
self:Execute(callback.cb, requestId, ...)
|
|
end
|
|
end
|
|
|
|
function Callbacks:ClientRecieve(eventName, requestId, invoker, ...)
|
|
if not self.storage[eventName] then
|
|
return error(("Client Callback with requestId ^5%s^1 Was Called by ^5%s^1 but does not exist."):format(eventName, invoker))
|
|
end
|
|
|
|
local returnCb = function(...)
|
|
TriggerServerEvent("esx:clientCallback", requestId, invoker, ...)
|
|
end
|
|
local callback = self.storage[eventName].cb
|
|
|
|
self:Execute(callback, requestId, returnCb, ...)
|
|
end
|
|
|
|
-- =============================================
|
|
-- MARK: ESX Functions
|
|
-- =============================================
|
|
|
|
---@param eventName string
|
|
---@param callback function
|
|
---@param ... any
|
|
---@return nil
|
|
function ESX.TriggerServerCallback(eventName, callback, ...)
|
|
local invokingResource = GetInvokingResource()
|
|
local invoker = (invokingResource and invokingResource ~= "unknown") and invokingResource or "es_extended"
|
|
|
|
Callbacks:Trigger(eventName, callback, invoker, ...)
|
|
end
|
|
|
|
---@param eventName string
|
|
---@param ... any
|
|
---@return ...
|
|
function ESX.AwaitServerCallback(eventName, ...)
|
|
local invokingResource = GetInvokingResource()
|
|
local invoker = (invokingResource and invokingResource ~= "unknown") and invokingResource or "es_extended"
|
|
|
|
local p = Callbacks:Trigger(eventName, false, invoker, ...)
|
|
if not p then return end
|
|
|
|
-- if the server callback takes longer than 15 seconds to respond, reject the promise
|
|
SetTimeout(15000, function()
|
|
if p.state == "pending" then
|
|
p:reject("Server Callback Timed Out")
|
|
end
|
|
end)
|
|
|
|
Citizen.Await(p)
|
|
|
|
return table.unpack(p.value)
|
|
end
|
|
|
|
function ESX.RegisterClientCallback(eventName, callback)
|
|
local invokingResource = GetInvokingResource()
|
|
local invoker = (invokingResource and invokingResource ~= "Unknown") and invokingResource or "es_extended"
|
|
|
|
Callbacks:Register(eventName, invoker, callback)
|
|
end
|
|
|
|
---@param eventName string
|
|
---@return boolean
|
|
function ESX.DoesClientCallbackExist(eventName)
|
|
return Callbacks.storage[eventName] ~= nil
|
|
end
|
|
|
|
-- =============================================
|
|
-- MARK: Events
|
|
-- =============================================
|
|
|
|
ESX.SecureNetEvent("esx:serverCallback", function(...)
|
|
Callbacks:ServerRecieve(...)
|
|
end)
|
|
|
|
ESX.SecureNetEvent("esx:triggerClientCallback", function(...)
|
|
Callbacks:ClientRecieve(...)
|
|
end)
|
|
|
|
AddEventHandler("onResourceStop", function(resource)
|
|
for k, v in pairs(Callbacks.storage) do
|
|
if v.resource == resource then
|
|
Callbacks.storage[k] = nil
|
|
end
|
|
end
|
|
end)
|