Skip to content

Commit

Permalink
Merge pull request #1481 from Mycroft-Studios/await-callbacks
Browse files Browse the repository at this point in the history
feat(es_extended/client/callback): implement ESX.AwaitServerCallback
  • Loading branch information
Mycroft-Studios authored Nov 17, 2024
2 parents 7cf3673 + faef100 commit 4bd84d6
Showing 1 changed file with 43 additions and 11 deletions.
54 changes: 43 additions & 11 deletions [core]/es_extended/client/modules/callback.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,51 @@ Callbacks.storage = {}
Callbacks.id = 0

function Callbacks:Trigger(event, cb, invoker, ...)
self.requests[self.id] = cb

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:Execute(cb, ...)
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(self.currentId))
print(("[^1ERROR^7] Failed to execute Callback with RequestId: ^5%s^7"):format(id))
error(errorString)
return
end
self.currentId = nil
end

function Callbacks:ServerRecieve(requestId, invoker, ...)
self.currentId = requestId
if not self.requests[self.currentId] then
return error(("Server Callback with requestId ^5%s^1 Was Called by ^5%s^1 but does not exist."):format(self.currentId, 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[self.currentId]
local callback = self.requests[requestId]

Callbacks:Execute(callback, ...)
self.requests[requestId] = nil

if callback.await then
callback.cb:resolve({...})
else
self:Execute(callback.cb, requestId, ...)
end
end

function Callbacks:Register(name, cb)
self.storage[name] = cb
end

function Callbacks:ClientRecieve(eventName, requestId, invoker, ...)
self.currentId = requestId

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))
Expand All @@ -52,7 +62,7 @@ function Callbacks:ClientRecieve(eventName, requestId, invoker, ...)
end
local callback = self.storage[eventName]

Callbacks:Execute(callback, returnCb, ...)
self:Execute(callback, requestId, returnCb, ...)
end

---@param eventName string
Expand All @@ -66,6 +76,28 @@ ESX.TriggerServerCallback = function(eventName, callback, ...)
Callbacks:Trigger(eventName, callback, invoker, ...)
end

---@param eventName string
---@param ... any
---@return any
ESX.AwaitServerCallback = function(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

ESX.SecureNetEvent("esx:serverCallback", function(...)
Callbacks:ServerRecieve(...)
end)
Expand Down

0 comments on commit 4bd84d6

Please sign in to comment.