UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

157 lines (126 loc) 3.09 kB
import List from "./List.js"; /** * @template T */ export class ListForwarder { /** * Where the data ends up * @type {List<T>} * @private */ #destination = new List(); /** * Where to take data from * @type {List<T>[]} * @private */ #sources = []; /** * * @type {boolean} * @private */ #is_linked = false; /** * * @param {List<T>} v */ set destination(v) { if (this.#is_linked) { // already linked throw new Error('Invalid state: linked'); } this.#destination = v; } /** * * @return {List<T>} */ get destination() { return this.#destination; } /** * * @param {List<T>} source * @return {boolean} */ add(source) { this.#sources.push(source); if (this.#is_linked) { this.#link_one(source); } return true; } /** * * @param {List<T>} source * @private */ #link_one(source) { source.on.added.add(this.#destination.add, this.#destination); source.on.removed.add(this.#destination.removeOneOf, this.#destination); // move data to destination source.forEach(this.#destination.add, this.#destination); } /** * * @param {List<T>} source * @private */ #unlink_one(source) { source.on.added.remove(this.#destination.add, this.#destination); source.on.removed.remove(this.#destination.removeOneOf, this.#destination); // remove all data from destination source.forEach(this.#destination.removeOneOf, this.#destination); } /** * * @param {List<T>} source * @return {boolean} */ remove(source) { const i = this.#sources.indexOf(source); if (i === -1) { return false; } if (this.#is_linked) { this.#unlink_one(source); } this.#sources.splice(i, 1); return true; } link() { if (this.#is_linked) { return; } if (this.#destination === null) { throw new Error('Illegal state: destination not set'); } this.#is_linked = true; const sources = this.#sources; const n = sources.length; for (let i = 0; i < n; i++) { const source = sources[i]; this.#link_one(source); } } unlink() { if (!this.#is_linked) { return; } this.#is_linked = false; const sources = this.#sources; const n = sources.length; for (let i = 0; i < n; i++) { const source = sources[i]; this.#unlink_one(source); } } /** * * @return {boolean} */ isLinked() { return this.#is_linked; } }