diff --git a/[core]/es_extended/client/modules/streaming.lua b/[core]/es_extended/client/modules/streaming.lua index 8614c4fb..385e57c8 100644 --- a/[core]/es_extended/client/modules/streaming.lua +++ b/[core]/es_extended/client/modules/streaming.lua @@ -1,4 +1,31 @@ ESX.Streaming = {} +local StreamTimeoutMS = 5000 +local StreamWaitStepMs = 50 + +---@param cond fun():boolean +---@param timeout number|nil +---@param step number|nil +---@return boolean loaded -- false on timeout +local function waitForLoaded(cond, timeout, step) + local start = GetGameTimer() + local to = timeout or StreamTimeoutMS + local st = step or StreamWaitStepMs + while not cond() do + if GetGameTimer() - start >= to then + return false + end + Wait(st) + end + return true +end + +---@generic T +---@param cb fun(val:T):any|nil +---@param val T +---@return T|any +local function ret(cb, val) + return cb and cb(val) or val +end ---@param modelHash number | string ---@param cb? function @@ -8,63 +35,94 @@ function ESX.Streaming.RequestModel(modelHash, cb) if not IsModelInCdimage(modelHash) then return end - RequestModel(modelHash) - while not HasModelLoaded(modelHash) do Wait(500) end + if HasModelLoaded(modelHash) then + return ret(cb, modelHash) + end - return cb and cb(modelHash) or modelHash + RequestModel(modelHash) + if not waitForLoaded(function() return HasModelLoaded(modelHash) end) then + return + end + + return ret(cb, modelHash) end ---@param textureDict string ---@param cb? function ---@return string | nil function ESX.Streaming.RequestStreamedTextureDict(textureDict, cb) + if HasStreamedTextureDictLoaded(textureDict) then + return ret(cb, textureDict) + end + RequestStreamedTextureDict(textureDict, false) + if not waitForLoaded(function() return HasStreamedTextureDictLoaded(textureDict) end) then + return + end - while not HasStreamedTextureDictLoaded(textureDict) do Wait(500) end - - return cb and cb(textureDict) or textureDict + return ret(cb, textureDict) end ---@param assetName string ---@param cb? function ---@return string | nil function ESX.Streaming.RequestNamedPtfxAsset(assetName, cb) + if HasNamedPtfxAssetLoaded(assetName) then + return ret(cb, assetName) + end + RequestNamedPtfxAsset(assetName) + if not waitForLoaded(function() return HasNamedPtfxAssetLoaded(assetName) end) then + return + end - while not HasNamedPtfxAssetLoaded(assetName) do Wait(500) end - - return cb and cb(assetName) or assetName + return ret(cb, assetName) end ---@param animSet string ---@param cb? function ---@return string | nil function ESX.Streaming.RequestAnimSet(animSet, cb) + if HasAnimSetLoaded(animSet) then + return ret(cb, animSet) + end + RequestAnimSet(animSet) + if not waitForLoaded(function() return HasAnimSetLoaded(animSet) end) then + return + end - while not HasAnimSetLoaded(animSet) do Wait(500) end - - return cb and cb(animSet) or animSet + return ret(cb, animSet) end ---@param animDict string ---@param cb? function ---@return string | nil function ESX.Streaming.RequestAnimDict(animDict, cb) + if HasAnimDictLoaded(animDict) then + return ret(cb, animDict) + end + RequestAnimDict(animDict) + if not waitForLoaded(function() return HasAnimDictLoaded(animDict) end) then + return + end - while not HasAnimDictLoaded(animDict) do Wait(500) end - - return cb and cb(animDict) or animDict + return ret(cb, animDict) end ---@param weaponHash number | string ---@param cb? function ---@return string | number | nil function ESX.Streaming.RequestWeaponAsset(weaponHash, cb) + if HasWeaponAssetLoaded(weaponHash) then + return ret(cb, weaponHash) + end + RequestWeaponAsset(weaponHash, 31, 0) + if not waitForLoaded(function() return HasWeaponAssetLoaded(weaponHash) end) then + return + end - while not HasWeaponAssetLoaded(weaponHash) do Wait(500) end - - return cb and cb(weaponHash) or weaponHash + return ret(cb, weaponHash) end