pixi.js
Version:
<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">
1 lines • 22.8 kB
Source Map (JSON)
{"version":3,"file":"Loader.mjs","sources":["../../../src/assets/loader/Loader.ts"],"sourcesContent":["import { warn } from '../../utils/logging/warn';\nimport { path } from '../../utils/path';\nimport { type ProgressCallback } from '../Assets';\nimport { convertToList } from '../utils/convertToList';\nimport { isSingleItem } from '../utils/isSingleItem';\n\nimport type { ResolvedAsset } from '../types';\nimport type { LoaderParser } from './parsers/LoaderParser';\nimport type { PromiseAndParser } from './types';\n\n/**\n * Options for loading assets with the Loader\n * @example\n * ```ts\n * await Assets.load(['file1.png', 'file2.png'], {\n * onProgress: (progress) => console.log(`Progress: ${progress * 100}%`),\n * onError: (error, url) => console.error(`Error loading ${url}: ${error.message}`),\n * strategy: 'retry', // 'throw' | 'skip' | 'retry'\n * retryCount: 5, // Number of retry attempts if strategy is 'retry'\n * retryDelay: 500, // Delay in ms between retries\n * });\n * ```\n * @category assets\n * @standard\n */\nexport interface LoadOptions\n{\n /**\n * Callback for progress updates during loading\n * @param progress - A number between 0 and 1 indicating the load progress\n * @example\n * ```ts\n * const options: LoadOptions = {\n * onProgress: (progress) => {\n * console.log(`Loading progress: ${progress * 100}%`);\n * },\n * };\n * await Assets.load('image.png', options);\n * ```\n */\n onProgress?: (progress: number) => void;\n /**\n * Callback for handling errors during loading\n * @param error - The error that occurred\n * @param url - The URL of the asset that failed to load\n * @example\n * ```ts\n * const options: LoadOptions = {\n * onError: (error, url) => {\n * console.error(`Failed to load ${url}: ${error.message}`);\n * },\n * };\n * await Assets.load('missing-file.png', options);\n * ```\n */\n onError?: (error: Error, url: string | ResolvedAsset) => void;\n /**\n * Strategy to handle load failures\n * - 'throw': Immediately throw an error and stop loading (default)\n * - 'skip': Skip the failed asset and continue loading others\n * - 'retry': Retry loading the asset a specified number of times\n * @default 'throw'\n * @example\n * ```ts\n * const options: LoadOptions = {\n * strategy: 'skip',\n * };\n * await Assets.load('sometimes-fails.png', options);\n * ```\n */\n strategy?: 'throw' | 'skip' | 'retry';\n /**\n * Number of retry attempts if strategy is 'retry'\n * @default 3\n * @example\n * ```ts\n * const options: LoadOptions = {\n * strategy: 'retry',\n * retryCount: 5, // Retry up to 5 times\n * };\n * await Assets.load('unstable-asset.png', options);\n * ```\n */\n retryCount?: number;\n /**\n * Delay in milliseconds between retry attempts\n * @default 250\n * @example\n * ```ts\n * const options: LoadOptions = {\n * strategy: 'retry',\n * retryDelay: 1000, // Wait 1 second between retries\n * };\n * await Assets.load('sometimes-fails.png', options);\n * ```\n */\n retryDelay?: number;\n}\n\n/**\n * The Loader is responsible for loading all assets, such as images, spritesheets, audio files, etc.\n * It does not do anything clever with URLs - it just loads stuff!\n * Behind the scenes all things are cached using promises. This means it's impossible to load an asset more than once.\n * Through the use of LoaderParsers, the loader can understand how to load any kind of file!\n *\n * It is not intended that this class is created by developers - its part of the Asset class\n * This is the second major system of PixiJS' main Assets class\n * @category assets\n * @advanced\n */\nexport class Loader\n{\n /**\n * Default options for loading assets\n * @example\n * ```ts\n * // Change default load options globally\n * Loader.defaultOptions = {\n * strategy: 'skip', // Change default strategy to 'skip'\n * retryCount: 5, // Change default retry count to 5\n * retryDelay: 500, // Change default retry delay to 500ms\n * };\n * ```\n */\n public static defaultOptions: LoadOptions = {\n onProgress: undefined,\n onError: undefined,\n strategy: 'throw',\n retryCount: 3,\n retryDelay: 250,\n };\n /**\n * Options for loading assets with the loader.\n * These options will be used as defaults for all load calls made with this loader instance.\n * They can be overridden by passing options directly to the load method.\n * @example\n * ```ts\n * // Create a loader with custom default options\n * const loader = new Loader();\n * loader.loadOptions = {\n * strategy: 'skip', // Default strategy to 'skip'\n * retryCount: 5, // Default retry count to 5\n * retryDelay: 500, // Default retry delay to 500ms\n * };\n *\n * // This load call will use the loader's default options\n * await loader.load('image1.png');\n */\n public loadOptions: LoadOptions = { ...Loader.defaultOptions };\n private readonly _parsers: LoaderParser[] = [];\n private _parserHash: Record<string, LoaderParser>;\n\n private _parsersValidated = false;\n\n /**\n * All loader parsers registered\n * @type {assets.LoaderParser[]}\n */\n public parsers = new Proxy(this._parsers, {\n set: (target, key, value) =>\n {\n this._parsersValidated = false;\n\n target[key as any as number] = value;\n\n return true;\n }\n });\n\n /** Cache loading promises that ae currently active */\n public promiseCache: Record<string, PromiseAndParser> = {};\n\n /** function used for testing */\n public reset(): void\n {\n this._parsersValidated = false;\n this.promiseCache = {};\n }\n\n /**\n * Used internally to generate a promise for the asset to be loaded.\n * @param url - The URL to be loaded\n * @param data - any custom additional information relevant to the asset being loaded\n * @returns - a promise that will resolve to an Asset for example a Texture of a JSON object\n */\n private _getLoadPromiseAndParser(url: string, data?: ResolvedAsset): PromiseAndParser\n {\n const result: PromiseAndParser = {\n promise: null,\n parser: null\n };\n\n result.promise = (async () =>\n {\n let asset = null;\n\n let parser: LoaderParser = null;\n\n // first check to see if the user has specified a parser\n if (data.parser || data.loadParser)\n {\n // they have? lovely, lets use it\n parser = this._parserHash[data.parser || data.loadParser];\n\n // #if _DEBUG\n if (data.loadParser)\n {\n warn(\n `[Assets] \"loadParser\" is deprecated, use \"parser\" instead for ${url}`\n );\n }\n // #endif\n\n if (!parser)\n {\n // #if _DEBUG\n warn(\n `[Assets] specified load parser \"${data.parser || data.loadParser}\" not found while loading ${url}`\n );\n // #endif\n }\n }\n\n // no parser specified, so lets try and find one using the tests\n if (!parser)\n {\n for (let i = 0; i < this.parsers.length; i++)\n {\n const parserX = this.parsers[i];\n\n if (parserX.load && parserX.test?.(url, data, this))\n {\n parser = parserX;\n break;\n }\n }\n\n if (!parser)\n {\n // #if _DEBUG\n // eslint-disable-next-line max-len\n warn(`[Assets] ${url} could not be loaded as we don't know how to parse it, ensure the correct parser has been added`);\n // #endif\n\n return null;\n }\n }\n\n asset = await parser.load(url, data, this);\n result.parser = parser;\n\n for (let i = 0; i < this.parsers.length; i++)\n {\n const parser = this.parsers[i];\n\n if (parser.parse)\n {\n if (parser.parse && await parser.testParse?.(asset, data, this))\n {\n // transform the asset..\n asset = await parser.parse(asset, data, this) || asset;\n\n result.parser = parser;\n }\n }\n }\n\n return asset;\n })();\n\n return result;\n }\n\n /**\n * Loads one or more assets using the parsers added to the Loader.\n * @example\n * // Single asset:\n * const asset = await Loader.load('cool.png');\n * console.log(asset);\n *\n * // Multiple assets:\n * const assets = await Loader.load(['cool.png', 'cooler.png']);\n * console.log(assets);\n * @param assetsToLoadIn - urls that you want to load, or a single one!\n * @param onProgress - For multiple asset loading only, an optional function that is called\n * when progress on asset loading is made. The function is passed a single parameter, `progress`,\n * which represents the percentage (0.0 - 1.0) of the assets loaded. Do not use this function\n * to detect when assets are complete and available, instead use the Promise returned by this function.\n */\n public async load<T = any>(\n assetsToLoadIn: string | ResolvedAsset,\n onProgress?: ProgressCallback | LoadOptions,\n ): Promise<T>;\n public async load<T = any>(\n assetsToLoadIn: string[] | ResolvedAsset[],\n onProgress?: ProgressCallback | LoadOptions,\n ): Promise<Record<string, T>>;\n public async load<T = any>(\n assetsToLoadIn: string | string[] | ResolvedAsset | ResolvedAsset[],\n onProgressOrOptions?: ProgressCallback | LoadOptions,\n ): Promise<T | Record<string, T>>\n {\n if (!this._parsersValidated)\n {\n this._validateParsers();\n }\n\n const options: LoadOptions = typeof onProgressOrOptions === 'function'\n ? { ...Loader.defaultOptions, ...this.loadOptions, onProgress: onProgressOrOptions }\n : { ...Loader.defaultOptions, ...this.loadOptions, ...(onProgressOrOptions || {}) };\n const { onProgress, onError, strategy, retryCount, retryDelay } = options;\n\n let count = 0;\n\n const assets: Record<string, T> = {};\n\n const singleAsset = isSingleItem(assetsToLoadIn);\n\n const assetsToLoad = convertToList<ResolvedAsset>(assetsToLoadIn, (item) => ({\n alias: [item],\n src: item,\n data: {}\n }));\n\n const total = assetsToLoad.reduce((sum, asset) => sum + (asset.progressSize || 1), 0);\n\n const promises: Promise<void>[] = assetsToLoad.map(async (asset: ResolvedAsset) =>\n {\n const url = path.toAbsolute(asset.src);\n\n if (assets[asset.src]) return;\n\n await this._loadAssetWithRetry(url, asset, { onProgress, onError, strategy, retryCount, retryDelay }, assets);\n\n count += (asset.progressSize || 1);\n if (onProgress) onProgress(count / total);\n });\n\n await Promise.all(promises);\n\n return singleAsset ? assets[assetsToLoad[0].src] : assets;\n }\n\n /**\n * Unloads one or more assets. Any unloaded assets will be destroyed, freeing up memory for your app.\n * The parser that created the asset, will be the one that unloads it.\n * @example\n * // Single asset:\n * const asset = await Loader.load('cool.png');\n *\n * await Loader.unload('cool.png');\n *\n * console.log(asset.destroyed); // true\n * @param assetsToUnloadIn - urls that you want to unload, or a single one!\n */\n public async unload(\n assetsToUnloadIn: string | string[] | ResolvedAsset | ResolvedAsset[],\n ): Promise<void>\n {\n const assetsToUnload = convertToList<ResolvedAsset>(assetsToUnloadIn, (item) => ({\n alias: [item],\n src: item,\n }));\n\n const promises: Promise<void>[] = assetsToUnload.map(async (asset: ResolvedAsset) =>\n {\n const url = path.toAbsolute(asset.src);\n\n const loadPromise = this.promiseCache[url];\n\n if (loadPromise)\n {\n const loadedAsset = await loadPromise.promise;\n\n delete this.promiseCache[url];\n\n await loadPromise.parser?.unload?.(loadedAsset, asset, this);\n }\n });\n\n await Promise.all(promises);\n }\n\n /** validates our parsers, right now it only checks for name conflicts but we can add more here as required! */\n private _validateParsers()\n {\n this._parsersValidated = true;\n\n this._parserHash = this._parsers\n .filter((parser) => parser.name || parser.id)\n .reduce((hash, parser) =>\n {\n if (!parser.name && !parser.id)\n {\n // #if _DEBUG\n warn(`[Assets] parser should have an id`);\n // #endif\n }\n else if (hash[parser.name] || hash[parser.id])\n {\n // #if _DEBUG\n warn(`[Assets] parser id conflict \"${parser.id}\"`);\n // #endif\n }\n\n // add both name and id to the hash\n hash[parser.name] = parser;\n if (parser.id) hash[parser.id] = parser;\n\n return hash;\n }, {} as Record<string, LoaderParser>);\n }\n\n private async _loadAssetWithRetry<T>(\n url: string,\n asset: ResolvedAsset,\n options: LoadOptions,\n assets: Record<string, T>\n )\n {\n let attempt = 0;\n const { onError, strategy, retryCount, retryDelay } = options;\n const wait = (ms: number) => new Promise((r) => setTimeout(r, ms));\n\n while (true)\n {\n try\n {\n if (!this.promiseCache[url])\n {\n this.promiseCache[url] = this._getLoadPromiseAndParser(url, asset);\n }\n\n assets[asset.src] = await this.promiseCache[url].promise as T;\n\n return;\n }\n catch (e)\n {\n // clear cache for a new attempt\n delete this.promiseCache[url];\n delete assets[asset.src];\n\n attempt++;\n\n const isLast = strategy !== 'retry' || attempt > retryCount;\n\n if (strategy === 'retry' && !isLast)\n {\n if (onError) onError(e as Error, asset);\n await wait(retryDelay);\n continue;\n }\n\n if (strategy === 'skip')\n {\n if (onError) onError(e as Error, asset);\n\n return;\n }\n\n // strategy 'throw' or exhausted 'retry'\n if (onError) onError(e as Error, asset);\n const error = new Error(`[Loader.load] Failed to load ${url}.\\n${e}`);\n\n if (e instanceof Error && e.stack)\n {\n error.stack = e.stack;\n }\n throw error;\n }\n }\n }\n}\n"],"names":["parser"],"mappings":"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"}