@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
113 lines (83 loc) • 3.26 kB
JavaScript
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;