110 lines
2.8 KiB
JavaScript
110 lines
2.8 KiB
JavaScript
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;
|
|
}
|
|
|
|
}
|