Merge pull request #2641 from sunryze-git/improved-pneumatics

improved pneumatics throughput
This commit is contained in:
HbmMods 2026-01-11 20:22:26 +01:00 committed by GitHub
commit a491b16dfe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -2,6 +2,7 @@ package com.hbm.uninos.networkproviders;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -67,37 +68,64 @@ public class PneumaticNetwork extends NodeNet {
if(sendOrder == SEND_LAST) BobMathUtil.reverseIntArray(sourceSlotAccess); if(sendOrder == SEND_LAST) BobMathUtil.reverseIntArray(sourceSlotAccess);
if(sendOrder == SEND_RANDOM) BobMathUtil.shuffleIntArray(sourceSlotAccess); if(sendOrder == SEND_RANDOM) BobMathUtil.shuffleIntArray(sourceSlotAccess);
ISidedInventory sidedSource = source instanceof ISidedInventory ? (ISidedInventory) source : null;
boolean hasItem = false;
for(int i : sourceSlotAccess) {
ItemStack stack = source.getStackInSlot(i);
if(stack != null) {
if(sidedSource != null && !sidedSource.canExtractItem(i, stack, sourceSide)) continue;
boolean match = tube.matchesFilter(stack);
if((match && !tube.whitelist) || (!match && tube.whitelist)) continue;
hasItem = true;
break;
}
}
// return early if there arent any items in the source inventory, saves on some cpu usage for idle networks
if(!hasItem) return false;
// for round robin, receivers are ordered by proximity to the source // for round robin, receivers are ordered by proximity to the source
ReceiverComparator comparator = new ReceiverComparator(tube); ReceiverComparator comparator = new ReceiverComparator(tube);
List<Entry<IInventory, Triplet<ForgeDirection, Long, TileEntityPneumoTube>>> receiverList = new ArrayList(receivers.size()); List<Entry<IInventory, Triplet<ForgeDirection, Long, TileEntityPneumoTube>>> receiverList = new ArrayList(receivers.size());
receiverList.addAll(receivers.entrySet()); receiverList.addAll(receivers.entrySet());
receiverList.sort(comparator);
int index = nextReceiver % receivers.size(); if(receiveOrder == RECEIVE_ROBIN) receiverList.sort(comparator);
Entry<IInventory, Triplet<ForgeDirection, Long, TileEntityPneumoTube>> chosenReceiverEntry = null; if(receiveOrder == RECEIVE_RANDOM) Collections.shuffle(receiverList);
if(receiveOrder == RECEIVE_ROBIN) chosenReceiverEntry = receiverList.get(index);
if(receiveOrder == RECEIVE_RANDOM) chosenReceiverEntry = receiverList.get(rand.nextInt(receiverList.size()));
if(chosenReceiverEntry == null) return false;
IInventory dest = chosenReceiverEntry.getKey();
TileEntityPneumoTube endpointTile = chosenReceiverEntry.getValue().getZ();
ISidedInventory sidedDest = dest instanceof ISidedInventory ? (ISidedInventory) dest : null;
ISidedInventory sidedSource = source instanceof ISidedInventory ? (ISidedInventory) source : null;
TileEntity tile1 = source instanceof TileEntity ? (TileEntity) source : null; TileEntity tile1 = source instanceof TileEntity ? (TileEntity) source : null;
int attempts = 0;
int maxAttempts = receiverList.size();
// try all receivers for both modes, in an attempts based system.
// instead of bailing out of trying after the first failure (which means you have to wait 0.25 seconds), we just try the next one.
while(attempts < maxAttempts) {
int index = (receiveOrder == RECEIVE_ROBIN) ? (nextReceiver + attempts) % receiverList.size() : attempts;
Entry<IInventory, Triplet<ForgeDirection, Long, TileEntityPneumoTube>> candidate = receiverList.get(index);
if(NodeNet.isBadLink(candidate.getKey())) {
receivers.remove(candidate.getKey());
attempts++;
continue;
}
IInventory dest = candidate.getKey();
TileEntityPneumoTube endpointTile = candidate.getValue().getZ();
TileEntity tile2 = dest instanceof TileEntity ? (TileEntity) dest : null; TileEntity tile2 = dest instanceof TileEntity ? (TileEntity) dest : null;
// range check for our compression level, skip if either source or dest aren't tile entities // range check for our compression level, skip if either source or dest aren't tile entities
if(tile1 != null && tile2 != null) { if(tile1 != null && tile2 != null) {
int sq = (tile1.xCoord - tile2.xCoord) * (tile1.xCoord - tile2.xCoord) + (tile1.yCoord - tile2.yCoord) * (tile1.yCoord - tile2.yCoord) + (tile1.zCoord - tile2.zCoord) * (tile1.zCoord - tile2.zCoord); int sq = (tile1.xCoord - tile2.xCoord) * (tile1.xCoord - tile2.xCoord) + (tile1.yCoord - tile2.yCoord) * (tile1.yCoord - tile2.yCoord) + (tile1.zCoord - tile2.zCoord) * (tile1.zCoord - tile2.zCoord);
if(sq > maxRange * maxRange) { if(sq > maxRange * maxRange) {
return false; attempts++;
continue;
} }
} }
int destSide = chosenReceiverEntry.getValue().getX().getOpposite().ordinal(); ISidedInventory sidedDest = dest instanceof ISidedInventory ? (ISidedInventory) dest : null;
int destSide = candidate.getValue().getX().getOpposite().ordinal();
int[] destSlotAccess = getSlotAccess(dest, destSide); int[] destSlotAccess = getSlotAccess(dest, destSide);
int itemsLeftToSend = ITEMS_PER_TRANSFER; // not actually individual items, but rather the total "mass", based on max stack size int itemsLeftToSend = ITEMS_PER_TRANSFER; // not actually individual items, but rather the total "mass", based on max stack size
int itemHardCap = dest instanceof TileEntityMachineAutocrafter ? 1 : ITEMS_PER_TRANSFER; int itemHardCap = dest instanceof TileEntityMachineAutocrafter ? 1 : ITEMS_PER_TRANSFER;
@ -167,9 +195,12 @@ public class PneumaticNetwork extends NodeNet {
if(didSomething) { if(didSomething) {
source.markDirty(); source.markDirty();
dest.markDirty(); dest.markDirty();
return true;
} }
return didSomething; attempts++;
}
return false;
} }
/** Returns an array of accessible slots from the given side of an IInventory. If it's an ISidedInventory, uses the sided restrictions instead. */ /** Returns an array of accessible slots from the given side of an IInventory. If it's an ISidedInventory, uses the sided restrictions instead. */