import Base from './base.js'; export default class Arbitrary extends Base { data = []; serializer; Instance; 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.properties); 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.properties[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) { const {properties} = this.constructor; const instance = this.get(entityId); const deserialized = this.constructor.schema.deserialize(view, offset); for (const key in properties) { instance[key] = deserialized[key]; } } serialize(entityId, view, offset) { this.constructor.schema.serialize(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() { const {properties} = Component.constructor; for (const key in properties) { const {defaultValue} = properties[key]; this[`$$${key}`] = 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 key in Component.constructor.properties) { properties[key] = { get: function get() { return this[`$$${key}`]; }, set: function set(value) { if (this[`$$${key}`] !== value) { this[`$$${key}`] = value; Component.markChange(this.entity, key, value); } }, }; } Object.defineProperties(Instance.prototype, properties); return Instance; } }