From 834b05a697c0bb1421c117ded0bd2131a51f27d3 Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Thu, 10 Aug 2023 13:15:43 +0700 Subject: [PATCH] Fix very obscure (undetected by HashSet) concurrent modification --- .../block/entity/storage/StorageInterfaces.kt | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt index e5348811e..2a5db7efc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.block.entity.storage +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet import net.minecraft.core.BlockPos import net.minecraft.network.chat.Component import net.minecraft.world.entity.player.Inventory @@ -39,6 +40,7 @@ import ru.dbotthepony.mc.otm.storage.StorageStack import java.math.BigInteger import java.util.* import java.util.stream.Stream +import kotlin.collections.ArrayList abstract class AbstractStorageImportExport( blockType: BlockEntityType<*>, @@ -235,7 +237,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : return StorageExporterMenu(containerID, inventory, this) } - private val relevantTuples = HashSet() + private val relevantTuples = ObjectOpenHashSet() override val storageType: StorageStack.Type get() = StorageStack.ITEMS @@ -280,12 +282,6 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : override val targetCapability: Capability get() = ForgeCapabilities.ITEM_HANDLER - private val exportStacks: Stream> - get() { - val view = cell.graph.getVirtualComponent(StorageStack.ITEMS) - return relevantTuples.stream().map { it to view[it] } - } - override fun tick() { super.tick() @@ -305,16 +301,16 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : lastSlot = 0 } - val any = exportStacks.anyMatch { - val (id, stack) = it + val any = ArrayList(relevantTuples).any { id -> + val stack = items[id] - if (!target.isItemValid(lastSlot, stack.toItemStack())) return@anyMatch false + if (stack.isEmpty || !target.isItemValid(lastSlot, stack.toItemStack())) return@any false val extracted = items.extractStack(id, stack.count.coerceAtMost(MAX_MOVE_PER_OPERATION), true) - if (extracted.isEmpty) return@anyMatch false + if (extracted.isEmpty) return@any false val required = StorageStack.ITEMS.energyPerOperation(extracted) - if (energy.extractEnergy(required, true) != required) return@anyMatch false + if (energy.extractEnergy(required, true) != required) return@any false val toInsert = extracted.toItemStack() val leftover = target.insertItem(lastSlot, toInsert, true)