Fast implementation of some methods in EnhancedContainer

This commit is contained in:
DBotThePony 2025-03-14 22:14:05 +07:00
parent 448041fe2e
commit 69d9aaab50
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -1,5 +1,6 @@
package ru.dbotthepony.mc.otm.container package ru.dbotthepony.mc.otm.container
import it.unimi.dsi.fastutil.ints.IntCollection
import it.unimi.dsi.fastutil.ints.IntOpenHashSet import it.unimi.dsi.fastutil.ints.IntOpenHashSet
import net.minecraft.core.HolderLookup.Provider import net.minecraft.core.HolderLookup.Provider
import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.CompoundTag
@ -12,9 +13,14 @@ import net.minecraft.world.entity.player.Player
import net.minecraft.world.item.ItemStack import net.minecraft.world.item.ItemStack
import net.neoforged.neoforge.common.util.INBTSerializable import net.neoforged.neoforge.common.util.INBTSerializable
import org.apache.logging.log4j.LogManager import org.apache.logging.log4j.LogManager
import ru.dbotthepony.kommons.collect.iterateClearBits
import ru.dbotthepony.kommons.collect.iterateSetBits
import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer import ru.dbotthepony.mc.otm.container.slotted.SlottedContainer
import ru.dbotthepony.mc.otm.core.collect.IntRange2Set
import ru.dbotthepony.mc.otm.core.collect.map
import ru.dbotthepony.mc.otm.core.isNotEmpty import ru.dbotthepony.mc.otm.core.isNotEmpty
import ru.dbotthepony.mc.otm.core.nbt.set import ru.dbotthepony.mc.otm.core.nbt.set
import java.util.BitSet
/** /**
* Flexible base implementation of [IEnhancedContainer], designed to be inherited, or used as-is * Flexible base implementation of [IEnhancedContainer], designed to be inherited, or used as-is
@ -26,6 +32,55 @@ import ru.dbotthepony.mc.otm.core.nbt.set
abstract class EnhancedContainer<out S : IContainerSlot>(private val size: Int) : IEnhancedContainer<S>, INBTSerializable<CompoundTag> { abstract class EnhancedContainer<out S : IContainerSlot>(private val size: Int) : IEnhancedContainer<S>, INBTSerializable<CompoundTag> {
private val items = Array(size) { ItemStack.EMPTY } private val items = Array(size) { ItemStack.EMPTY }
private val observedItems = Array(size) { ItemStack.EMPTY } private val observedItems = Array(size) { ItemStack.EMPTY }
private val bitmap = BitSet(size)
final override fun isEmpty(): Boolean {
return bitmap.isEmpty
}
final override fun nextEmptySlot(startIndex: Int): Int {
if (startIndex >= size)
return -1
else if (startIndex < 0)
return bitmap.nextClearBit(0)
else
return bitmap.nextClearBit(startIndex)
}
final override fun nextNonEmptySlot(startIndex: Int): Int {
if (startIndex >= size)
return -1
else if (startIndex < 0)
return bitmap.nextSetBit(0)
else
return bitmap.nextSetBit(startIndex)
}
final override fun iterator(): Iterator<ItemStack> {
return bitmap.iterateSetBits(size).map { this[it] }
}
final override fun nonEmptySlotIndexIterator(): IntIterator {
return bitmap.iterateSetBits(size)
}
final override fun emptySlotIndexIterator(): IntIterator {
return bitmap.iterateClearBits(size)
}
final override fun emptySlotIndexIterator(allowedSlots: IntCollection): IntIterator {
if (allowedSlots is IntRange2Set && allowedSlots.isNotEmpty())
return bitmap.iterateClearBits(allowedSlots.firstInt(), allowedSlots.lastInt() + 1)
return super.emptySlotIndexIterator(allowedSlots)
}
final override fun nonEmptySlotIndexIterator(allowedSlots: IntCollection): IntIterator {
if (allowedSlots is IntRange2Set && allowedSlots.isNotEmpty())
return bitmap.iterateSetBits(allowedSlots.firstInt(), allowedSlots.lastInt() + 1)
return super.nonEmptySlotIndexIterator(allowedSlots)
}
protected open fun notifySlotChanged(slot: Int, old: ItemStack) {} protected open fun notifySlotChanged(slot: Int, old: ItemStack) {}
@ -36,9 +91,11 @@ abstract class EnhancedContainer<out S : IContainerSlot>(private val size: Int)
if (items[slot].isEmpty) { if (items[slot].isEmpty) {
items[slot] = ItemStack.EMPTY items[slot] = ItemStack.EMPTY
observedItems[slot] = ItemStack.EMPTY observedItems[slot] = ItemStack.EMPTY
bitmap[slot] = false
} else { } else {
notifySlotChanged(slot, observedItems[slot]) notifySlotChanged(slot, observedItems[slot])
observedItems[slot] = items[slot].copy() observedItems[slot] = items[slot].copy()
bitmap[slot] = true
} }
} }
} }
@ -50,6 +107,7 @@ abstract class EnhancedContainer<out S : IContainerSlot>(private val size: Int)
override fun clearContent() { override fun clearContent() {
items.fill(ItemStack.EMPTY) items.fill(ItemStack.EMPTY)
observedItems.fill(ItemStack.EMPTY) observedItems.fill(ItemStack.EMPTY)
bitmap.clear()
} }
override fun setChanged() { override fun setChanged() {
@ -146,6 +204,7 @@ abstract class EnhancedContainer<out S : IContainerSlot>(private val size: Int)
val copy = observedItems.copyOf() val copy = observedItems.copyOf()
items.fill(ItemStack.EMPTY) items.fill(ItemStack.EMPTY)
observedItems.fill(ItemStack.EMPTY) observedItems.fill(ItemStack.EMPTY)
bitmap.clear()
val seenSlots = IntOpenHashSet() val seenSlots = IntOpenHashSet()
val ops = provider.createSerializationContext(NbtOps.INSTANCE) val ops = provider.createSerializationContext(NbtOps.INSTANCE)
@ -166,6 +225,7 @@ abstract class EnhancedContainer<out S : IContainerSlot>(private val size: Int)
if (it.isNotEmpty) { if (it.isNotEmpty) {
items[slot] = it items[slot] = it
observedItems[slot] = it.copy() observedItems[slot] = it.copy()
bitmap[slot] = true
if (it.count != copy[slot].count || !ItemStack.isSameItemSameComponents(it, copy[slot])) if (it.count != copy[slot].count || !ItemStack.isSameItemSameComponents(it, copy[slot]))
notifySlotChanged(slot, copy[slot]) notifySlotChanged(slot, copy[slot])