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) {
const creating = [];
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);
await this.createMany(entities);
}
instanceFromSchema() {
@ -158,6 +145,16 @@ export default class Component {
toJSON() {
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 = {};
properties.entity = {
@ -216,4 +213,11 @@ export default class Component {
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 {
async insertMany(entities) {
async updateMany(entities) {
for (const [id, {cleared, given, qtyUpdated, swapped}] of entities) {
const instance = this.get(id);
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) {
if (slots) {
const instance = this.get(id);

View File

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

View File

@ -59,6 +59,7 @@ export default class Ecs {
async apply(patch) {
const creating = [];
const destroying = [];
const inserting = [];
const removing = [];
const updating = [];
for (const entityIdString in patch) {
@ -82,7 +83,23 @@ export default class Ecs {
removing.push([entityId, componentsToRemove]);
}
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 {
creating.push([entityId, componentsToUpdate]);
@ -91,14 +108,19 @@ export default class Ecs {
if (destroying.length > 0) {
this.destroyMany(destroying);
}
if (updating.length > 0) {
await this.insertMany(updating);
const promises = [];
if (inserting.length > 0) {
promises.push(this.insertMany(inserting));
}
if (removing.length > 0) {
this.removeMany(removing);
if (updating.length > 0) {
promises.push(this.updateMany(updating));
}
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());
}
}