UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

221 lines (190 loc) 4.79 kB
import Signal from "../events/signal/Signal.js"; import { inverseLerp } from "../math/inverseLerp.js"; import { computeHashFloat } from "../primitives/numbers/computeHashFloat.js"; class BoundedValue { /** * * @param {Number} currentValue * @param {Number} upperLimit * @param {Number} [lowerLimit=0] * @constructor */ constructor(currentValue, upperLimit, lowerLimit) { /** * @property {Number} * @private */ this.__value = currentValue !== undefined ? currentValue : 0; /** * @property {Number} * @private */ this.__limitUpper = upperLimit !== undefined ? upperLimit : 0; /** * @type {Number} * @private */ this.__limitLower = lowerLimit !== undefined ? lowerLimit : 0; this.onChanged = new Signal(); this.onOverflow = new Signal(); this.onFilled = new Signal(); this.on = { changed: this.onChanged, overflow: this.onOverflow }; } /** * * @param {Number} v */ setUpperLimit(v) { const oldValue = this.__limitUpper; if (v === oldValue) { //no change return; } this.__limitUpper = v; this.onChanged.send4(this.__value, this.__limitUpper, this.__value, oldValue); } /** * * @returns {Number} */ getUpperLimit() { return this.__limitUpper; } /** * * @returns {Number} */ getLowerLimit() { return this.__limitLower; } /** * * @param {Number} v */ setLowerLimit(v) { const old = this.__limitLower; if (v === old) { //no change return; } this.__limitLower = v; //TODO change signal signature to include lower limit this.onChanged.dispatch(); } /** * * @param {Number} v */ setValue(v) { const oldValue = this.__value; if (oldValue === v) { //no change return; } const spill = v - this.__limitUpper; this.__value = v; //dispatch change this.onChanged.send4(this.__value, this.__limitUpper, oldValue, this.__limitUpper); if (spill > 0) { this.onOverflow.send1(spill); } if (spill >= 0) { this.onFilled.send0(); } } /** * * @returns {Number} */ getValue() { return this.__value; } /** * * @returns {number} */ getFraction() { return inverseLerp(this.__limitLower, this.__limitUpper, this.__value); } /** * */ setValueToLimit() { this.setValue(this.__limitUpper); } /** * * @return {boolean} */ isValueAtLimit() { return this.__value === this.__limitUpper; } /** * * @param {Number} val */ addValue(val) { this.setValue(this.__value + val); } /** * * @param {BoundedValue} other * @returns {BoundedValue} */ copy(other) { this.setUpperLimit(other.getUpperLimit()); this.setValue(other.getValue()); return this; } /** * * @param {BoundedValue} other * @returns {boolean} */ equals(other) { return this.__value === other.__value && this.__limitLower === other.__limitLower && this.__limitUpper === other.__limitUpper; } /** * * @returns {number} */ hash() { const v0 = computeHashFloat(this.__value); const v1 = computeHashFloat(this.__limitLower); const v2 = computeHashFloat(this.__limitUpper); const h0 = (v0 << 5) - v0 + v1; return (h0 << 5) - h0 + v2; } toJSON() { return { value: this.__value, limit: this.__limitUpper }; } fromJSON(json) { this.setUpperLimit(json.limit); this.setValue(json.value); } /** * * @param {BinaryBuffer} buffer */ toBinaryBuffer(buffer) { buffer.writeFloat64(this.__value); buffer.writeFloat64(this.__limitUpper); } /** * * @param {BinaryBuffer} buffer */ fromBinaryBuffer(buffer) { const value = buffer.readFloat64(); const upperLimit = buffer.readFloat64(); this.setUpperLimit(upperLimit); this.setValue(value); } } export default BoundedValue;