perf: micro

This commit is contained in:
cha0s 2024-08-01 13:23:23 -05:00
parent 5d352bb367
commit 05350e6ccf

View File

@ -2,10 +2,9 @@ import Schema from './schema.js';
export default class Component { export default class Component {
data = [];
ecs; ecs;
Instance; Instance;
map = {}; instances = {};
pool = []; pool = [];
static properties = {}; static properties = {};
static $$schema; static $$schema;
@ -15,19 +14,6 @@ export default class Component {
this.Instance = this.instanceFromSchema(); this.Instance = this.instanceFromSchema();
} }
allocateMany(count) {
const results = [];
while (count > 0) {
results.push(
this.pool.length > 0
? this.pool.pop()
: this.data.push(new this.Instance()) - 1,
)
count -= 1;
}
return results;
}
async create(entityId, values) { async create(entityId, values) {
const [created] = await this.createMany([[entityId, values]]); const [created] = await this.createMany([[entityId, values]]);
return created; return created;
@ -37,36 +23,28 @@ export default class Component {
if (0 === entries.length) { if (0 === entries.length) {
return []; return [];
} }
const allocated = this.allocateMany(entries.length); let {length} = entries;
const {properties} = this.constructor.schema.specification.concrete; const allocated = [];
const Schema = this.constructor.schema.constructor; while (length > 0) {
const keys = Object.keys(properties); allocated.push(
this.pool.length > 0
? this.pool.pop()
: new this.Instance(),
)
length -= 1;
}
const promises = []; const promises = [];
for (let i = 0; i < entries.length; ++i) { for (const [entityId, values] of entries) {
const [entityId, values = {}] = entries[i]; const instance = allocated.pop();
this.map[entityId] = allocated[i]; this.instances[entityId] = instance;
this.data[allocated[i]].entity = entityId; instance.entity = entityId;
for (let k = 0; k < keys.length; ++k) { for (const key in values) {
const j = keys[k]; instance[key] = values[key];
const instance = this.data[allocated[i]];
if (j in values) {
instance[j] = values[j];
}
else {
const defaultValue = Schema.defaultValue(properties[j]);
if ('undefined' !== typeof defaultValue) {
instance[j] = defaultValue;
}
}
} }
promises.push(this.load(this.data[allocated[i]])); promises.push(this.load(instance));
} }
await Promise.all(promises); await Promise.all(promises);
const created = []; return allocated;
for (let i = 0; i < allocated.length; ++i) {
created.push(this.data[allocated[i]]);
}
return created;
} }
deserialize(entityId, view, offset) { deserialize(entityId, view, offset) {
@ -82,19 +60,19 @@ export default class Component {
this.destroyMany([entityId]); this.destroyMany([entityId]);
} }
destroyMany(entities) { destroyMany(entityIds) {
this.freeMany( this.freeMany(
entities entityIds
.map((entityId) => { .map((entityId) => {
if ('undefined' !== typeof this.map[entityId]) { if ('undefined' !== typeof this.instances[entityId]) {
return this.map[entityId]; return this.instances[entityId];
} }
throw new Error(`can't free for non-existent id ${entityId}`); throw new Error(`can't free for non-existent id ${entityId}`);
}), }),
); );
for (let i = 0; i < entities.length; i++) { for (const entityId of entityIds) {
this.data[this.map[entities[i]]].destroy(); this.instances[entityId].destroy();
this.map[entities[i]] = undefined; delete this.instances[entityId];
} }
} }
@ -110,14 +88,12 @@ export default class Component {
return json; return json;
} }
freeMany(indices) { freeMany(instances) {
for (let i = 0; i < indices.length; ++i) { this.pool.push(...instances);
this.pool.push(indices[i]);
}
} }
get(entityId) { get(entityId) {
return this.data[this.map[entityId]]; return this.instances[entityId];
} }
async insertMany(entities) { async insertMany(entities) {