Migrated array of entities in entity_manager.js to map using uid as key

pull/1511/head
Bart Remmers 1 year ago
parent 0713c850ec
commit 0c5f6db70c

@ -440,7 +440,7 @@ export class GameCore {
this.overlayAlpha = lerp(this.overlayAlpha, desiredOverlayAlpha, 0.25); this.overlayAlpha = lerp(this.overlayAlpha, desiredOverlayAlpha, 0.25);
// On low performance, skip the fade // On low performance, skip the fade
if (this.root.entityMgr.entities.length > 5000 || this.root.dynamicTickrate.averageFps < 50) { if (this.root.entityMgr.entities.size > 5000 || this.root.dynamicTickrate.averageFps < 50) {
this.overlayAlpha = desiredOverlayAlpha; this.overlayAlpha = desiredOverlayAlpha;
} }

@ -20,8 +20,8 @@ export class EntityManager extends BasicSerializableObject {
/** @type {GameRoot} */ /** @type {GameRoot} */
this.root = root; this.root = root;
/** @type {Array<Entity>} */ /** @type {Map<number, Entity>} */
this.entities = []; this.entities = new Map();
// We store a separate list with entities to destroy, since we don't destroy // We store a separate list with entities to destroy, since we don't destroy
// them instantly // them instantly
@ -48,7 +48,7 @@ export class EntityManager extends BasicSerializableObject {
} }
getStatsText() { getStatsText() {
return this.entities.length + " entities [" + this.destroyList.length + " to kill]"; return this.entities.size + " entities [" + this.destroyList.length + " to kill]";
} }
// Main update // Main update
@ -63,7 +63,7 @@ export class EntityManager extends BasicSerializableObject {
*/ */
registerEntity(entity, uid = null) { registerEntity(entity, uid = null) {
if (G_IS_DEV && !globalConfig.debug.disableSlowAsserts) { if (G_IS_DEV && !globalConfig.debug.disableSlowAsserts) {
assert(this.entities.indexOf(entity) < 0, `RegisterEntity() called twice for entity ${entity}`); assert(this.entities.get(entity.uid) !== entity, `RegisterEntity() called twice for entity ${entity}`);
} }
assert(!entity.destroyed, `Attempting to register destroyed entity ${entity}`); assert(!entity.destroyed, `Attempting to register destroyed entity ${entity}`);
@ -72,7 +72,11 @@ export class EntityManager extends BasicSerializableObject {
assert(uid >= 0 && uid < Number.MAX_SAFE_INTEGER, "Invalid uid passed: " + uid); assert(uid >= 0 && uid < Number.MAX_SAFE_INTEGER, "Invalid uid passed: " + uid);
} }
this.entities.push(entity); // Give each entity a unique id
entity.uid = uid ? uid : this.generateUid();
entity.registered = true;
this.entities.set(entity.uid, entity);
// Register into the componentToEntity map // Register into the componentToEntity map
for (const componentId in entity.components) { for (const componentId in entity.components) {
@ -85,10 +89,6 @@ export class EntityManager extends BasicSerializableObject {
} }
} }
// Give each entity a unique id
entity.uid = uid ? uid : this.generateUid();
entity.registered = true;
this.root.signals.entityAdded.dispatch(entity); this.root.signals.entityAdded.dispatch(entity);
} }
@ -136,23 +136,17 @@ export class EntityManager extends BasicSerializableObject {
* @returns {Entity} * @returns {Entity}
*/ */
findByUid(uid, errorWhenNotFound = true) { findByUid(uid, errorWhenNotFound = true) {
const arr = this.entities; const entity = this.entities.get(uid);
for (let i = 0, len = arr.length; i < len; ++i) {
const entity = arr[i]; if (entity === undefined || entity.queuedForDestroy || entity.destroyed) {
if (entity.uid === uid) { if (errorWhenNotFound) {
if (entity.queuedForDestroy || entity.destroyed) { logger.warn("Entity with UID", uid, "not found (destroyed)");
if (errorWhenNotFound) {
logger.warn("Entity with UID", uid, "not found (destroyed)");
}
return null;
}
return entity;
} }
return null
} }
if (errorWhenNotFound) {
logger.warn("Entity with UID", uid, "not found"); return entity
}
return null;
} }
/** /**
@ -163,14 +157,12 @@ export class EntityManager extends BasicSerializableObject {
*/ */
getFrozenUidSearchMap() { getFrozenUidSearchMap() {
const result = new Map(); const result = new Map();
const array = this.entities; for (const [uid, entity] of this.entities.entries()){
for (let i = 0, len = array.length; i < len; ++i) {
const entity = array[i];
if (!entity.queuedForDestroy && !entity.destroyed) { if (!entity.queuedForDestroy && !entity.destroyed) {
result.set(entity.uid, entity); result.set(uid, entity);
} }
} }
return result; return result
} }
/** /**
@ -200,8 +192,8 @@ export class EntityManager extends BasicSerializableObject {
for (let i = 0; i < this.destroyList.length; ++i) { for (let i = 0; i < this.destroyList.length; ++i) {
const entity = this.destroyList[i]; const entity = this.destroyList[i];
// Remove from entities list // Remove from entities map
arrayDeleteValue(this.entities, entity); this.entities.delete(entity.uid)
// Remove from componentToEntity list // Remove from componentToEntity list
this.unregisterEntityComponents(entity); this.unregisterEntityComponents(entity);

@ -93,7 +93,7 @@ export class HUDPuzzleEditorSettings extends BaseHUDPart {
trim() { trim() {
// Now, find the center // Now, find the center
const buildings = this.root.entityMgr.entities.slice(); const buildings = Array.from(this.root.entityMgr.entities.values());
if (buildings.length === 0) { if (buildings.length === 0) {
// nothing to do // nothing to do

@ -64,7 +64,7 @@ export class HUDWiresOverlay extends BaseHUDPart {
const desiredAlpha = this.root.currentLayer === "wires" ? 1.0 : 0.0; const desiredAlpha = this.root.currentLayer === "wires" ? 1.0 : 0.0;
// On low performance, skip the fade // On low performance, skip the fade
if (this.root.entityMgr.entities.length > 5000 || this.root.dynamicTickrate.averageFps < 50) { if (this.root.entityMgr.entities.size > 5000 || this.root.dynamicTickrate.averageFps < 50) {
this.currentAlpha = desiredAlpha; this.currentAlpha = desiredAlpha;
} else { } else {
this.currentAlpha = lerp(this.currentAlpha, desiredAlpha, 0.12); this.currentAlpha = lerp(this.currentAlpha, desiredAlpha, 0.12);

@ -473,7 +473,7 @@ export class GameLogic {
* Clears all belts and items * Clears all belts and items
*/ */
clearAllBeltsAndItems() { clearAllBeltsAndItems() {
for (const entity of this.root.entityMgr.entities) { for (const entity of this.root.entityMgr.entities.values()) {
for (const component of Object.values(entity.components)) { for (const component of Object.values(entity.components)) {
/** @type {Component} */ (component).clear(); /** @type {Component} */ (component).clear();
} }

@ -37,7 +37,7 @@ export class SavegameSerializer {
gameMode: root.gameMode.serialize(), gameMode: root.gameMode.serialize(),
entityMgr: root.entityMgr.serialize(), entityMgr: root.entityMgr.serialize(),
hubGoals: root.hubGoals.serialize(), hubGoals: root.hubGoals.serialize(),
entities: this.internal.serializeEntityArray(root.entityMgr.entities), entities: this.internal.serializeEntityMap(root.entityMgr.entities),
beltPaths: root.systemMgr.systems.belt.serializePaths(), beltPaths: root.systemMgr.systems.belt.serializePaths(),
pinnedShapes: root.hud.parts.pinnedShapes ? root.hud.parts.pinnedShapes.serialize() : null, pinnedShapes: root.hud.parts.pinnedShapes ? root.hud.parts.pinnedShapes.serialize() : null,
waypoints: root.hud.parts.waypoints ? root.hud.parts.waypoints.serialize() : null, waypoints: root.hud.parts.waypoints ? root.hud.parts.waypoints.serialize() : null,
@ -86,7 +86,7 @@ export class SavegameSerializer {
} }
seenUids.add(uid); seenUids.add(uid);
// Verify components // Verify components/
if (!entity.components) { if (!entity.components) {
return ExplainedResult.bad("Entity is missing key 'components': " + JSON.stringify(entity)); return ExplainedResult.bad("Entity is missing key 'components': " + JSON.stringify(entity));
} }

@ -11,12 +11,11 @@ const logger = createLogger("serializer_internal");
export class SerializerInternal { export class SerializerInternal {
/** /**
* Serializes an array of entities * Serializes an array of entities
* @param {Array<Entity>} array * @param {Map<number, Entity>} map
*/ */
serializeEntityArray(array) { serializeEntityMap(map) {
const serialized = []; const serialized = [];
for (let i = 0; i < array.length; ++i) { for (const entity of map.values()) {
const entity = array[i];
if (!entity.queuedForDestroy && !entity.destroyed) { if (!entity.queuedForDestroy && !entity.destroyed) {
serialized.push(entity.serialize()); serialized.push(entity.serialize());
} }

Loading…
Cancel
Save