Fast implementation of some methods in EnhancedContainer
This commit is contained in:
parent
448041fe2e
commit
69d9aaab50
@ -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])
|
||||||
|
Loading…
Reference in New Issue
Block a user