@woosh/meep-engine
Version:
Pure JavaScript game engine. Fully featured and production ready.
175 lines (145 loc) • 3.52 kB
JavaScript
import { assert } from "../assert.js";
import Signal from "../events/signal/Signal.js";
import { computeStringHash } from "../primitives/strings/computeStringHash.js";
/**
* Observable string container.
* Signals change via {@link onChanged}.
*
* @example
* const name = new ObservedString("Alice")
* name.onChanged((new_name, old_name) => console.log(`Name changed from ${old_name} to ${new_name}!`));
* ...
* name.set("Barbara"); // will print "Name changed from Alice to Barbara!" in console
* name.getValue() === "Barbara"
*
* @author Alex Goldring
* @copyright Company Named Limited (c) 2025
*/
class ObservedString extends String {
/**
*
* @param {string} [value=""]
*/
constructor(value = "") {
super();
assert.isString(value, 'value');
/**
*
* @type {string}
* @private
*/
this.__value = value;
/**
*
* @type {Signal<string,string>}
*/
this.onChanged = new Signal();
}
/**
*
* @returns {string}
*/
valueOf() {
return this.__value;
}
/**
*
* @returns {string}
*/
toString() {
return this.__value;
}
/**
*
* @param {string} value
* @returns {ObservedString}
*/
set(value) {
assert.isString(value, 'value');
const oldValue = this.__value;
if (oldValue !== value) {
this.__value = value;
this.onChanged.send2(value, oldValue);
}
return this;
}
/**
*
* @param {ObservedString} other
*/
copy(other) {
this.set(other.getValue());
}
/**
* @return {ObservedString}
*/
clone() {
const r = new this.constructor();
r.copy(this);
return r;
}
/**
*
* @returns {string}
*/
getValue() {
return this.__value;
}
/**
*
* @param {function(string,string)} f
* @param {*} [thisArg]
* @returns {this}
*/
process(f, thisArg) {
this.onChanged.add(f, thisArg);
const v = this.getValue();
f.call(thisArg, v, v);
return this;
}
/**
* @deprecated use {@link buffer.writeUTF8String} directly instead
* @param {BinaryBuffer} buffer
*/
toBinaryBuffer(buffer) {
buffer.writeUTF8String(this.__value);
}
/**
* @deprecated use {@link buffer.readUTF8String} directly instead
* @param {BinaryBuffer} buffer
*/
fromBinaryBuffer(buffer) {
const value = buffer.readUTF8String();
this.set(value);
}
/**
*
* @param {ObservedString} other
* @returns {boolean}
*/
equals(other) {
return this.__value === other.__value;
}
/**
*
* @return {number}
*/
hash() {
return computeStringHash(this.__value);
}
}
/**
* Used for optimized "instanceof" check
* @readonly
* @type {boolean}
*/
ObservedString.prototype.isObservedString = true;
/**
* @readonly
* @type {string}
*/
ObservedString.typeName = "ObservedString";
// JSON methods
ObservedString.prototype.toJSON = ObservedString.prototype.toString;
ObservedString.prototype.fromJSON = ObservedString.prototype.set;
export default ObservedString;