From 2e183559ad81a5e8910951e786d85ca79515821b Mon Sep 17 00:00:00 2001 From: cha0s Date: Thu, 1 Aug 2024 14:59:52 -0500 Subject: [PATCH] Revert "perf: micro" This reverts commit 05350e6ccfb373d43d4b74462d846c452c6bfab9. --- app/ecs/component.js | 82 ++++++++++++++++++++++++++++---------------- 1 file changed, 53 insertions(+), 29 deletions(-) diff --git a/app/ecs/component.js b/app/ecs/component.js index 7dc0e65..7a47715 100644 --- a/app/ecs/component.js +++ b/app/ecs/component.js @@ -2,9 +2,10 @@ import Schema from './schema.js'; export default class Component { + data = []; ecs; Instance; - instances = {}; + map = {}; pool = []; static properties = {}; static $$schema; @@ -14,6 +15,19 @@ export default class Component { 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) { const [created] = await this.createMany([[entityId, values]]); return created; @@ -23,28 +37,36 @@ export default class Component { if (0 === entries.length) { return []; } - let {length} = entries; - const allocated = []; - while (length > 0) { - allocated.push( - this.pool.length > 0 - ? this.pool.pop() - : new this.Instance(), - ) - length -= 1; - } + const allocated = this.allocateMany(entries.length); + const {properties} = this.constructor.schema.specification.concrete; + const Schema = this.constructor.schema.constructor; + const keys = Object.keys(properties); const promises = []; - for (const [entityId, values] of entries) { - const instance = allocated.pop(); - this.instances[entityId] = instance; - instance.entity = entityId; - for (const key in values) { - instance[key] = values[key]; + for (let i = 0; i < entries.length; ++i) { + const [entityId, values = {}] = entries[i]; + this.map[entityId] = allocated[i]; + this.data[allocated[i]].entity = entityId; + for (let k = 0; k < keys.length; ++k) { + const j = keys[k]; + 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(instance)); + promises.push(this.load(this.data[allocated[i]])); } await Promise.all(promises); - return allocated; + const created = []; + for (let i = 0; i < allocated.length; ++i) { + created.push(this.data[allocated[i]]); + } + return created; } deserialize(entityId, view, offset) { @@ -60,19 +82,19 @@ export default class Component { this.destroyMany([entityId]); } - destroyMany(entityIds) { + destroyMany(entities) { this.freeMany( - entityIds + entities .map((entityId) => { - if ('undefined' !== typeof this.instances[entityId]) { - return this.instances[entityId]; + if ('undefined' !== typeof this.map[entityId]) { + return this.map[entityId]; } throw new Error(`can't free for non-existent id ${entityId}`); }), ); - for (const entityId of entityIds) { - this.instances[entityId].destroy(); - delete this.instances[entityId]; + for (let i = 0; i < entities.length; i++) { + this.data[this.map[entities[i]]].destroy(); + this.map[entities[i]] = undefined; } } @@ -88,12 +110,14 @@ export default class Component { return json; } - freeMany(instances) { - this.pool.push(...instances); + freeMany(indices) { + for (let i = 0; i < indices.length; ++i) { + this.pool.push(indices[i]); + } } get(entityId) { - return this.instances[entityId]; + return this.data[this.map[entityId]]; } async insertMany(entities) {