refactor: sound

This commit is contained in:
cha0s 2021-02-04 20:19:15 -06:00
parent c9b2988e1c
commit 22e8d7f45f
4 changed files with 63 additions and 16 deletions

View File

@ -238,6 +238,11 @@ export default (latus) => class Entity extends decorate(JsonResource) {
return Object.values(this.invokeHook(hook, ...args));
}
invokeHookReduced(hook, ...args) {
return this.invokeHookFlat(hook, ...args)
.reduce((r, result) => ({...r, ...result}), {});
}
is(type) {
return type in this.#traits;
}

View File

@ -0,0 +1,12 @@
/* eslint-disable class-methods-use-this */
export default class FakeAudio {
cloneNode() {
return this;
}
pause() {}
play() {}
}

View File

@ -1,6 +1,8 @@
import {JsonResource, Resource} from '@avocado/resource';
import LRU from 'lru-cache';
import FakeAudio from '../fake-audio';
const cache = new LRU({
dispose: ([url]) => URL.revokeObjectURL(url),
max: 32,
@ -23,12 +25,7 @@ export default () => class Sound extends JsonResource {
}
let promise;
if ('client' !== process.env.SIDE) {
promise = Promise.resolve([
'',
{
play: () => {},
},
]);
promise = Promise.resolve(['', new FakeAudio()]);
}
else {
promise = new Promise((resolve, reject) => {
@ -53,8 +50,14 @@ export default () => class Sound extends JsonResource {
[this.#objectUrl, this.#audio] = await promise;
}
pause() {
this.#audio.pause();
}
play() {
this.#audio.play();
const clone = this.#audio.cloneNode();
clone.volume = this.#audio.volume;
clone.play();
}
};

View File

@ -12,6 +12,25 @@ export default (latus) => class Audible extends Trait {
}
}
async addSounds(sounds) {
const {Sound} = latus.get('%resources');
return Object.fromEntries(
await Promise.all(
Object.entries(sounds).map(([key, sound]) => {
if (this.#sounds[key]) {
return undefined;
}
this.#sounds[key] = Sound.load(sound).then((sound) => {
this.#sounds[key] = sound;
return sound;
});
return [key, this.#sounds[key]];
})
.filter((entry) => !!entry),
),
);
}
cleanPackets() {
this.#playing = {};
}
@ -50,19 +69,25 @@ export default (latus) => class Audible extends Trait {
destroy() {
Object.values(this.#sounds).forEach((sound) => {
sound.destroy();
Promise.resolve(sound).then((sound) => {
sound.destroy();
});
});
}
async load(json) {
await super.load(json);
const {Sound} = latus.get('%resources');
this.#sounds = Object.fromEntries(
await Promise.all(
Object.entries(this.params.sounds)
.map(async ([key, sound]) => [key, await Sound.load(sound)]),
),
);
this.#sounds = await this.addSounds(this.params.sounds);
}
listeners() {
return {
traitAdded: () => {
this.addSounds(this.entity.invokeHookReduced('sounds'));
},
};
}
methods() {
@ -72,7 +97,9 @@ export default (latus) => class Audible extends Trait {
playSound: (key) => {
if (this.entity.hasSound(key)) {
this.#sounds[key].play();
Promise.resolve(this.#sounds[key]).then((sound) => {
sound.play();
});
if ('client' !== process.env.SIDE) {
this.#playing[key] = true;
}