mirror of
https://github.com/tobspr/shapez.io.git
synced 2024-10-27 20:34:29 +00:00
Improve mass deletion performance
This commit is contained in:
parent
b7c773a70e
commit
5bdf6386a1
@ -93,14 +93,6 @@ export class Entity extends BasicSerializableObject {
|
||||
return clone;
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal destroy callback
|
||||
*/
|
||||
internalDestroyCallback() {
|
||||
assert(!this.destroyed, "Can not destroy entity twice");
|
||||
this.destroyed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new component, only possible until the entity is registered on the entity manager,
|
||||
* after that use @see EntityManager.addDynamicComponent
|
||||
|
@ -155,6 +155,24 @@ export class EntityManager extends BasicSerializableObject {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a map which gives a mapping from UID to Entity.
|
||||
* This map is not updated.
|
||||
*
|
||||
* @returns {Map<number, Entity>}
|
||||
*/
|
||||
getFrozenUidSearchMap() {
|
||||
const result = new Map();
|
||||
const array = this.entities;
|
||||
for (let i = 0, len = array.length; i < len; ++i) {
|
||||
const entity = array[i];
|
||||
if (!entity.queuedForDestroy && !entity.destroyed) {
|
||||
result.set(entity.uid, entity);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all entities having the given component
|
||||
* @param {typeof Component} componentHandle
|
||||
@ -206,7 +224,7 @@ export class EntityManager extends BasicSerializableObject {
|
||||
this.unregisterEntityComponents(entity);
|
||||
|
||||
entity.registered = false;
|
||||
entity.internalDestroyCallback();
|
||||
entity.destroyed = true;
|
||||
|
||||
this.root.signals.entityDestroyed.dispatch(entity);
|
||||
}
|
||||
|
@ -88,15 +88,16 @@ export class GameSystemWithFilter extends GameSystem {
|
||||
}
|
||||
|
||||
refreshCaches() {
|
||||
this.allEntities.sort((a, b) => a.uid - b.uid);
|
||||
|
||||
// Remove all entities which are queued for destroy
|
||||
for (let i = 0; i < this.allEntities.length; ++i) {
|
||||
const entity = this.allEntities[i];
|
||||
if (entity.queuedForDestroy || entity.destroyed) {
|
||||
this.allEntities.splice(i, 1);
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
this.allEntities.sort((a, b) => a.uid - b.uid);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,6 +48,9 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
* @param {Entity} entity
|
||||
*/
|
||||
onEntityDestroyed(entity) {
|
||||
if (this.root.bulkOperationRunning) {
|
||||
return;
|
||||
}
|
||||
this.selectedUids.delete(entity.uid);
|
||||
}
|
||||
|
||||
@ -90,14 +93,30 @@ export class HUDMassSelector extends BaseHUDPart {
|
||||
|
||||
doDelete() {
|
||||
const entityUids = Array.from(this.selectedUids);
|
||||
for (let i = 0; i < entityUids.length; ++i) {
|
||||
const uid = entityUids[i];
|
||||
const entity = this.root.entityMgr.findByUid(uid);
|
||||
if (!this.root.logic.tryDeleteBuilding(entity)) {
|
||||
logger.error("Error in mass delete, could not remove building");
|
||||
this.selectedUids.delete(uid);
|
||||
|
||||
// Build mapping from uid to entity
|
||||
/**
|
||||
* @type {Map<number, Entity>}
|
||||
*/
|
||||
const mapUidToEntity = this.root.entityMgr.getFrozenUidSearchMap();
|
||||
|
||||
this.root.logic.performBulkOperation(() => {
|
||||
for (let i = 0; i < entityUids.length; ++i) {
|
||||
const uid = entityUids[i];
|
||||
const entity = mapUidToEntity.get(uid);
|
||||
if (!entity) {
|
||||
logger.error("Entity not found by uid:", uid);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!this.root.logic.tryDeleteBuilding(entity)) {
|
||||
logger.error("Error in mass delete, could not remove building");
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Clear uids later
|
||||
this.selectedUids = new Set();
|
||||
}
|
||||
|
||||
startCopy() {
|
||||
|
Loading…
Reference in New Issue
Block a user