UNPKG

playcanvas

Version:

Open-source WebGL/WebGPU 3D engine for the web

261 lines (260 loc) 11.6 kB
/** * Callback used by {@link ResourceHandler#load} when a resource is loaded (or an error occurs). */ export type ResourceHandlerCallback = (err: string | null, response?: any) => void; /** * The context describing the resource being loaded, passed to {@link ResourceParser#canParse}. */ export type ParserContext = { /** * - The original resource URL with any query string removed, or null. */ url: string | null; /** * - The lower-cased file extension without a leading dot (for example `'json'`), * or an empty string if there is none. */ ext: string; /** * - The lower-cased file name (for example `'lod-meta.json'`), or an empty * string. */ basename: string; /** * - The asset being loaded, if any. */ asset: Asset | undefined; /** * - The running {@link AppBase}. */ app: AppBase; }; /** * A parser used by a {@link ResourceHandler} to recognize and load a specific resource format. A parser * implements `canParse` (to claim a resource) and `load` (to fetch and produce it), and may implement * `open`. When registered with {@link ResourceHandler#addParser} the handler assigns itself to the * parser's `handler` property, so `load` can fetch the data via `this.handler.fetch(...)`. */ export type ResourceParser = { /** * - Returns true if this parser can handle the * described resource. Parsers are consulted newest-first; the first to return true is used. */ canParse: (context: ParserContext) => boolean; /** * - * Fetches (typically via `this.handler.fetch`) and produces the resource, then invokes the callback. */ load: (url: (string | { load: string; original: string; }), callback: ResourceHandlerCallback, asset?: Asset) => void; /** * - Optional. Called by the default * {@link ResourceHandler#open} when parsers are registered. Handlers that override `open` may call * it with an extended signature - for example the texture handler calls * `open(url, data, device, textureOptions)` on its parsers. */ open?: (url: string, data: any, asset?: Asset) => any; /** * - Assigned by the owning handler on registration; available in * `load`/`open` (for example `this.handler.fetch(...)`). */ handler?: ResourceHandler; }; /** * @import { AppBase } from '../app-base.js' * @import { AssetRegistry } from '../asset/asset-registry.js' */ /** * @callback ResourceHandlerCallback * Callback used by {@link ResourceHandler#load} when a resource is loaded (or an error occurs). * @param {string|null} err - The error message in the case where the load fails. * @param {any} [response] - The raw data that has been successfully loaded. * @returns {void} */ /** * The context describing the resource being loaded, passed to {@link ResourceParser#canParse}. * * @typedef {object} ParserContext * @property {string|null} url - The original resource URL with any query string removed, or null. * @property {string} ext - The lower-cased file extension without a leading dot (for example `'json'`), * or an empty string if there is none. * @property {string} basename - The lower-cased file name (for example `'lod-meta.json'`), or an empty * string. * @property {Asset|undefined} asset - The asset being loaded, if any. * @property {AppBase} app - The running {@link AppBase}. */ /** * A parser used by a {@link ResourceHandler} to recognize and load a specific resource format. A parser * implements `canParse` (to claim a resource) and `load` (to fetch and produce it), and may implement * `open`. When registered with {@link ResourceHandler#addParser} the handler assigns itself to the * parser's `handler` property, so `load` can fetch the data via `this.handler.fetch(...)`. * * @typedef {object} ResourceParser * @property {(context: ParserContext) => boolean} canParse - Returns true if this parser can handle the * described resource. Parsers are consulted newest-first; the first to return true is used. * @property {(url: (string | {load: string, original: string}), callback: ResourceHandlerCallback, asset?: Asset) => void} load - * Fetches (typically via `this.handler.fetch`) and produces the resource, then invokes the callback. * @property {(url: string, data: *, asset?: Asset) => *} [open] - Optional. Called by the default * {@link ResourceHandler#open} when parsers are registered. Handlers that override `open` may call * it with an extended signature - for example the texture handler calls * `open(url, data, device, textureOptions)` on its parsers. * @property {ResourceHandler} [handler] - Assigned by the owning handler on registration; available in * `load`/`open` (for example `this.handler.fetch(...)`). */ /** * Base class for ResourceHandlers used by {@link ResourceLoader}. A handler is a collection of * {@link ResourceParser}s for a single asset type; register parsers with {@link ResourceHandler#addParser} * and the base implementation selects the matching one to load and open the resource. A handler with a * single parser is the common (single-format) case. */ export class ResourceHandler { /** * @param {AppBase} app - The running {@link AppBase}. * @param {string} handlerType - The type of the resource the handler handles. */ constructor(app: AppBase, handlerType: string); /** * Type of the resource the handler handles. */ handlerType: string; /** * The running app instance. * * @type {AppBase} * @protected */ protected _app: AppBase; /** @private */ private _maxRetries; /** * The registered parsers, consulted newest-first during selection. * * @type {ResourceParser[]} * @ignore */ _parsers: ResourceParser[]; /** * Gets the running {@link AppBase} instance. * * @type {AppBase} */ get app(): AppBase; /** * Sets the number of times to retry a failed request for the resource. * * @type {number} */ set maxRetries(value: number); /** * Gets the number of times to retry a failed request for the resource. * * @type {number} */ get maxRetries(): number; /** * Registers a {@link ResourceParser} for this handler. Parsers are consulted newest-first: the most * recently added parser whose {@link ResourceParser#canParse} returns true is selected. This lets a * later registration override a built-in parser for the same format. * * Register parsers before starting loads for this handler's type - selection runs for both the * load and open phases, so changing the registry while loads are in flight can route them * inconsistently. Note that handlers that implement their own loading without consulting * registered parsers (for example cubemap or font) ignore registered parsers. * * @param {ResourceParser} parser - The parser to register. Must implement `canParse(context)`. * @param {*} [decider] - Removed. Previously a `(url, data) => boolean` selector; implement * `canParse(context)` on the parser instead. If passed, it is ignored and logs a warning. * @example * app.loader.getHandler('model').addParser(new ObjModelParser(app.graphicsDevice)); */ addParser(parser: ResourceParser, decider?: any): void; /** * Removes a previously registered {@link ResourceParser}. * * @param {ResourceParser} parser - The parser to remove. */ removeParser(parser: ResourceParser): void; /** * Gets a read-only copy of the registered parsers. * * @type {ResourceParser[]} */ get parsers(): ResourceParser[]; /** * Fetches a resource's raw data using this handler's retry settings, reusing pre-fetched * `asset.file.contents` when available. A convenience for a {@link ResourceParser}'s `load` method, * so parsers don't reimplement the fetch boilerplate. * * @param {string | {load: string, original: string}} url - The resource URL, or a load/original * structure. * @param {string} responseType - The {@link Http.ResponseType} to fetch as (for example * `Http.ResponseType.ARRAY_BUFFER` for a binary format, or `Http.ResponseType.TEXT`). * @param {ResourceHandlerCallback} callback - Called with `(err, data)` when the fetch completes. * @param {Asset} [asset] - The asset being loaded, used to reuse already-fetched contents. */ fetch(url: string | { load: string; original: string; }, responseType: string, callback: ResourceHandlerCallback, asset?: Asset): void; /** * Builds the {@link ParserContext} used for parser selection. * * @param {string | {load: string, original: string} | null} url - The URL, a load/original * structure, or null. * @param {Asset} [asset] - The asset being loaded, if any. * @returns {ParserContext} The parser context. * @ignore */ _makeContext(url: string | { load: string; original: string; } | null, asset?: Asset): ParserContext; /** * Selects a parser for the given context, consulting registered parsers newest-first. * * @param {ParserContext} context - The context built by {@link ResourceHandler#_makeContext}. * @returns {ResourceParser|null} The first parser whose `canParse` returns true, or null. * @ignore */ _selectParser(context: ParserContext): ResourceParser | null; /** * Load a resource from a remote URL. When parsers are registered, the matching parser's `load` is * used; otherwise the base implementation does nothing (subclasses may override). * * @param {string | {load: string, original: string}} url - Either the URL of the resource to * load or a structure containing the load URL (used for loading the resource) and the original * URL (used for identifying the resource format; necessary when loading, for example, from * a blob URL). * @param {ResourceHandlerCallback} callback - The callback used when the resource is loaded or * an error occurs. * @param {Asset} [asset] - Optional asset that is passed by ResourceLoader. */ load(url: string | { load: string; original: string; }, callback: ResourceHandlerCallback, asset?: Asset): void; /** * The open function is passed the raw resource data. The handler can then process the data * into a format that can be used at runtime. When parsers are registered, the matching parser's * `open` is used (if it implements one); otherwise the base implementation simply returns the data. * * @param {string} url - The URL of the resource to open. * @param {*} data - The raw resource data passed by callback from {@link load}. * @param {Asset} [asset] - Optional asset that is passed by ResourceLoader. * @returns {*} The parsed resource data. */ open(url: string, data: any, asset?: Asset): any; /** * The patch function performs any operations on a resource that requires a dependency on its * asset data or any other asset data. The base implementation does nothing. * * @param {Asset} asset - The asset to patch. * @param {AssetRegistry} assets - The asset registry. */ patch(asset: Asset, assets: AssetRegistry): void; } import { Asset } from '../asset/asset.js'; import type { AppBase } from '../app-base.js'; import type { AssetRegistry } from '../asset/asset-registry.js';