Snapshot change events on each frame, to avoid event spam when attached inventory
reconstruct slot list (hi Ender Rift)
This commit is contained in:
parent
c24c8a9a80
commit
7c0c43dbb4
@ -28,6 +28,7 @@ import ru.dbotthepony.mc.otm.capability.WorkerEnergyStorage
|
||||
import ru.dbotthepony.mc.otm.container.ItemFilter
|
||||
import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
||||
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.graph.Graph6Node
|
||||
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 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>
|
||||
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")
|
||||
scannedMap.children.remove(slot)
|
||||
val count = scannedMap.stack.count
|
||||
scannedMap.stack.count -= item.stack.count.toBigInteger()
|
||||
|
||||
if (scannedMap.stack.count.isPositive) {
|
||||
for (listener in listeners) {
|
||||
listener.changeStack(scannedMap, count)
|
||||
}
|
||||
val snapshot = snapshot
|
||||
|
||||
if (snapshot != null) {
|
||||
snapshot.change(scannedMap.id, -item.stack.count.toBigInteger())
|
||||
} else {
|
||||
for (listener in listeners) {
|
||||
listener.removeStack(scannedMap)
|
||||
scannedMap.stack.count -= item.stack.count.toBigInteger()
|
||||
|
||||
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
|
||||
item.stack.count += diff
|
||||
scannedMap.stack.count += diff.toBigInteger()
|
||||
|
||||
for (listener in listeners) {
|
||||
listener.changeStack(scannedMap.stack, scannedMap.id, oldCount)
|
||||
val snapshot = snapshot
|
||||
|
||||
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
|
||||
} else {
|
||||
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())
|
||||
@ -277,8 +343,14 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
||||
listener.addStack(tuple.stack, tuple.id, this)
|
||||
}
|
||||
} else {
|
||||
for (listener in listeners) {
|
||||
listener.changeStack(tuple.stack, tuple.id, oldCount)
|
||||
val snapshot = snapshot
|
||||
|
||||
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() {
|
||||
sizeScan()
|
||||
|
||||
snapshot = EventsSnapshot()
|
||||
|
||||
for (slot in 0 until parent.slots) {
|
||||
scan(slot)
|
||||
}
|
||||
|
||||
snapshot!!.apply()
|
||||
snapshot = null
|
||||
}
|
||||
|
||||
override fun insertStack(stack: ItemStackWrapper, simulate: Boolean): ItemStackWrapper {
|
||||
|
Loading…
Reference in New Issue
Block a user