UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

147 lines (125 loc) 2.95 kB
import { assert } from "../assert.js"; import Signal from "../events/signal/Signal.js"; /** * Enumerable value abstraction. Think `enum` keyword in TypeScript or any other programming language. * Given a set of valid values, holds one of such values. * This is an observable value, meaning you can subscribe to be notified of changes via {@link onChanged} signal. * * @example * const v = new ObservedEnum(7, { * ONE: 1, * SEVEN: 7 * }); * * v.getValue(); // 7 * * v.set(1); * * v.getValue(); // 1 * * v.set(2); // will throw error, as 2 is not a valid enum value */ class ObservedEnum { /** * @template T * @param {T} value * @param {Object.<string,T>} validSet */ constructor(value, validSet) { assert.isObject(validSet, "validSet"); assert.enum(value, validSet, "value"); /** * * @type {T} * @private */ this.__value = value; /** * * @type {Object<string, T>} * @private */ this.__validSet = validSet; /** * @readonly * @type {Signal<T,T>} */ this.onChanged = new Signal(); } /** * Do not modify result * @returns {Object<string, T>} */ getValidValueSet() { return this.__validSet; } /** * * @param {T} value * @returns {ObservedEnum} */ set(value) { assert.enum(value, this.__validSet, "value") const oldValue = this.__value; if (oldValue !== value) { this.__value = value; this.onChanged.dispatch(value, oldValue); } return this; } /** * @template T * @param {ObservedEnum<T>} other * @returns {boolean} */ equals(other) { return this.__value === other.__value; } /** * * @return {number} */ hash() { let hash = 0; for (const n of this.__validSet) { if(this.__validSet[n] === this.__value) { break; } hash++; } return hash; } /** * * @param {ObservedEnum} other */ copy(other) { this.set(other.getValue()); } /** * * @returns {T} */ getValue() { return this.__value; } /** * * @param {function(T,T)} processor * @param {*} [thisArg] * @returns {this} */ process(processor, thisArg) { this.onChanged.add(processor, thisArg); const v = this.__value; processor.call(thisArg, v, v); return this; } toJSON() { return this.__value; } fromJSON(obj) { this.set(obj); } } export default ObservedEnum;