Files
community_bridge/lib/utility/shared/callbacks.lua
T

143 lines
4.4 KiB
Lua
Raw Normal View History

2025-05-05 15:49:03 -03:00
local Callback = {}
local CallbackRegistry = {}
-- Constants
local RESOURCE = GetCurrentResourceName() or 'unknown'
local EVENT_NAMES = {
CLIENT_TO_SERVER = RESOURCE .. ':CS:Callback',
SERVER_TO_CLIENT = RESOURCE .. ':SC:Callback',
CLIENT_RESPONSE = RESOURCE .. ':CSR:Callback',
SERVER_RESPONSE = RESOURCE .. ':SCR:Callback'
}
-- Utility functions
local function generateCallbackId(name)
return string.format('%s_%d', name, math.random(1000000, 9999999))
end
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
local function handleResponse(registry, name, callbackId, ...)
local data = registry[callbackId]
if not data then return end
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
if data.callback then
data.callback(...)
end
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
if data.promise then
data.promise:resolve({ ... })
end
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
registry[callbackId] = nil
end
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
local function triggerCallback(eventName, target, name, args, callback)
local callbackId = generateCallbackId(name)
local promise = promise.new()
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
CallbackRegistry[callbackId] = {
2025-03-30 21:06:58 -05:00
callback = callback,
2025-05-05 15:49:03 -03:00
promise = promise
2025-03-30 21:06:58 -05:00
}
2025-05-05 15:49:03 -03:00
if type(target) == 'table' then
for _, id in ipairs(target) do
TriggerClientEvent(eventName, tonumber(id), name, callbackId, table.unpack(args))
2025-03-30 21:06:58 -05:00
end
else
2025-05-05 15:49:03 -03:00
TriggerClientEvent(eventName, tonumber(target), name, callbackId, table.unpack(args))
2025-03-30 21:06:58 -05:00
end
2025-05-05 15:49:03 -03:00
if not callback then
local result = Citizen.Await(promise)
2025-05-05 17:05:29 -05:00
local returnResults = (result and type(result) == 'table' ) and result or {result}
return table.unpack(returnResults)
2025-03-30 21:06:58 -05:00
end
end
2025-05-05 15:49:03 -03:00
-- Server-side implementation
if IsDuplicityVersion() then
function Callback.Register(name, handler)
Callback[name] = handler
end
2025-03-31 03:43:08 -05:00
2025-05-05 15:49:03 -03:00
function Callback.Trigger(name, target, ...)
local args = { ... }
local callback = type(args[1]) == 'function' and table.remove(args, 1) or nil
return triggerCallback(EVENT_NAMES.SERVER_TO_CLIENT, target or -1, name, args, callback)
2025-03-30 21:06:58 -05:00
end
2025-05-05 15:49:03 -03:00
RegisterNetEvent(EVENT_NAMES.CLIENT_TO_SERVER, function(name, callbackId, ...)
2025-07-20 00:38:35 -04:00
if not name or not callbackId then return print(string.format("[%s] Warning: Invalid callback parameters - name: %s, callbackId: %s", RESOURCE, tostring(name), tostring(callbackId))) end
2025-05-05 15:49:03 -03:00
local handler = Callback[name]
if not handler then return end
2025-03-30 21:06:58 -05:00
2025-07-20 00:38:35 -04:00
local playerId = source
if not playerId or playerId == 0 then return print(string.format("[%s] Warning: Invalid source for callback '%s'", RESOURCE, name)) end
local result = table.pack(handler(playerId, ...))
TriggerClientEvent(EVENT_NAMES.CLIENT_RESPONSE, playerId, name, callbackId, table.unpack(result))
2025-05-05 15:49:03 -03:00
end)
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
RegisterNetEvent(EVENT_NAMES.SERVER_RESPONSE, function(name, callbackId, ...)
handleResponse(CallbackRegistry, name, callbackId, ...)
end)
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
-- Client-side implementation
else
local ClientCallbacks = {}
local ReboundCallbacks = {}
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
function Callback.Register(name, handler)
ClientCallbacks[name] = handler
end
2025-05-05 15:49:03 -03:00
function Callback.RegisterRebound(name, handler)
ReboundCallbacks[name] = handler
2025-03-30 21:06:58 -05:00
end
2025-05-05 15:49:03 -03:00
function Callback.Trigger(name, ...)
local args = { ... }
local callback = type(args[1]) == 'function' and table.remove(args, 1) or nil
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
local callbackId = generateCallbackId(name)
local promise = promise.new()
2025-05-05 15:49:03 -03:00
CallbackRegistry[callbackId] = {
callback = callback,
promise = promise
}
TriggerServerEvent(EVENT_NAMES.CLIENT_TO_SERVER, name, callbackId, table.unpack(args))
2025-05-05 15:49:03 -03:00
if not callback then
local result = Citizen.Await(promise)
2025-07-20 00:38:35 -04:00
return table.unpack(result)
2025-05-05 15:49:03 -03:00
end
2025-03-30 21:06:58 -05:00
end
2025-05-05 15:49:03 -03:00
RegisterNetEvent(EVENT_NAMES.CLIENT_RESPONSE, function(name, callbackId, ...)
if ReboundCallbacks[name] then
ReboundCallbacks[name](...)
end
handleResponse(CallbackRegistry, name, callbackId, ...)
end)
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
RegisterNetEvent(EVENT_NAMES.SERVER_TO_CLIENT, function(name, callbackId, ...)
local handler = ClientCallbacks[name]
if not handler then return end
2025-05-05 15:49:03 -03:00
local result = table.pack(handler(...))
TriggerServerEvent(EVENT_NAMES.SERVER_RESPONSE, name, callbackId, table.unpack(result))
end)
end
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
-- Exports
exports('Callback', Callback)
2025-03-30 21:06:58 -05:00
exports('RegisterCallback', Callback.Register)
exports('TriggerCallback', Callback.Trigger)
2025-05-05 15:49:03 -03:00
if not IsDuplicityVersion() then
exports('RegisterRebound', Callback.RegisterRebound)
end
2025-03-30 21:06:58 -05:00
2025-05-05 15:49:03 -03:00
return Callback