diff --git a/package/client/resource/streaming/index.ts b/package/client/resource/streaming/index.ts index 5af27cc..31fc72c 100644 --- a/package/client/resource/streaming/index.ts +++ b/package/client/resource/streaming/index.ts @@ -1,4 +1,6 @@ -function streamingRequest( +import { waitFor } from 'shared'; + +async function streamingRequest( request: Function, hasLoaded: Function, assetType: string, @@ -6,23 +8,17 @@ function streamingRequest( timeout?: number, ...args: any ): Promise { - return new Promise((resolve, reject) => { - if (hasLoaded(asset)) resolve(asset); + if (hasLoaded(asset)) return asset; - request(asset, ...args); + request(asset, ...args); - if (typeof timeout !== 'number') timeout = 500; - - let i = 0; - - setTick(() => { - if (hasLoaded(asset)) resolve(asset); - - i++; - - if (i === timeout) reject(`failed to load ${assetType} '${asset}' after ${timeout} ticks`); - }); - }); + waitFor( + () => { + if (hasLoaded(asset)) return asset; + }, + `failed to load ${assetType} '${asset}' after ${timeout} ticks`, + timeout || 500 + ); } export const requestAnimDict = (animDict: string, timeout?: number): Promise => { @@ -50,5 +46,18 @@ export const requestScaleformMovie = (scaleformName: string, timeout?: number): export const requestStreamedTextureDict = (textureDict: string, timeout?: number): Promise => streamingRequest(RequestStreamedTextureDict, HasStreamedTextureDictLoaded, 'textureDict', textureDict, timeout); -export const requestWeaponAsset = (weaponHash: string | number, timeout?: number, weaponResourceFlags: number = 31, extraWeaponComponentFlags: number = 0): Promise => - streamingRequest(RequestWeaponAsset, HasWeaponAssetLoaded, 'weaponHash', weaponHash, timeout, weaponResourceFlags, extraWeaponComponentFlags); +export const requestWeaponAsset = ( + weaponHash: string | number, + timeout?: number, + weaponResourceFlags: number = 31, + extraWeaponComponentFlags: number = 0 +): Promise => + streamingRequest( + RequestWeaponAsset, + HasWeaponAssetLoaded, + 'weaponHash', + weaponHash, + timeout, + weaponResourceFlags, + extraWeaponComponentFlags + ); diff --git a/package/shared/index.ts b/package/shared/index.ts index 16f2c12..74c7ab9 100644 --- a/package/shared/index.ts +++ b/package/shared/index.ts @@ -6,3 +6,35 @@ export type FlattenObjectKeys, Key = keyof T> ? `${Key}.${FlattenObjectKeys}` : `${Key}` : never; + +export function sleep(ms: number) { + return new Promise((resolve) => setTimeout(resolve, ms, null)); +} + +export async function waitFor(cb: () => T, errMessage: string | void, timeout = 1000): Promise { + let value = await cb(); + + if (value !== undefined) return value; + + if (IsDuplicityVersion()) timeout /= 50; + else timeout -= GetFrameTime() * 1000; + + const start = GetGameTimer(); + let id: number; + let i = 0; + + const p = new Promise((resolve, reject) => { + id = setTick(async () => { + i++; + + if (i > timeout) + return reject(`${errMessage || 'failed to resolve callback'} (waited ${(GetGameTimer() - start) / 1000}ms)`); + + value = await cb(); + + if (value !== undefined) resolve(value); + }); + }).finally(() => clearTick(id)); + + return p; +}