UNPKG

@babylonjs/core

Version:

Getting started? Play directly with the Babylon.js API using our [playground](https://playground.babylonjs.com/). It also contains a lot of samples to learn how to use it.

127 lines 4.45 kB
/** * Adds common sub graph functionality to an audio node. * * Audio nodes such as static sounds, streaming sounds, and buses can use audio sub graphs to process audio internally * before sending it to connected downstream audio nodes. This is useful for applying effects, spatial audio, and other * audio processing tasks common to multiple audio node classes. * * A key feature of audio sub graphs is their audio sub nodes are created asynchronously on demand so the minimum set * of sub nodes are used at all times to save memory and CPU resources. The tradeoff is a small delay when first * setting a property backed by a sub node. This delay is avoided by using the appropriate options to initialize the * sub node on creation, e.g. `spatialEnabled` and `stereoEnabled`, or by setting any creation option backed by the * sub node, e.g. `spatialPosition` and `stereoPan`. * * @internal */ export class _AbstractAudioSubGraph { constructor() { this._createSubNodePromises = {}; this._isDisposed = false; this._subNodes = {}; this._onSubNodeDisposed = (node) => { const subNode = node; delete this._subNodes[subNode.name]; this._onSubNodesChanged(); }; } /** * Executes the given callback with the named sub node, creating the sub node if needed. * * @param name The name of the sub node * @param callback The function to call with the named sub node * * @internal */ callOnSubNode(name, callback) { const node = this.getSubNode(name); if (node) { callback(node); return; } // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then this._createSubNodePromisesResolvedAsync().then(() => { const node = this.getSubNode(name); if (node) { callback(node); return; } // eslint-disable-next-line @typescript-eslint/no-floating-promises, github/no-then this.createAndAddSubNodeAsync(name).then((node) => { callback(node); }); }); } /** * Creates the named subnode and adds it to the sub graph. * * @param name The name of the sub node. * @returns A promise that resolves to the created sub node. * * @internal */ // eslint-disable-next-line @typescript-eslint/promise-function-async, no-restricted-syntax createAndAddSubNodeAsync(name) { var _a; // eslint-disable-next-line github/no-then (_a = this._createSubNodePromises)[name] || (_a[name] = this._createSubNode(name).then((node) => { this._addSubNode(node); return node; })); return this._createSubNodePromises[name]; } /** * Releases associated resources. * * @internal */ dispose() { this._isDisposed = true; const subNodes = Object.values(this._subNodes); for (const subNode of subNodes) { subNode.dispose(); } this._subNodes = {}; this._createSubNodePromises = {}; } /** * Gets a previously created sub node. * * @param name - The name of the sub node * @returns The named sub node, or `null` if it has not been created, yet * * @internal * */ getSubNode(name) { return this._subNodes[name] ?? null; } /** * Removes a sub node from the sub graph. * * @param subNode - The sub node to remove * @returns A promise that resolves when the sub node is removed * * @internal */ async removeSubNodeAsync(subNode) { await this._createSubNodePromisesResolvedAsync(); const name = subNode.name; if (this._subNodes[name]) { delete this._subNodes[name]; } delete this._createSubNodePromises[name]; this._onSubNodesChanged(); } async _createSubNodePromisesResolvedAsync() { return await Promise.all(Object.values(this._createSubNodePromises)); } _addSubNode(node) { if (this._isDisposed) { node.dispose(); return; } this._subNodes[node.name] = node; node.onDisposeObservable.addOnce(this._onSubNodeDisposed); this._onSubNodesChanged(); } } //# sourceMappingURL=abstractAudioSubGraph.js.map