110 lines
2.7 KiB
JavaScript
110 lines
2.7 KiB
JavaScript
import Serializer from './serializer.js';
|
|
|
|
import Base from './base.js';
|
|
|
|
export default class Arbitrary extends Base {
|
|
|
|
data = [];
|
|
|
|
serializer;
|
|
|
|
Instance;
|
|
|
|
constructor() {
|
|
super();
|
|
this.serializer = new Serializer(this.constructor.schema);
|
|
}
|
|
|
|
allocateMany(count) {
|
|
if (!this.Instance) {
|
|
this.Instance = this.instanceFromSchema();
|
|
}
|
|
const results = super.allocateMany(count);
|
|
count -= results.length; while (count--) {
|
|
results.push(this.data.push(new this.Instance()) - 1);
|
|
}
|
|
return results;
|
|
}
|
|
|
|
createMany(entries) {
|
|
if (entries.length > 0) {
|
|
const allocated = this.allocateMany(entries.length);
|
|
const keys = Object.keys(this.constructor.schema.specification);
|
|
for (let i = 0; i < entries.length; ++i) {
|
|
const [entityId, values = {}] = entries[i];
|
|
this.map[entityId] = allocated[i];
|
|
this.data[allocated[i]].entity = entityId;
|
|
if (false === values) {
|
|
continue;
|
|
}
|
|
for (let k = 0; k < keys.length; ++k) {
|
|
const j = keys[k];
|
|
const {defaultValue} = this.constructor.schema.specification[j];
|
|
if (j in values) {
|
|
this.data[allocated[i]][j] = values[j];
|
|
}
|
|
else if ('undefined' !== typeof defaultValue) {
|
|
this.data[allocated[i]][j] = defaultValue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
deserialize(entityId, view, offset) {
|
|
this.serializer.decode(view, this.get(entityId), offset);
|
|
}
|
|
|
|
serialize(entityId, view, offset) {
|
|
this.serializer.encode(this.get(entityId), view, offset);
|
|
}
|
|
|
|
get(entityId) {
|
|
return this.data[this.map[entityId]];
|
|
}
|
|
|
|
instanceFromSchema() {
|
|
const Component = this;
|
|
const Instance = class {
|
|
$$entity = 0;
|
|
constructor() {
|
|
this.$$reset();
|
|
}
|
|
$$reset() {
|
|
for (const [i, {defaultValue}] of Component.constructor.schema) {
|
|
this[`$$${i}`] = defaultValue;
|
|
}
|
|
}
|
|
toJSON() {
|
|
return Component.constructor.filterDefaults(this);
|
|
}
|
|
};
|
|
const properties = {};
|
|
properties.entity = {
|
|
get: function get() {
|
|
return this.$$entity;
|
|
},
|
|
set: function set(v) {
|
|
this.$$entity = v;
|
|
this.$$reset();
|
|
},
|
|
};
|
|
for (const [i] of Component.constructor.schema) {
|
|
properties[i] = {
|
|
get: function get() {
|
|
return this[`$$${i}`];
|
|
},
|
|
set: function set(v) {
|
|
if (this[`$$${i}`] !== v) {
|
|
this[`$$${i}`] = v;
|
|
Component.markChange(this.entity, i, v);
|
|
}
|
|
},
|
|
};
|
|
}
|
|
Object.defineProperties(Instance.prototype, properties);
|
|
return Instance;
|
|
}
|
|
|
|
}
|