1
0
mirror of https://github.com/tobspr/shapez.io.git synced 2024-10-27 20:34:29 +00:00

Vastly improve underground belt performance

This commit is contained in:
tobspr 2020-09-22 10:29:04 +02:00
parent 9075841768
commit afa08b06dc
2 changed files with 23 additions and 46 deletions

View File

@ -48,7 +48,7 @@ export class UndergroundBeltComponent extends Component {
* Used on both receiver and sender. * Used on both receiver and sender.
* Reciever: Used to store the next item to transfer, and to block input while doing this * Reciever: Used to store the next item to transfer, and to block input while doing this
* Sender: Used to store which items are currently "travelling" * Sender: Used to store which items are currently "travelling"
* @type {Array<[BaseItem, number]>} Format is [Item, remaining seconds until transfer/ejection] * @type {Array<[BaseItem, number]>} Format is [Item, ingame time to eject the item]
*/ */
this.pendingItems = []; this.pendingItems = [];
@ -85,8 +85,9 @@ export class UndergroundBeltComponent extends Component {
* @param {BaseItem} item * @param {BaseItem} item
* @param {number} travelDistance How many tiles this item has to travel * @param {number} travelDistance How many tiles this item has to travel
* @param {number} beltSpeed How fast this item travels * @param {number} beltSpeed How fast this item travels
* @param {number} now Current ingame time
*/ */
tryAcceptTunneledItem(item, travelDistance, beltSpeed) { tryAcceptTunneledItem(item, travelDistance, beltSpeed, now) {
if (this.mode !== enumUndergroundBeltMode.receiver) { if (this.mode !== enumUndergroundBeltMode.receiver) {
// Only receivers can accept tunneled items // Only receivers can accept tunneled items
return false; return false;
@ -105,11 +106,7 @@ export class UndergroundBeltComponent extends Component {
// Additionally it takes 1 tile for the acceptor which we just add on top. // Additionally it takes 1 tile for the acceptor which we just add on top.
const travelDuration = (travelDistance + 1.5) / beltSpeed / globalConfig.itemSpacingOnBelts; const travelDuration = (travelDistance + 1.5) / beltSpeed / globalConfig.itemSpacingOnBelts;
this.pendingItems.push([item, travelDuration]); this.pendingItems.push([item, now + travelDuration]);
// Sort so we can only look at the first ones
this.pendingItems.sort((a, b) => a[1] - b[1]);
return true; return true;
} }
} }

View File

@ -224,21 +224,9 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
update() { update() {
this.staleAreaWatcher.update(); this.staleAreaWatcher.update();
const delta = this.root.dynamicTickrate.deltaSeconds;
for (let i = 0; i < this.allEntities.length; ++i) { for (let i = 0; i < this.allEntities.length; ++i) {
const entity = this.allEntities[i]; const entity = this.allEntities[i];
const undergroundComp = entity.components.UndergroundBelt; const undergroundComp = entity.components.UndergroundBelt;
const pendingItems = undergroundComp.pendingItems;
// Decrease remaining time of all items in belt
for (let k = 0; k < pendingItems.length; ++k) {
const item = pendingItems[k];
item[1] = Math.max(0, item[1] - delta);
if (G_IS_DEV && globalConfig.debug.instantBelts) {
item[1] = 0;
}
}
if (undergroundComp.mode === enumUndergroundBeltMode.sender) { if (undergroundComp.mode === enumUndergroundBeltMode.sender) {
this.handleSender(entity); this.handleSender(entity);
} else { } else {
@ -316,21 +304,18 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
return; return;
} }
// Check if we have any item // Check if we have any items to eject
if (undergroundComp.pendingItems.length > 0) {
assert(undergroundComp.pendingItems.length === 1, "more than 1 pending");
const nextItemAndDuration = undergroundComp.pendingItems[0]; const nextItemAndDuration = undergroundComp.pendingItems[0];
const remainingTime = nextItemAndDuration[1]; if (nextItemAndDuration) {
const nextItem = nextItemAndDuration[0]; assert(undergroundComp.pendingItems.length === 1, "more than 1 pending");
// Check if the item is ready to be emitted
if (remainingTime === 0) {
// Check if the receiver can accept it // Check if the receiver can accept it
if ( if (
cacheEntry.entity.components.UndergroundBelt.tryAcceptTunneledItem( cacheEntry.entity.components.UndergroundBelt.tryAcceptTunneledItem(
nextItem, nextItemAndDuration[0],
cacheEntry.distance, cacheEntry.distance,
this.root.hubGoals.getUndergroundBeltBaseSpeed() this.root.hubGoals.getUndergroundBeltBaseSpeed(),
this.root.time.now()
) )
) { ) {
// Drop this item // Drop this item
@ -338,7 +323,6 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
} }
} }
} }
}
/** /**
* *
@ -348,19 +332,15 @@ export class UndergroundBeltSystem extends GameSystemWithFilter {
const undergroundComp = entity.components.UndergroundBelt; const undergroundComp = entity.components.UndergroundBelt;
// Try to eject items, we only check the first one because it is sorted by remaining time // Try to eject items, we only check the first one because it is sorted by remaining time
const items = undergroundComp.pendingItems;
if (items.length > 0) {
const nextItemAndDuration = undergroundComp.pendingItems[0]; const nextItemAndDuration = undergroundComp.pendingItems[0];
const remainingTime = nextItemAndDuration[1]; if (nextItemAndDuration) {
const nextItem = nextItemAndDuration[0]; if (this.root.time.now() > nextItemAndDuration[1]) {
if (remainingTime <= 0) {
const ejectorComp = entity.components.ItemEjector; const ejectorComp = entity.components.ItemEjector;
const nextSlotIndex = ejectorComp.getFirstFreeSlot(); const nextSlotIndex = ejectorComp.getFirstFreeSlot();
if (nextSlotIndex !== null) { if (nextSlotIndex !== null) {
if (ejectorComp.tryEject(nextSlotIndex, nextItem)) { if (ejectorComp.tryEject(nextSlotIndex, nextItemAndDuration[0])) {
items.shift(); undergroundComp.pendingItems.shift();
} }
} }
} }