UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

113 lines (83 loc) 3.26 kB
import { ResourceAccessKind } from "../../../core/model/ResourceAccessKind.js"; import { ResourceAccessSpecification } from "../../../core/model/ResourceAccessSpecification.js"; import { System } from '../../ecs/System.js'; import { SoundEmitter } from './emitter/SoundEmitter.js'; import { SoundTrack } from "./emitter/SoundTrack.js"; import SoundController from './SoundController.js'; /** * * @param {Rule} rule * @returns {string} */ function pickTackFromRule(rule) { const randomNumber = Math.random(); const tracks = rule.tracks; const numTracks = tracks.length; const index = Math.floor(randomNumber * numTracks); return tracks[index]; } class SoundControllerSystem extends System { constructor() { super(); this.dependencies = [SoundController]; this.components_used = [ ResourceAccessSpecification.from(SoundEmitter, ResourceAccessKind.Write) ]; this.removers = []; } /** * * @param {SoundController} component * @param {number} entity */ link(component, entity) { const em = this.entityManager; const dataset = em.dataset; const callbacks = this.removers[entity] = []; /** * * @param {SoundController.Rule} rule */ function registerRule(rule) { function startEventHandler() { const emitter = dataset.getComponent(entity, SoundEmitter); if (emitter === undefined) { //do nothing? console.error("Entity " + entity + " has no SoundEmitter to control"); } const track = new SoundTrack(); const url = pickTackFromRule(rule); track.fromJSON({ url, loop: rule.loop, volume: rule.volume, channel: rule.channel }); emitter.tracks.add(track); } function stopEventHandler() { const emitter = dataset.getComponent(entity, SoundEmitter); emitter.tracks.removeOneIf(function (t) { return rule.tracks.indexOf(t.url) !== -1; }); } if (typeof rule.stopEvent === "string") { dataset.addEntityEventListener(entity, rule.stopEvent, stopEventHandler); callbacks.push({ name: rule.stopEvent, handler: stopEventHandler }); } dataset.addEntityEventListener(entity, rule.startEvent, startEventHandler); callbacks.push({ name: rule.startEvent, handler: startEventHandler }); } component.rules.forEach(registerRule); } unlink(component, entity) { const callbacks = this.removers[entity]; delete this.removers[entity]; const em = this.entityManager; const dataset = em.dataset; callbacks.forEach(function (cb) { dataset.removeEntityEventListener(entity, cb.name, cb.handler); }); } } export default SoundControllerSystem;