@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
96 lines (87 loc) • 2.58 kB
text/typescript
import type {Constructor} from '../../../../../types/GlobalTypes';
import type {BaseNodeType} from '../../../_Base';
import {ParamConfig} from '../../../utils/params/ParamsConfig';
import type {RootManagerNode} from '../../Root';
import {isBooleanTrue} from '../../../../../core/Type';
import type {AudioListenerObjNode} from '../../../obj/AudioListener';
const CallbackOptions = {
computeOnDirty: false,
callback: (node: BaseNodeType) => {
RootAudioController.update(node as RootManagerNode);
},
};
export function RootAudioParamConfig<TBase extends Constructor>(Base: TBase) {
return class Mixin extends Base {
// audio
/** @param set if a audio icon is shown in the viewer to toggle sound on/off */
displayAudioIcon = ParamConfig.BOOLEAN(0, {
...CallbackOptions,
separatorBefore: true,
});
/** @param icon color */
audioIconColor = ParamConfig.COLOR([0, 0, 0], {
...CallbackOptions,
visibleIf: {displayAudioIcon: 1},
});
/** @param icon style properties */
audioIconStyle = ParamConfig.STRING(
'position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; cursor: pointer',
{
...CallbackOptions,
visibleIf: {displayAudioIcon: 1},
}
);
};
}
type onToggleSoundCallback = (soundOn: boolean) => void;
export class RootAudioController {
constructor(protected node: RootManagerNode) {}
async toggleSound() {
this.audioListeners().forEach((node) => {
node.toggleSound();
});
this.update();
this._runOnToggleSoundCallbacks();
}
soundOn() {
const listener = this.audioListeners()[0];
if (listener) {
return isBooleanTrue(listener.pv.soundOn) || false;
} else {
return false;
}
}
update() {
this._updateViewers();
}
audioListeners(): AudioListenerObjNode[] {
return this.node.nodesByType('audioListener') as AudioListenerObjNode[];
}
private _updateViewers() {
this.node.scene().viewersRegister.traverseViewers((viewer) => {
viewer.audioController().update();
});
}
static update(node: RootManagerNode) {
node.audioController.update();
}
/*
*
* CALLBACKS
*
*/
private _callbacksByName = new Map<string, onToggleSoundCallback>();
onToggleSound(callbackName: string, callback: onToggleSoundCallback) {
if (this._callbacksByName.get(callbackName)) {
console.warn(`callback already registered ith name '${callbackName}'`);
return;
}
this._callbacksByName.set(callbackName, callback);
}
private _runOnToggleSoundCallbacks() {
const soundOn = this.soundOn();
this._callbacksByName.forEach((callback) => {
callback(soundOn);
});
}
}