From c844dd4798c06ca21268b0ca337d65913f8f5795 Mon Sep 17 00:00:00 2001 From: tobspr Date: Sat, 27 Jun 2020 09:52:26 +0200 Subject: [PATCH] Improve performance by only updating belt ejectors on the end of paths --- src/js/game/belt_path.js | 101 +++++++++++++------------ src/js/game/components/item_ejector.js | 5 ++ src/js/game/systems/item_ejector.js | 4 + 3 files changed, 60 insertions(+), 50 deletions(-) diff --git a/src/js/game/belt_path.js b/src/js/game/belt_path.js index ffa6703f..9cc2c88d 100644 --- a/src/js/game/belt_path.js +++ b/src/js/game/belt_path.js @@ -58,34 +58,6 @@ export class BeltPath extends BasicSerializableObject { return fakeObject; } - /** - * Initializes the path by computing the properties which are not saved - * @param {boolean} computeSpacing Whether to also compute the spacing - */ - init(computeSpacing = true) { - // Find acceptor and ejector - this.ejectorComp = this.entityPath[this.entityPath.length - 1].components.ItemEjector; - this.ejectorSlot = this.ejectorComp.slots[0]; - this.initialBeltComponent = this.entityPath[0].components.Belt; - - this.totalLength = this.computeTotalLength(); - - if (computeSpacing) { - this.spacingToFirstItem = this.totalLength; - } - - /** - * Current bounds of this path - * @type {Rectangle} - */ - this.worldBounds = this.computeBounds(); - - // Connect the belts - for (let i = 0; i < this.entityPath.length; ++i) { - this.entityPath[i].components.Belt.assignedPath = this; - } - } - /** * @param {GameRoot} root * @param {Array} entityPath @@ -112,6 +84,32 @@ export class BeltPath extends BasicSerializableObject { this.debug_checkIntegrity("constructor"); } + /** + * Initializes the path by computing the properties which are not saved + * @param {boolean} computeSpacing Whether to also compute the spacing + */ + init(computeSpacing = true) { + // Find acceptor and ejector + + this.totalLength = this.computeTotalLength(); + + if (computeSpacing) { + this.spacingToFirstItem = this.totalLength; + } + + /** + * Current bounds of this path + * @type {Rectangle} + */ + this.worldBounds = this.computeBounds(); + + // Connect the belts + for (let i = 0; i < this.entityPath.length; ++i) { + this.entityPath[i].components.Belt.assignedPath = this; + } + + this.onPathChanged(); + } /** * Returns whether this path can accept a new item @@ -158,6 +156,18 @@ export class BeltPath extends BasicSerializableObject { return bounds.allScaled(globalConfig.tileSize); } + /** + * Updates all ejectors on the path, so that only the last ejector + */ + onPathChanged() { + this.ejectorComp = this.entityPath[this.entityPath.length - 1].components.ItemEjector; + this.ejectorSlot = this.ejectorComp.slots[0]; + + for (let i = 0; i < this.entityPath.length; ++i) { + this.entityPath[i].components.ItemEjector.enabled = i === this.entityPath.length - 1; + } + } + /** * Helper to throw an error on mismatch * @param {string} change @@ -201,6 +211,11 @@ export class BeltPath extends BasicSerializableObject { return fail("Reference to destroyed entity " + entity.uid); } + const enabledState = i === this.entityPath.length - 1; + if (entity.components.ItemEjector.enabled !== enabledState) { + return fail("Item ejector enabled state is not synchronized (index =" + i + ")"); + } + const followUp = this.root.systemMgr.systems.belt.findFollowUpEntity(entity); if (!followUp) { return fail( @@ -241,9 +256,6 @@ export class BeltPath extends BasicSerializableObject { if (!this.ejectorSlot) { return fail("Ejector slot not set"); } - if (this.initialBeltComponent !== this.entityPath[0].components.Belt) { - return fail("Stale initial belt component handle"); - } // Check spacing if (this.spacingToFirstItem > this.totalLength + 0.005) { @@ -326,6 +338,7 @@ export class BeltPath extends BasicSerializableObject { // Append the entity this.entityPath.push(entity); + this.onPathChanged(); // Extend the path length const additionalLength = beltComp.getEffectiveLengthTiles(); @@ -349,10 +362,6 @@ export class BeltPath extends BasicSerializableObject { lastItem[_nextDistance] += additionalLength; } - // Update handles - this.ejectorComp = entity.components.ItemEjector; - this.ejectorSlot = this.ejectorComp.slots[0]; - // Assign reference beltComp.assignedPath = this; @@ -384,7 +393,7 @@ export class BeltPath extends BasicSerializableObject { // Set handles and append entity beltComp.assignedPath = this; this.entityPath.unshift(entity); - this.initialBeltComponent = this.entityPath[0].components.Belt; + this.onPathChanged(); // Update bounds this.worldBounds = this.computeBounds(); @@ -559,9 +568,8 @@ export class BeltPath extends BasicSerializableObject { this.spacingToFirstItem = this.totalLength; } - // Set new ejector and acceptor handles - this.ejectorComp = firstPathEndEntity.components.ItemEjector; - this.ejectorSlot = this.ejectorComp.slots[0]; + this.onPathChanged(); + secondPath.onPathChanged(); // Update bounds this.worldBounds = this.computeBounds(); @@ -598,6 +606,7 @@ export class BeltPath extends BasicSerializableObject { ); this.totalLength -= beltLength; this.entityPath.pop(); + this.onPathChanged(); DEBUG && logger.log( @@ -671,10 +680,6 @@ export class BeltPath extends BasicSerializableObject { } } - // Update handles - this.ejectorComp = this.entityPath[this.entityPath.length - 1].components.ItemEjector; - this.ejectorSlot = this.ejectorComp.slots[0]; - // Update bounds this.worldBounds = this.computeBounds(); @@ -708,6 +713,7 @@ export class BeltPath extends BasicSerializableObject { ); this.totalLength -= beltLength; this.entityPath.shift(); + this.onPathChanged(); DEBUG && logger.log( @@ -801,9 +807,6 @@ export class BeltPath extends BasicSerializableObject { } } - // Update handles - this.initialBeltComponent = this.entityPath[0].components.Belt; - // Update bounds this.worldBounds = this.computeBounds(); @@ -846,10 +849,6 @@ export class BeltPath extends BasicSerializableObject { this.totalLength ); - // Update handles - this.ejectorComp = this.entityPath[this.entityPath.length - 1].components.ItemEjector; - this.ejectorSlot = this.ejectorComp.slots[0]; - // Now, update the distance of our last item if (this.items.length !== 0) { const lastItem = this.items[this.items.length - 1]; @@ -881,6 +880,8 @@ export class BeltPath extends BasicSerializableObject { // Update bounds this.worldBounds = this.computeBounds(); + this.onPathChanged(); + this.debug_checkIntegrity("extend-by-path"); } diff --git a/src/js/game/components/item_ejector.js b/src/js/game/components/item_ejector.js index 7ae97724..739a0b9f 100644 --- a/src/js/game/components/item_ejector.js +++ b/src/js/game/components/item_ejector.js @@ -69,6 +69,11 @@ export class ItemEjectorComponent extends Component { /** @type {ItemEjectorSlot[]} */ this.cachedConnectedSlots = null; + + /** + * Whether this ejector slot is enabled + */ + this.enabled = true; } /** diff --git a/src/js/game/systems/item_ejector.js b/src/js/game/systems/item_ejector.js index b5da836a..b2ebf30d 100644 --- a/src/js/game/systems/item_ejector.js +++ b/src/js/game/systems/item_ejector.js @@ -186,6 +186,10 @@ export class ItemEjectorSystem extends GameSystemWithFilter { for (let i = 0; i < this.allEntities.length; ++i) { const sourceEntity = this.allEntities[i]; const sourceEjectorComp = sourceEntity.components.ItemEjector; + if (!sourceEjectorComp.enabled) { + continue; + } + if (!sourceEjectorComp.cachedConnectedSlots) { continue; }