Snapshot change events on each frame, to avoid event spam when attached inventory

reconstruct slot list (hi Ender Rift)
This commit is contained in:
DBotThePony 2022-06-08 19:27:29 +07:00
parent c24c8a9a80
commit 7c0c43dbb4
Signed by: DBot
GPG Key ID: DCC23B5715498507

View File

@ -28,6 +28,7 @@ import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
import ru.dbotthepony.mc.otm.container.ItemFilter import ru.dbotthepony.mc.otm.container.ItemFilter
import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.core.ImpreciseFraction
import ru.dbotthepony.mc.otm.core.isPositive import ru.dbotthepony.mc.otm.core.isPositive
import ru.dbotthepony.mc.otm.core.isZero
import ru.dbotthepony.mc.otm.core.plus import ru.dbotthepony.mc.otm.core.plus
import ru.dbotthepony.mc.otm.graph.Graph6Node import ru.dbotthepony.mc.otm.graph.Graph6Node
import ru.dbotthepony.mc.otm.graph.GraphNodeListener import ru.dbotthepony.mc.otm.graph.GraphNodeListener
@ -186,6 +187,55 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
} }
private inner class ItemHandlerComponent(private val parent: IItemHandler) : IStorageComponent<ItemStackWrapper> { private inner class ItemHandlerComponent(private val parent: IItemHandler) : IStorageComponent<ItemStackWrapper> {
private inner class EventsSnapshot {
val index = Long2ObjectAVLTreeMap<BigInteger>()
fun change(key: Long, diff: BigInteger) {
if (diff.isZero)
return
val value = index[key]
if (value == null) {
index[key] = diff
} else {
val newvalue = value + diff
if (newvalue.isZero) {
index.remove(key)
} else {
index[key] = newvalue
}
}
}
fun apply() {
for ((key, value) in index) {
val tuple = checkNotNull(this@ItemHandlerComponent.index[key]) { "Tuple with ID $key is missing!" }
val count = tuple.stack.count
tuple.stack.count += value
if (tuple.stack.count.isPositive) {
for (listener in listeners) {
listener.changeStack(tuple, count)
}
} else {
for (listener in listeners) {
listener.removeStack(tuple)
}
this@ItemHandlerComponent.index.remove(tuple.id)
val tuplekey = tuple.stack.key()
tuples.remove(tuplekey) ?: throw IllegalStateException("Cross-reference integrity check failed for $tuple")
}
}
}
}
private var snapshot: EventsSnapshot? = null
override val storageType: StorageStackType<ItemStackWrapper> override val storageType: StorageStackType<ItemStackWrapper>
get() = ITEM_STORAGE get() = ITEM_STORAGE
@ -219,21 +269,28 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
val item = scannedMap.children[slot] ?: throw IllegalStateException("${scannedMap.id} does not track $slot") val item = scannedMap.children[slot] ?: throw IllegalStateException("${scannedMap.id} does not track $slot")
scannedMap.children.remove(slot) scannedMap.children.remove(slot)
val count = scannedMap.stack.count val count = scannedMap.stack.count
scannedMap.stack.count -= item.stack.count.toBigInteger()
if (scannedMap.stack.count.isPositive) { val snapshot = snapshot
for (listener in listeners) {
listener.changeStack(scannedMap, count) if (snapshot != null) {
} snapshot.change(scannedMap.id, -item.stack.count.toBigInteger())
} else { } else {
for (listener in listeners) { scannedMap.stack.count -= item.stack.count.toBigInteger()
listener.removeStack(scannedMap)
if (scannedMap.stack.count.isPositive) {
for (listener in listeners) {
listener.changeStack(scannedMap, count)
}
} else {
for (listener in listeners) {
listener.removeStack(scannedMap)
}
index.remove(scannedMap.id)
val key = scannedMap.stack.key()
tuples.remove(key) ?: throw IllegalStateException("Item tuple is not present for slot $slot at ${scannedMap.stack}")
} }
index.remove(scannedMap.id)
val key = scannedMap.stack.key()
tuples.remove(key) ?: throw IllegalStateException("Item tuple is not present for slot $slot at ${scannedMap.stack}")
} }
} }
@ -243,10 +300,17 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
val oldCount = scannedMap.stack.count val oldCount = scannedMap.stack.count
item.stack.count += diff item.stack.count += diff
scannedMap.stack.count += diff.toBigInteger()
for (listener in listeners) { val snapshot = snapshot
listener.changeStack(scannedMap.stack, scannedMap.id, oldCount)
if (snapshot != null) {
snapshot.change(scannedMap.id, diff.toBigInteger())
} else {
scannedMap.stack.count += diff.toBigInteger()
for (listener in listeners) {
listener.changeStack(scannedMap.stack, scannedMap.id, oldCount)
}
} }
} }
@ -265,7 +329,9 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
tuples[key] = tuple tuples[key] = tuple
} else { } else {
oldCount = tuple!!.stack.count oldCount = tuple!!.stack.count
tuple.stack.count += stack.count.toBigInteger()
if (snapshot == null)
tuple.stack.count += stack.count.toBigInteger()
} }
tuple.children[slot] = SlotTuple(slot, stack.copy()) tuple.children[slot] = SlotTuple(slot, stack.copy())
@ -277,8 +343,14 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
listener.addStack(tuple.stack, tuple.id, this) listener.addStack(tuple.stack, tuple.id, this)
} }
} else { } else {
for (listener in listeners) { val snapshot = snapshot
listener.changeStack(tuple.stack, tuple.id, oldCount)
if (snapshot != null) {
snapshot.change(tuple.id, stack.count.toBigInteger())
} else {
for (listener in listeners) {
listener.changeStack(tuple.stack, tuple.id, oldCount)
}
} }
} }
} }
@ -339,9 +411,14 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
fun scan() { fun scan() {
sizeScan() sizeScan()
snapshot = EventsSnapshot()
for (slot in 0 until parent.slots) { for (slot in 0 until parent.slots) {
scan(slot) scan(slot)
} }
snapshot!!.apply()
snapshot = null
} }
override fun insertStack(stack: ItemStackWrapper, simulate: Boolean): ItemStackWrapper { override fun insertStack(stack: ItemStackWrapper, simulate: Boolean): ItemStackWrapper {