-
-
Notifications
You must be signed in to change notification settings - Fork 183
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
130 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import type { UnresolvedAsset } from '../typedefs/UnresolvedAsset'; | ||
|
||
/** Retrieves the key from an unresolved asset. */ | ||
export function getAssetKey<T>(asset: UnresolvedAsset<T>) | ||
{ | ||
let assetKey; | ||
|
||
if (typeof asset === 'string') | ||
{ | ||
assetKey = asset; | ||
} | ||
else | ||
{ | ||
assetKey = (asset.alias ?? asset.src) as string; | ||
} | ||
|
||
return assetKey; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { | ||
Assets, | ||
Cache, | ||
} from 'pixi.js'; | ||
import { getAssetKey } from '../helpers/getAssetKey.ts'; | ||
|
||
import type { AssetRetryState } from '../typedefs/AssetRetryState.ts'; | ||
import type { UnresolvedAsset } from '../typedefs/UnresolvedAsset.ts'; | ||
import type { UseAssetsOptions } from '../typedefs/UseAssetsOptions.ts'; | ||
|
||
const errorCache: Map<UnresolvedAsset, AssetRetryState> = new Map(); | ||
|
||
/** Loads assets, returning a hash of assets once they're loaded. */ | ||
export function useAssets<T>( | ||
/** @description Assets to be loaded. */ | ||
assets: UnresolvedAsset<T>[], | ||
/** @description Asset options. */ | ||
options: UseAssetsOptions = {}, | ||
): T[] | ||
{ | ||
if (typeof window === 'undefined') | ||
{ | ||
throw Object.assign(Error('`useAsset` will only run on the client.'), { | ||
digest: 'BAILOUT_TO_CLIENT_SIDE_RENDERING', | ||
}); | ||
} | ||
|
||
const { | ||
maxRetries = 3, | ||
onError, | ||
onProgress, | ||
retryOnFailure = true, | ||
} = options; | ||
|
||
const allAssetsAreLoaded = assets.some((asset: UnresolvedAsset<T>) => Cache.has(getAssetKey(asset))); | ||
|
||
if (!allAssetsAreLoaded) | ||
{ | ||
let state = errorCache.get(assets); | ||
|
||
// Rethrow the cached error if we are not retrying on failure or have reached the max retries | ||
if (state && (!retryOnFailure || state.retries > maxRetries)) | ||
{ | ||
if (typeof onError === 'function') | ||
{ | ||
onError(state.error); | ||
} | ||
else | ||
{ | ||
throw state.error; | ||
} | ||
} | ||
|
||
throw Assets | ||
.load<T>(assets, (progressValue) => | ||
{ | ||
if (typeof onProgress === 'function') | ||
{ | ||
onProgress(progressValue); | ||
} | ||
}) | ||
.catch((error) => | ||
{ | ||
if (!state) | ||
{ | ||
state = { | ||
error, | ||
retries: 0, | ||
}; | ||
} | ||
|
||
errorCache.set(assets, { | ||
...state, | ||
error, | ||
retries: state.retries + 1, | ||
}); | ||
}); | ||
} | ||
|
||
const assetKeys = assets.map((asset: UnresolvedAsset<T>) => getAssetKey(asset)); | ||
const resolvedAssetsDictionary = Assets.get<T>(assetKeys) as Record<string, T>; | ||
|
||
return assets.map((_asset: UnresolvedAsset<T>, index: number) => resolvedAssetsDictionary[index]); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import type { UnresolvedAsset as PixiUnresolvedAsset } from 'pixi.js'; | ||
|
||
export type UnresolvedAsset<T = any> = PixiUnresolvedAsset<T> | string; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { type ErrorCallback } from './ErrorCallback.ts'; | ||
|
||
import type { ProgressCallback } from 'pixi.js'; | ||
|
||
export interface UseAssetsOptions | ||
{ | ||
/** @description The maximum number of retries allowed before we give up on loading this asset. */ | ||
maxRetries?: number | ||
|
||
/** @description A function to be called when if the asset loader encounters an error. */ | ||
onError?: ErrorCallback, | ||
|
||
/** @description A function to be called when the asset loader reports loading progress. */ | ||
onProgress?: ProgressCallback, | ||
|
||
/** @description Whether to try loading this asset again if it fails. */ | ||
retryOnFailure?: boolean | ||
} |