UNPKG

sound-manager

Version:
223 lines (180 loc) 5.34 kB
import { assert, assertValid, } from 'ts-assertions'; import { getFrozenObject, } from '../functions/getFrozenObject'; import { IGroup, } from './IGroup'; import { IGroupOptions, } from './IGroupOptions'; import { ISound, } from '../Sound/ISound'; import { ISoundsMap, } from './ISoundsMap'; import { isValidVolume, } from '../functions/isValidVolume'; import { BaseNode, } from '../Node/BaseNode'; import { NodeTypes, } from '../enums/NodeTypes'; import { PanelRegisterableNodeMixin, } from '../Node/PanelRegisterableNodeMixin'; import { TaggableNodeMixin, } from '../Node/TaggableNodeMixin'; export class Group extends PanelRegisterableNodeMixin( TaggableNodeMixin( BaseNode )) implements IGroup { get type(): NodeTypes.Group { return NodeTypes.Group; } private __sounds: ISoundsMap = getFrozenObject(); get sounds() { return this.__sounds; } constructor(options: IGroupOptions) { super({ ...options }); const { sounds, tags, volume, } = options; if (sounds && typeof sounds === 'object') { this.addSounds(sounds); } if (tags) { tags.forEach(this.addTag); } if (isValidVolume(volume)) { this.setVolume(volume); } } public readonly setVolume = (value: number) => { super.setVolume(value); this.updateAllAudioElementsVolume(); return this; }; public readonly hasSound = (name: string) => ( name in this.sounds ); public readonly hasSounds = (names: string[]) => ( !names.find((name) => !this.hasSound(name)) ); public readonly getSound = (name: string) => assertValid<ISound>( this.sounds[name], ); public readonly getSounds = (names: string[]) => ( assert(Array.isArray(names)) && names.map((name) => this.getSound(name)) ); public readonly getAllSounds = () => ( this.getSounds(Object.keys(this.sounds)) ); public readonly getSoundsByTag = (tag: string) => ( this.getAllSounds().filter((sound) => sound.hasTag(tag)) ); public readonly getSoundsByTags = ( tags: string[], matchOneOrAll: 'one' | 'all' = 'one', ) => this.getAllSounds().filter((sound) => ( matchOneOrAll === 'all' ? tags.filter(sound.hasTag).length === tags.length : tags.filter(sound.hasTag).length >= 1 )); private readonly __registeredAdditionIntents: Record<string, boolean> = {}; public readonly registerIntentToAddSound = (name: string) => { assert(!(name in this.__registeredAdditionIntents)); this.__registeredAdditionIntents[name] = true; return this; }; public readonly deregisterIntentToAddSound = (name: string) => ( void delete this.__registeredAdditionIntents[name] ); public readonly hasIntentToAddSound = (name: string) => ( name in this.__registeredAdditionIntents ); public readonly addSound = (name: string, sound: ISound) => ( this.addSounds({ [name]: sound }) ); public readonly addSounds = (sounds: ISoundsMap) => { const names = Object.keys(sounds); const volumeGetter = () => this.getVolume(); names.forEach((soundName) => { assert(soundName) assert(!(soundName in this.sounds)); assert(sounds[soundName]); const sound = sounds[soundName]; sound.getGroupVolume = volumeGetter; }); this.__sounds = getFrozenObject(this.sounds, sounds); return this; }; public readonly removeSound = (name: string) => { this.removeSounds([ name ]); return this; }; public readonly removeSounds = (names: string[]) => { assert(Array.isArray(names)); const sounds = { ...this.sounds, }; names.forEach((soundName: string) => { delete sounds[soundName]; }); this.__sounds = getFrozenObject(sounds); return this; }; public readonly removeAllSounds = () => ( this.removeSounds(Object.keys(this.sounds)) ); public readonly playSound = (name: string) => this.getSound(name).play(); public readonly playSounds = (names: string[]) => { assert(Array.isArray(names)); return Promise.all(names.map((name) => this.playSound(name))); }; public readonly playAllSounds = () => ( this.playSounds(Object.keys(this.sounds)) ); public readonly pauseSound = (name: string) => { this.getSound(name).pause(); return this; }; public readonly pauseSounds = (names: string[]) => { assert(Array.isArray(names)); names.map((name) => this.pauseSound(name)); return this; }; public readonly pauseAllSounds = () => ( this.pauseSounds(Object.keys(this.sounds)) ); public readonly stopSound = (name: string) => { this.getSound(name).stop(); return this; }; public readonly stopSounds = (names: string[]) => { assert(Array.isArray(names)); names.map((name) => this.stopSound(name)); return this; }; public readonly stopAllSounds = () => ( this.stopSounds(Object.keys(this.sounds)) ); public readonly updateAllAudioElementsVolume = () => { this.getAllSounds().forEach((sound) => { sound.updateAudioElementVolume(); }); return this; }; }