diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt index 77196304a..17a67f16b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageBusBlockEntity.kt @@ -40,12 +40,13 @@ import ru.dbotthepony.mc.otm.registry.MNames import ru.dbotthepony.mc.otm.storage.* import java.lang.ref.WeakReference import java.math.BigInteger +import java.util.* import java.util.stream.Stream import kotlin.collections.ArrayList import kotlin.collections.HashMap private class SlotTuple(val slot: Int, val stack: ItemStack) -private class TrackedTuple(override val stack: ItemStackWrapper, override val id: Long) : IStorageTuple { +private class TrackedTuple(override val stack: ItemStackWrapper, override val id: UUID) : IStorageTuple { val children = Int2ObjectAVLTreeMap() override fun toString(): String { @@ -188,9 +189,9 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter private inner class ItemHandlerComponent(private val parent: IItemHandler) : IStorageComponent { private inner class EventsSnapshot { - val index = Long2ObjectAVLTreeMap() + val index = HashMap() - fun change(key: Long, diff: BigInteger) { + fun change(key: UUID, diff: BigInteger) { if (diff.isZero) return @@ -241,8 +242,6 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter private val listeners = ArrayList>() - private var nextID = 0L - override fun addListener(listener: IStorageEventConsumer): Boolean { if (!listeners.contains(listener)) { listeners.add(listener) @@ -259,7 +258,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter private var scanned = arrayOfNulls(0) private var scannedMap = arrayOfNulls(0) private val tuples = HashMap() - private val index = Long2ObjectAVLTreeMap() + private val index = HashMap() private fun removeTracked(slot: Int) { scanned[slot] = null @@ -324,7 +323,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter var oldCount = BigInteger.ZERO if (added) { - tuple = TrackedTuple(storageStack, nextID++) + tuple = TrackedTuple(storageStack, UUID.randomUUID()) index[tuple.id] = tuple tuples[key] = tuple } else { @@ -462,11 +461,11 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter } } - override fun get(id: Long): ItemStackWrapper { + override fun get(id: UUID): ItemStackWrapper { return index[id]?.stack ?: ItemStackWrapper.EMPTY } - override fun extractStack(id: Long, amount: BigInteger, simulate: Boolean): ItemStackWrapper { + override fun extractStack(id: UUID, amount: BigInteger, simulate: Boolean): ItemStackWrapper { if (!amount.isPositive) return ItemStackWrapper.EMPTY diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt index 99ca61a76..6a6f89155 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/storage/StorageInterfaces.kt @@ -37,7 +37,9 @@ import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MNames import ru.dbotthepony.mc.otm.storage.* import java.math.BigInteger +import java.util.* import java.util.stream.Stream +import kotlin.collections.HashSet abstract class AbstractStorageImportExport( blockType: BlockEntityType<*>, @@ -271,7 +273,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : return StorageExporterMenu(containerID, inventory, this) } - private val relevantTuples = LongArraySet() + private val relevantTuples = HashSet() override val storageType: StorageStackType get() = ITEM_STORAGE @@ -280,7 +282,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : cell.addStorageComponent(this) } - override fun addStack(stack: ItemStackWrapper, id: Long, provider: IStorageProvider) { + override fun addStack(stack: ItemStackWrapper, id: UUID, provider: IStorageProvider) { if (!filter.match(stack.item)) { return } @@ -288,11 +290,11 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : relevantTuples.add(id) } - override fun changeStack(stack: ItemStackWrapper, id: Long, oldCount: BigInteger) { + override fun changeStack(stack: ItemStackWrapper, id: UUID, oldCount: BigInteger) { // no-op } - override fun removeStack(stack: ItemStackWrapper, id: Long) { + override fun removeStack(stack: ItemStackWrapper, id: UUID) { relevantTuples.remove(id) } @@ -317,7 +319,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : override val targetCapability: Capability get() = CapabilityItemHandler.ITEM_HANDLER_CAPABILITY - private val exportStacks: Stream> + private val exportStacks: Stream> get() { val view = cell.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: return Stream.empty() return relevantTuples.stream().map { it to view[it] } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt index 462835b92..a9039d0c9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/drive/AbstractMatteryDrive.kt @@ -27,7 +27,7 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor var maxDifferentStacks: Int = 0xFFFF ) : IMatteryDrive { protected val tuples = HashMap>() - protected val tuplesByID: MutableMap> = Long2ObjectAVLTreeMap() + protected val tuplesByID: MutableMap> = HashMap() override var isDirty = false set(value) { @@ -41,8 +41,6 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor var storedDifferentStacks = 0 protected set - protected var nextID = 0L - override var storedCount: BigInteger = BigInteger.ZERO protected set @@ -83,7 +81,7 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor val copy = stack.copy() as T copy.count = maxInsert - val state = StorageTuple(nextID++, copy) + val state = StorageTuple(UUID.randomUUID(), copy) tuples[key] = state tuplesByID[state.id] = state @@ -100,7 +98,7 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor } @Suppress("unchecked_cast") - override fun extractStack(id: Long, amount: BigInteger, simulate: Boolean): T { + override fun extractStack(id: UUID, amount: BigInteger, simulate: Boolean): T { val get = tuplesByID[id] ?: return storageType.empty @Suppress("NAME_SHADOWING") @@ -194,7 +192,7 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor if (stack != null) { storedCount += stack.count storedDifferentStacks++ - val tuple = StorageTuple(nextID++, stack) + val tuple = StorageTuple(UUID.randomUUID(), stack) tuples[tuple.stack.key()] = tuple tuplesByID[tuple.id] = tuple } @@ -202,7 +200,7 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor } } - override fun get(id: Long): T { + override fun get(id: UUID): T { return tuplesByID[id]?.stack ?: storageType.empty } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/mekanism/QIO.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/mekanism/QIO.kt index fdb34ff80..1b32df8fc 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/compat/mekanism/QIO.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/compat/mekanism/QIO.kt @@ -37,7 +37,7 @@ private val QIO_LOCATION = ResourceLocation(OverdriveThatMatters.MOD_ID, "item_s private class QIOTuple( val mekanismItem: HashedItem, override val stack: ItemStackWrapper, - override val id: Long, + override val id: UUID, var mark: Long ) : IStorageTuple @@ -47,13 +47,11 @@ private class QIOFrequencyAccess(val parent: QIOFrequency) : IStorageComponent get() = OverdriveThatMatters.INSTANCE.ITEM_STORAGE() - private val index = Long2ObjectAVLTreeMap() + private val index = HashMap() private val tracked = HashMap() private val listeners = ArrayList>() - private var nextID = 0L - - override fun get(id: Long): ItemStackWrapper { + override fun get(id: UUID): ItemStackWrapper { return index[id]?.stack ?: ItemStackWrapper.EMPTY } @@ -90,7 +88,7 @@ private class QIOFrequencyAccess(val parent: QIOFrequency) : IStorageComponent { - data class NetworkedItem constructor(val id: Int, val stack: ItemStack, val upstreamId: Long? = null) + data class NetworkedItem constructor(val id: Int, val stack: ItemStack, val upstreamId: UUID? = null) override val storageType: StorageStackType get() = ITEM_STORAGE - protected var nextStackID = 0 // this (how client see and interact with) val localState = Int2ObjectAVLTreeMap() @@ -194,7 +193,7 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote: } // parent (e.g. VirtualComponent) - protected val upstreamState = Long2ObjectAVLTreeMap() + protected val upstreamState = HashMap() protected val networkBacklog = ArrayList() operator fun get(id: Int): NetworkedItem? = localState[id] @@ -232,8 +231,8 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote: return localState.values.size } - override fun addStack(stack: ItemStackWrapper, id: Long, provider: IStorageProvider) = addObject(stack.stack, id) - override fun changeStack(stack: ItemStackWrapper, id: Long, oldCount: BigInteger) = changeObject(id, stack.count.toInt()) + override fun addStack(stack: ItemStackWrapper, id: UUID, provider: IStorageProvider) = addObject(stack.stack, id) + override fun changeStack(stack: ItemStackWrapper, id: UUID, oldCount: BigInteger) = changeObject(id, stack.count.toInt()) protected fun network(fn: () -> Any) { if (!remote) { @@ -241,24 +240,26 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote: } } - override fun removeStack(stack: ItemStackWrapper, id: Long) { + override fun removeStack(stack: ItemStackWrapper, id: UUID) { val get = upstreamState[id] ?: throw IllegalStateException("Unknown ItemStack with upstream id $id!") upstreamState.remove(id) localState.remove(get.id) network { StackRemovePacket(menu.containerId, get.id) } } - fun addObject(stack: ItemStack, id_upstream: Long) { + protected var nextItemID = 0 + + fun addObject(stack: ItemStack, id_upstream: UUID) { check(!upstreamState.containsKey(id_upstream)) { "Already tracking ItemStack with upstream id $id_upstream!" } - val state = NetworkedItem(nextStackID++, stack.copy(), id_upstream) + val state = NetworkedItem(nextItemID++, stack.copy(), id_upstream) this.localState[state.id] = state upstreamState[id_upstream] = state network { StackAddPacket(menu.containerId, state.id, stack) } } - fun changeObject(id_upstream: Long, new_count: Int) { + fun changeObject(id_upstream: UUID, new_count: Int) { val get = upstreamState[id_upstream] ?: throw IllegalStateException("Unknown ItemStack with upstream id $id_upstream!") get.stack.count = new_count network { StackChangePacket(menu.containerId, get.id, new_count) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/API.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/API.kt index d051cdbfb..310bc98ca 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/API.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/API.kt @@ -86,17 +86,17 @@ interface IStorageEventConsumer : IStorage { /** * Fired on whenever an object is added (to listener) we subscribed to */ - fun addStack(stack: T, id: Long, provider: IStorageProvider) + fun addStack(stack: T, id: UUID, provider: IStorageProvider) /** * Fired on whenever an object is changes on listener we subscribed to */ - fun changeStack(stack: T, id: Long, oldCount: BigInteger) + fun changeStack(stack: T, id: UUID, oldCount: BigInteger) /** * Fired on whenever an object is removed from listener we subscribed to */ - fun removeStack(stack: T, id: Long) + fun removeStack(stack: T, id: UUID) } interface IStorageAcceptor : IStorage { @@ -112,7 +112,7 @@ interface IStorageProvider : IStorageEventProducer { * @param id identifier of stack * @return stored object (not a copy). Do not edit it. */ - operator fun get(id: Long): T + operator fun get(id: UUID): T val stacks: Stream> @@ -124,7 +124,7 @@ interface IStorageProvider : IStorageEventProducer { * @param simulate whenever to simulate the action or not * @return copy of object, with amount of units actually extracted */ - fun extractStack(id: Long, amount: BigInteger, simulate: Boolean): T + fun extractStack(id: UUID, amount: BigInteger, simulate: Boolean): T } fun IStorageProvider.removeListenerAuto(listener: IStorageEventConsumer): Boolean { @@ -166,11 +166,11 @@ fun IStorageEventConsumer.removeStack(tuple: IStorageTupl } interface IStorageTuple { - val id: Long + val id: UUID val stack: T } -class StorageTuple(override val id: Long, override val stack: T) : IStorageTuple +class StorageTuple(override val id: UUID, override val stack: T) : IStorageTuple /** * Component which (most time) proxy other components (combine their contents into single view) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/VirtualComponent.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/VirtualComponent.kt index e49692a19..bcce72458 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/VirtualComponent.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/VirtualComponent.kt @@ -13,7 +13,7 @@ import kotlin.reflect.full.isSubclassOf class RemoteTuple( override val stack: T, - override val id: Long, + override val id: UUID, val provider: IStorageProvider, val local: LocalTuple ) : IStorageTuple { @@ -30,7 +30,7 @@ class RemoteTuple( } } -class LocalTuple(override val stack: T, override val id: Long, val tuples: ArrayList>) : IStorageTuple +class LocalTuple(override val stack: T, override val id: UUID, val tuples: ArrayList>) : IStorageTuple open class VirtualComponent(type: StorageStackType) : IVirtualStorageComponent { constructor(type: Class) : this(StorageRegistry.get(type)) @@ -38,21 +38,19 @@ open class VirtualComponent(type: StorageStackType) : IVir override val storageType: StorageStackType = type // удаленный UUID -> Кортеж - protected val remoteTuples = Long2ObjectAVLTreeMap>() + protected val remoteTuples = HashMap>() // локальный UUID -> Локальный кортеж - protected val localTuples = Long2ObjectAVLTreeMap>() + protected val localTuples = HashMap>() // Стак -> Локальный кортеж стака - protected val hashedTuples: MutableMap> = HashMap() + protected val hashedTuples = HashMap>() // ArrayList для скорости работы protected val listeners: MutableSet> = ObjectArraySet() protected val children: MutableSet> = ObjectArraySet() protected val consumers: MutableSet> = ObjectArraySet() - private var nextID = 0L - protected open fun onAdd(identity: IStorage) {} protected open fun onRemove(identity: IStorage) {} @@ -118,7 +116,7 @@ open class VirtualComponent(type: StorageStackType) : IVir return listeners.remove(listener) } - override fun get(id: Long): T { + override fun get(id: UUID): T { return localTuples[id]?.stack ?: this.storageType.empty } @@ -127,7 +125,7 @@ open class VirtualComponent(type: StorageStackType) : IVir } @Suppress("unchecked_cast") - override fun addStack(stack: T, id: Long, provider: IStorageProvider) { + override fun addStack(stack: T, id: UUID, provider: IStorageProvider) { check(!remoteTuples.containsKey(id)) { "Already tracking tuple with id $id" } val key = stack.key() @@ -136,7 +134,7 @@ open class VirtualComponent(type: StorageStackType) : IVir val added = local == null if (local == null) { - local = LocalTuple(stack.copy() as T, nextID++, ArrayList>(1)) + local = LocalTuple(stack.copy() as T, UUID.randomUUID(), ArrayList>(1)) localTuples[local.id] = local hashedTuples[key] = local } else { @@ -159,7 +157,7 @@ open class VirtualComponent(type: StorageStackType) : IVir } } - override fun changeStack(stack: T, id: Long, oldCount: BigInteger) { + override fun changeStack(stack: T, id: UUID, oldCount: BigInteger) { require(stack.count.isPositive) val tuple = remoteTuples[id] ?: throw IllegalStateException("No such tuple with id $id") @@ -174,7 +172,7 @@ open class VirtualComponent(type: StorageStackType) : IVir } } - override fun removeStack(stack: T, id: Long) { + override fun removeStack(stack: T, id: UUID) { val tuple = remoteTuples[id] ?: throw IllegalStateException("No such tuple with id $id") tuple.local.stack.shrink(tuple.stack.count) @@ -212,7 +210,7 @@ open class VirtualComponent(type: StorageStackType) : IVir } @Suppress("unchecked_cast") - override fun extractStack(id: Long, amount: BigInteger, simulate: Boolean): T { + override fun extractStack(id: UUID, amount: BigInteger, simulate: Boolean): T { if (!amount.isPositive) return this.storageType.empty @@ -318,9 +316,9 @@ open class PoweredComponent(open val parent: IStorageComponen return stack } - override fun get(id: Long) = parent[id] + override fun get(id: UUID) = parent[id] - override fun extractStack(id: Long, amount: BigInteger, simulate: Boolean): T { + override fun extractStack(id: UUID, amount: BigInteger, simulate: Boolean): T { val required = storageType.energyPerOperation * amount val energy = energyProvider.invoke() val extracted = energy.extractEnergyInner(required, true) @@ -374,9 +372,9 @@ open class PoweredVirtualComponent(override val parent: IVirt constructor(parent: Class, energy: IMatteryEnergyStorage) : this(VirtualComponent(parent), { energy }) constructor(parent: StorageStackType, energy: IMatteryEnergyStorage) : this(VirtualComponent(parent), { energy }) - override fun addStack(stack: T, id: Long, provider: IStorageProvider) = parent.addStack(stack, id, provider) - override fun changeStack(stack: T, id: Long, oldCount: BigInteger) = parent.changeStack(stack, id, oldCount) - override fun removeStack(stack: T, id: Long) = parent.removeStack(stack, id) + override fun addStack(stack: T, id: UUID, provider: IStorageProvider) = parent.addStack(stack, id, provider) + override fun changeStack(stack: T, id: UUID, oldCount: BigInteger) = parent.changeStack(stack, id, oldCount) + override fun removeStack(stack: T, id: UUID) = parent.removeStack(stack, id) override fun add(identity: IStorage) = parent.add(identity) override fun remove(identity: IStorage) = parent.remove(identity)