UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

106 lines (78 loc) 2.43 kB
import { assert } from "../../../../../core/assert.js"; import { array_push_if_unique } from "../../../../../core/collection/array/array_push_if_unique.js"; import { Codec } from "./Codec.js"; /** * Codec that tries to decode data with multiple codecs in order. * * @template T * @extends {Codec<T>} */ export class CodecWithFallback extends Codec { /** * * @type {Codec<T>[]} */ children = [] /** * * @param {Codec<T>} codecs */ constructor(...codecs) { super(); assert.isArray(codecs, 'codecs'); for (const codec of codecs) { this.#add(codec); } if (this.children.length < 1) { throw new Error('At least one codec must be provided'); } } /** * * @param {Codec<T>} codec */ #add(codec) { assert.defined(codec, 'codec'); assert.isObject(codec, 'codec'); assert.isInstanceOf(codec, Codec, 'codec', 'Codec'); return array_push_if_unique(this.children, codec); } async test(data) { const codecs = this.children; const codec_count = codecs.length; for (let i = 0; i < codec_count; i++) { const codec = codecs[i]; const codec_supports_data = await codec.test(data); if (codec_supports_data) { return true; } } return false; } async decode(data) { const codecs = this.children; const codec_count = codecs.length; const errors = []; let result; for (let i = 0; i < codec_count; i++) { const codec = codecs[i]; const codec_supports_data = await codec.test(data); if (!codec_supports_data) { errors.push({ index: i, error: "Codec doesn't support this data" }); continue; } try { result = await codec.decode(data); } catch (e) { errors.push({ index: i, error: e }); continue; } return result; } throw new Error(`All codecs failed, errors: ${errors.map(a => JSON.stringify(a)).join('\n')}`); } }