@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
221 lines (190 loc) • 4.79 kB
JavaScript
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;