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 package ru.dbotthepony.mc.otm.block.entity.storage
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet
import net.minecraft.core.BlockPos import net.minecraft.core.BlockPos
import net.minecraft.network.chat.Component import net.minecraft.network.chat.Component
import net.minecraft.world.entity.player.Inventory import net.minecraft.world.entity.player.Inventory
@ -39,6 +40,7 @@ import ru.dbotthepony.mc.otm.storage.StorageStack
import java.math.BigInteger import java.math.BigInteger
import java.util.* import java.util.*
import java.util.stream.Stream import java.util.stream.Stream
import kotlin.collections.ArrayList
abstract class AbstractStorageImportExport<T>( abstract class AbstractStorageImportExport<T>(
blockType: BlockEntityType<*>, blockType: BlockEntityType<*>,
@ -235,7 +237,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
return StorageExporterMenu(containerID, inventory, this) return StorageExporterMenu(containerID, inventory, this)
} }
private val relevantTuples = HashSet<UUID>() private val relevantTuples = ObjectOpenHashSet<UUID>()
override val storageType: StorageStack.Type<ItemStorageStack> override val storageType: StorageStack.Type<ItemStorageStack>
get() = StorageStack.ITEMS get() = StorageStack.ITEMS
@ -280,12 +282,6 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
override val targetCapability: Capability<IItemHandler> override val targetCapability: Capability<IItemHandler>
get() = ForgeCapabilities.ITEM_HANDLER 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() { override fun tick() {
super.tick() super.tick()
@ -305,16 +301,16 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
lastSlot = 0 lastSlot = 0
} }
val any = exportStacks.anyMatch { val any = ArrayList(relevantTuples).any { id ->
val (id, stack) = it 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) 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) 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 toInsert = extracted.toItemStack()
val leftover = target.insertItem(lastSlot, toInsert, true) val leftover = target.insertItem(lastSlot, toInsert, true)