perf: separate insert/update

This commit is contained in:
cha0s 2024-07-30 11:46:04 -05:00
parent 64df3b882f
commit 90ab588133
4 changed files with 71 additions and 24 deletions

View File

@ -121,20 +121,7 @@ export default class Component {
} }
async insertMany(entities) { async insertMany(entities) {
const creating = []; await this.createMany(entities);
for (let i = 0; i < entities.length; i++) {
const [entityId, values] = entities[i];
if (!this.get(entityId)) {
creating.push([entityId, values]);
}
else {
const instance = this.get(entityId);
for (const i in values) {
instance[i] = values[i];
}
}
}
await this.createMany(creating);
} }
instanceFromSchema() { instanceFromSchema() {
@ -158,6 +145,16 @@ export default class Component {
toJSON() { toJSON() {
return Component.constructor.filterDefaults(this); return Component.constructor.filterDefaults(this);
} }
update(values) {
for (const key in values) {
if (concrete.properties[key]) {
this[`$$${key}`] = values[key];
}
else {
this[key] = values[key];
}
}
}
}; };
const properties = {}; const properties = {};
properties.entity = { properties.entity = {
@ -216,4 +213,11 @@ export default class Component {
return this.constructor.schema.sizeOf(this.get(entityId)); return this.constructor.schema.sizeOf(this.get(entityId));
} }
async updateMany(entities) {
for (let i = 0; i < entities.length; i++) {
const [entityId, values] = entities[i];
this.get(entityId).update(values);
}
}
} }

View File

@ -115,7 +115,7 @@ class ItemProxy {
} }
export default class Inventory extends Component { export default class Inventory extends Component {
async insertMany(entities) { async updateMany(entities) {
for (const [id, {cleared, given, qtyUpdated, swapped}] of entities) { for (const [id, {cleared, given, qtyUpdated, swapped}] of entities) {
const instance = this.get(id); const instance = this.get(id);
const {$$items, slots} = instance; const {$$items, slots} = instance;
@ -152,7 +152,7 @@ export default class Inventory extends Component {
} }
} }
} }
await super.insertMany(entities); await super.updateMany(entities);
for (const [id, {slots}] of entities) { for (const [id, {slots}] of entities) {
if (slots) { if (slots) {
const instance = this.get(id); const instance = this.get(id);

View File

@ -164,7 +164,7 @@ export default class TileLayers extends Component {
} }
return super.createMany(entities); return super.createMany(entities);
} }
async insertMany(entities) { async updateMany(entities) {
for (const [, {layers}] of entities) { for (const [, {layers}] of entities) {
if (layers) { if (layers) {
for (const layer of layers) { for (const layer of layers) {
@ -179,7 +179,7 @@ export default class TileLayers extends Component {
} }
} }
} }
await super.insertMany(entities); await super.updateMany(entities);
for (const [id, {layerChange}] of entities) { for (const [id, {layerChange}] of entities) {
if (layerChange) { if (layerChange) {
const component = this.get(id); const component = this.get(id);

View File

@ -59,6 +59,7 @@ export default class Ecs {
async apply(patch) { async apply(patch) {
const creating = []; const creating = [];
const destroying = []; const destroying = [];
const inserting = [];
const removing = []; const removing = [];
const updating = []; const updating = [];
for (const entityIdString in patch) { for (const entityIdString in patch) {
@ -82,7 +83,23 @@ export default class Ecs {
removing.push([entityId, componentsToRemove]); removing.push([entityId, componentsToRemove]);
} }
if (this.$$entities[entityId]) { if (this.$$entities[entityId]) {
updating.push([entityId, componentsToUpdate]); const entity = this.$$entities[entityId];
const entityInserts = {};
const entityUpdates = {};
for (const componentName in componentsToUpdate) {
if (entity[componentName]) {
entityUpdates[componentName] = componentsToUpdate[componentName];
}
else {
entityInserts[componentName] = componentsToUpdate[componentName];
}
}
if (Object.keys(entityInserts).length > 0) {
inserting.push([entityId, entityInserts]);
}
if (Object.keys(entityUpdates).length > 0) {
updating.push([entityId, entityUpdates]);
}
} }
else { else {
creating.push([entityId, componentsToUpdate]); creating.push([entityId, componentsToUpdate]);
@ -91,14 +108,19 @@ export default class Ecs {
if (destroying.length > 0) { if (destroying.length > 0) {
this.destroyMany(destroying); this.destroyMany(destroying);
} }
if (updating.length > 0) { const promises = [];
await this.insertMany(updating); if (inserting.length > 0) {
promises.push(this.insertMany(inserting));
} }
if (removing.length > 0) { if (updating.length > 0) {
this.removeMany(removing); promises.push(this.updateMany(updating));
} }
if (creating.length > 0) { if (creating.length > 0) {
await this.createManySpecific(creating); promises.push(this.createManySpecific(creating));
}
await Promise.all(promises);
if (removing.length > 0) {
this.removeMany(removing);
} }
} }
@ -502,4 +524,25 @@ export default class Ecs {
}; };
} }
async updateMany(entities) {
const updating = {};
const unique = new Set();
for (const [entityId, components] of entities) {
this.rebuild(entityId);
for (const componentName in components) {
if (!updating[componentName]) {
updating[componentName] = [];
}
updating[componentName].push([entityId, components[componentName]]);
}
unique.add(entityId);
}
const promises = [];
for (const componentName in updating) {
promises.push(this.Components[componentName].updateMany(updating[componentName]));
}
await Promise.all(promises);
this.reindex(unique.values());
}
} }