From dbf28efe895dfbf465351a873db3061a620ef29a Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 23 Jun 2023 23:42:30 +0700 Subject: [PATCH] Optimize Container.balance --- .../ru/dbotthepony/mc/otm/container/Ext.kt | 23 +++++++++++-------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/container/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/container/Ext.kt index 89024f2bf..94024d62d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/container/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/container/Ext.kt @@ -13,6 +13,7 @@ import net.minecraftforge.fluids.capability.IFluidHandler import ru.dbotthepony.mc.otm.core.addAll import ru.dbotthepony.mc.otm.core.collect.iterator import ru.dbotthepony.mc.otm.core.collect.nonEmpty +import ru.dbotthepony.mc.otm.core.isNotEmpty import kotlin.math.roundToInt operator fun Container.set(index: Int, value: ItemStack) = setItem(index, value) @@ -119,7 +120,7 @@ inline fun Container.forEachNonEmpty(lambda: (ItemStack) -> Unit) { } fun Container.balance(slots: IntSet) { - if (slots.isEmpty()) return + if (slots.isEmpty() || !slots.any { getItem(it).isNotEmpty }) return val empty = IntArrayList() val itemTypes = Object2ObjectOpenCustomHashMap(ItemStackHashStrategy) @@ -140,12 +141,15 @@ fun Container.balance(slots: IntSet) { // только один вид предмета, просто балансируем его во все слоты if (itemTypes.size == 1) { val (item, list) = itemTypes.entries.first() - var count = list.stream().mapToInt { getItem(it).count }.sum() + var count = 0 + for (i in list.intIterator()) count += getItem(i).count + var ghostChanges = false // всего предметов меньше, чем слотов if (count < slots.size) { for (slot in list.intIterator()) { getItem(slot).count = 1 + ghostChanges = true } count -= list.size @@ -157,6 +161,7 @@ fun Container.balance(slots: IntSet) { if (count > 0) { getItem(list.firstInt()).count += count + ghostChanges = true } } else { // всего предметов больше, чем слотов @@ -164,17 +169,17 @@ fun Container.balance(slots: IntSet) { var leftover = count - perSlot * slots.size for (i in slots.intIterator()) { - setItem(i, item.copyWithCount(perSlot)) - } + val target = perSlot + leftover.coerceAtMost(1) - for (i in slots.intIterator()) { - if (leftover <= 0) break - getItem(i).count++ - leftover-- + if (getItem(i).count != target) { + setItem(i, item.copyWithCount(target)) + } + + if (leftover > 0) leftover-- } } - setChanged() + if (ghostChanges) setChanged() return }