Fix very obscure (undetected by HashSet) concurrent modification

This commit is contained in:
DBotThePony 2023-08-10 13:15:43 +07:00
parent 506017f055
commit 834b05a697
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -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<T>(
blockType: BlockEntityType<*>,
@ -235,7 +237,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
return StorageExporterMenu(containerID, inventory, this)
}
private val relevantTuples = HashSet<UUID>()
private val relevantTuples = ObjectOpenHashSet<UUID>()
override val storageType: StorageStack.Type<ItemStorageStack>
get() = StorageStack.ITEMS
@ -280,12 +282,6 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
override val targetCapability: Capability<IItemHandler>
get() = ForgeCapabilities.ITEM_HANDLER
private val exportStacks: Stream<Pair<UUID, ItemStorageStack>>
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)