multyx-client
Version:
Framework designed to simplify the creation of multiplayer browser games by addressing the complexities of managing server-client communication, shared state, and input handling
100 lines (99 loc) • 3.5 kB
JavaScript
"use strict";
var _a;
Object.defineProperty(exports, "__esModule", { value: true });
const message_1 = require("../message");
const utils_1 = require("../utils");
class MultyxClientValue {
get value() {
return this.readModifiers.reduce((value, modifier) => modifier(value), this._value);
}
set value(v) {
this._value = v;
}
addReadModifier(modifier) {
this.readModifiers.push(modifier);
}
addEditCallback(callback) {
this.editCallbacks.push(callback);
}
[utils_1.Edit](updatePath, value) {
if (updatePath.length != 0)
return;
this.set(new utils_1.EditWrapper(value));
}
constructor(multyx, value, propertyPath = [], editable) {
this.readModifiers = [];
this.editCallbacks = [];
/* Native methods to allow MultyxValue to be treated as primitive */
this.toString = () => this.value.toString();
this.valueOf = () => this.value;
this[_a] = () => this.value;
this.propertyPath = propertyPath;
this.editable = editable;
this.multyx = multyx;
this.constraints = {};
this.set(value);
const propSymbol = Symbol.for("_" + this.propertyPath.join('.'));
if (this.multyx.events.has(propSymbol)) {
this.multyx[utils_1.Done].push(...this.multyx.events.get(propSymbol).map(e => () => e(this.value)));
}
}
set(value) {
if (value instanceof utils_1.EditWrapper) {
const oldValue = this.value;
this.value = value.value;
this.editCallbacks.forEach(fn => fn(value.value, oldValue));
return true;
}
// Attempting to edit property not editable to client
if (!this.editable) {
if (this.multyx.options.verbose) {
console.error(`Attempting to set property that is not editable. Setting '${this.propertyPath.join('.')}' to ${value}`);
}
return false;
}
let nv = value;
for (const constraint in this.constraints) {
const fn = this.constraints[constraint];
nv = fn(nv);
if (nv === null) {
if (this.multyx.options.verbose) {
console.error(`Attempting to set property that failed on constraint. Setting '${this.propertyPath.join('.')}' to ${value}, stopped by constraint '${constraint}'`);
}
return false;
}
}
if (this.value === nv) {
this.value = nv;
return true;
}
this.value = nv;
this.multyx.ws.send(message_1.Message.Native({
instruction: 'edit',
path: this.propertyPath,
value: nv
}));
return true;
}
bindElement(element) {
this.addEditCallback((value, previousValue) => {
if (value !== previousValue) {
element.innerText = value.toString();
}
});
}
/**
* Unpack constraints sent from server and store
* @param constraints Packed constraints from server
*/
[utils_1.Unpack](constraints) {
for (const [cname, args] of Object.entries(constraints)) {
const constraint = (0, utils_1.BuildConstraint)(cname, args);
if (!constraint)
continue;
this.constraints[cname] = constraint;
}
}
}
_a = Symbol.toPrimitive;
exports.default = MultyxClientValue;