Skip to content

Commit e7a428d

Browse files
committed
Stop checking drawers when we run out of items to fit in them
1 parent 779d429 commit e7a428d

File tree

1 file changed

+74
-63
lines changed

1 file changed

+74
-63
lines changed

common/src/main/java/com/jaquadro/minecraft/storagedrawers/block/tile/BlockEntityController.java

Lines changed: 74 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -967,69 +967,68 @@ public ItemStack insertItem (@NotNull ItemStack stack, boolean simulate, Predica
967967
Collection<SlotRecord> primaryRecords = drawerPrimaryLookup.getEntries(stack.getItem());
968968
Set<Integer> checkedSlots = (simulate) ? new HashSet<>() : null;
969969
List<IDrawer> rebalance = new ArrayList<>();
970+
boolean needRebalance = false;
970971

971972
int amount = stack.getCount();
972-
if (primaryRecords != null) {
973-
// First test by strict remaining capacity
973+
if (primaryRecords != null && amount >= 0) {
974+
record PossibleDrawer(IDrawer drawer, SlotRecord record) {}
975+
var possibleDrawers = new ArrayList<PossibleDrawer>();
976+
977+
// This loop assumes that capacity does not affect predicates in a way
978+
// that things can strictly fit but not loosely fit.
979+
// This is currently true, and I can't think of a useful predicate that would
980+
// make it untrue, but if it becomes untrue, the set of valid drawers
981+
// would change between the first test loop and the second.
974982
for (SlotRecord record : primaryRecords) {
975-
IDrawerGroup candidateGroup = getGroupForSlotRecord(record);
976-
if (candidateGroup == null)
977-
continue;
978-
979-
IDrawer drawer = candidateGroup.getDrawer(record.slot);
980-
if (drawer.isEmpty())
981-
continue;
982-
if (!testPredicateInsert(drawer, stack, predicate))
983-
continue;
984-
if (!hasAccess(candidateGroup, drawer))
985-
continue;
986-
987-
IDrawerAttributes attrs = drawer.getAttributes();
988-
if (attrs.isSuspended())
989-
continue;
990-
if (attrs.isBalancedFill())
983+
IDrawer drawer = getValidDrawer(stack, predicate, record);
984+
985+
// We handle empty drawers below.
986+
if (drawer == null || drawer.isEmpty()) continue;
987+
possibleDrawers.add(new PossibleDrawer(drawer, record));
988+
// If we put an item in any drawer that has balanced fill, all
989+
// the drawers with balanced fill will need to be adjusted.
990+
// We add them here, and check if we placed an item in the loops below.
991+
if (drawer.getAttributes().isBalancedFill())
991992
rebalance.add(drawer);
993+
}
994+
// First test by strict remaining capacity
995+
for (var possibleDrawer : possibleDrawers) {
996+
int amountBefore = amount;
997+
int adjusted = Math.min(amount, possibleDrawer.drawer.getRemainingCapacity());
992998

993-
if (amount == 0)
994-
continue;
995-
996-
int adjusted = Math.min(amount, drawer.getRemainingCapacity());
997999
amount = (simulate)
998-
? Math.max(amount - drawer.getRemainingCapacity(), 0)
999-
: (amount - adjusted) + drawer.adjustStoredItemCount(adjusted);
1000-
1001-
if (amount == 0)
1002-
continue;
1000+
? Math.max(amount - possibleDrawer.drawer.getRemainingCapacity(), 0)
1001+
: (amount - adjusted) + possibleDrawer.drawer.adjustStoredItemCount(adjusted);
10031002

10041003
if (simulate)
1005-
checkedSlots.add(record.index);
1004+
checkedSlots.add(possibleDrawer.record.index);
1005+
1006+
// If we placed anything in a rebalancing drawer, mark the need to rebalance
1007+
if (!needRebalance && amountBefore != amount && possibleDrawer.drawer.getAttributes().isBalancedFill())
1008+
needRebalance = true;
1009+
1010+
// Once we have fit all the items, we do not need to continue.
1011+
if (amount == 0)
1012+
break;
10061013
}
10071014

1008-
// Then relax to available capacity
1015+
// Then relax to available capacity if needed
10091016
if (amount > 0) {
1010-
for (SlotRecord record : primaryRecords) {
1011-
IDrawerGroup candidateGroup = getGroupForSlotRecord(record);
1012-
if (candidateGroup == null)
1013-
continue;
1014-
1015-
IDrawer drawer = candidateGroup.getDrawer(record.slot);
1016-
if (drawer.isEmpty())
1017-
continue;
1018-
if (!testPredicateInsert(drawer, stack, predicate))
1019-
continue;
1020-
if (!hasAccess(candidateGroup, drawer))
1021-
continue;
1022-
1023-
IDrawerAttributes attrs = drawer.getAttributes();
1024-
if (attrs.isSuspended())
1025-
continue;
1026-
1017+
for (var possibleDrawer : possibleDrawers) {
1018+
int amountBefore = amount;
10271019
amount = (simulate)
1028-
? Math.max(amount - drawer.getAcceptingRemainingCapacity(), 0)
1029-
: drawer.adjustStoredItemCount(amount);
1020+
? Math.max(amount - possibleDrawer.drawer.getAcceptingRemainingCapacity(), 0)
1021+
: possibleDrawer.drawer.adjustStoredItemCount(amount);
10301022

10311023
if (simulate)
1032-
checkedSlots.add(record.index);
1024+
checkedSlots.add(possibleDrawer.record.index);
1025+
1026+
if (!needRebalance && amountBefore != amount && possibleDrawer.drawer.getAttributes().isBalancedFill())
1027+
needRebalance = true;
1028+
1029+
// Once we have fit all the items, we do not need to continue.
1030+
if (amount == 0)
1031+
break;
10331032
}
10341033
}
10351034
}
@@ -1039,19 +1038,8 @@ public ItemStack insertItem (@NotNull ItemStack stack, boolean simulate, Predica
10391038
IDrawer drawer = getDrawer(slot);
10401039
if (!drawer.isEnabled())
10411040
continue;
1042-
if (!testPredicateInsert(drawer, stack, predicate))
1043-
continue;
1044-
if (!hasAccess(getGroupForDrawerSlot(slot), drawer))
1045-
continue;
1046-
1047-
IDrawerGroup group = getGroupForDrawerSlot(slot);
1048-
if (!hasAccess(group, drawer))
1049-
continue;
1050-
1051-
IDrawerAttributes attrs = drawer.getAttributes();
1052-
if (attrs.isSuspended())
1041+
if (!isValidDrawer(stack, predicate, drawer, getGroupForDrawerSlot(slot)))
10531042
continue;
1054-
10551043
if (simulate && checkedSlots.contains(slot))
10561044
continue;
10571045

@@ -1062,20 +1050,43 @@ public ItemStack insertItem (@NotNull ItemStack stack, boolean simulate, Predica
10621050
amount = (simulate)
10631051
? Math.max(amount - (empty ? drawer.getAcceptingMaxCapacity(stack) : drawer.getAcceptingRemainingCapacity()), 0)
10641052
: drawer.adjustStoredItemCount(amount);
1065-
1053+
// Once we have fit all the items, we do not need to continue.
10661054
if (amount == 0)
10671055
break;
10681056
}
10691057
}
10701058

1071-
if (!rebalance.isEmpty())
1059+
if (needRebalance && !rebalance.isEmpty())
10721060
StorageUtil.rebalanceDrawers(rebalance.stream());
10731061

10741062
return (amount == 0)
10751063
? ItemStack.EMPTY
10761064
: stackResult(stack, amount);
10771065
}
10781066

1067+
private @Nullable IDrawer getValidDrawer(@NotNull ItemStack stack, Predicate<ItemStack> predicate, SlotRecord record) {
1068+
IDrawerGroup candidateGroup = getGroupForSlotRecord(record);
1069+
if (candidateGroup == null)
1070+
return null;
1071+
IDrawer drawer = candidateGroup.getDrawer(record.slot);
1072+
if (!isValidDrawer(stack, predicate, drawer, candidateGroup)) return null;
1073+
return drawer;
1074+
}
1075+
1076+
private boolean isValidDrawer(@NotNull ItemStack stack, Predicate<ItemStack> predicate, IDrawer drawer, IDrawerGroup candidateGroup) {
1077+
if (!testPredicateInsert(drawer, stack, predicate))
1078+
return false;
1079+
1080+
if (!hasAccess(candidateGroup, drawer))
1081+
return false;
1082+
1083+
IDrawerAttributes attrs = drawer.getAttributes();
1084+
if (attrs.isSuspended())
1085+
return false;
1086+
1087+
return true;
1088+
}
1089+
10791090
@NotNull
10801091
@Override
10811092
public ItemStack extractItem (@NotNull ItemStack stack, int amount, boolean simulate, Predicate<ItemStack> predicate) {

0 commit comments

Comments
 (0)