diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageBusBlockEntity.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageBusBlockEntity.kt index e256fb9d2..f23e52ca6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageBusBlockEntity.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageBusBlockEntity.kt @@ -1,6 +1,7 @@ package ru.dbotthepony.mc.otm.block.entity import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap +import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.nbt.CompoundTag @@ -43,7 +44,7 @@ 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: UUID) : IStorageTuple { +private class TrackedTuple(override val stack: ItemStackWrapper, override val id: Long) : IStorageTuple { val children = Int2ObjectAVLTreeMap() override fun toString(): String { @@ -186,10 +187,12 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter private inner class ItemHandlerComponent(private val parent: IItemHandler) : IStorageComponent { override val storageType: StorageStackType - get() = OverdriveThatMatters.INSTANCE.ITEM_STORAGE() + get() = ITEM_STORAGE private val listeners = ArrayList>() + private var nextID = 0L + override fun addListener(listener: IStorageEventConsumer): Boolean { if (!listeners.contains(listener)) { listeners.add(listener) @@ -206,7 +209,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 = HashMap() + private val index = Long2ObjectAVLTreeMap() private fun removeTracked(slot: Int) { scanned[slot] = null @@ -257,7 +260,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter var oldCount = BigInteger.ZERO if (added) { - tuple = TrackedTuple(storageStack, UUID.randomUUID()) + tuple = TrackedTuple(storageStack, nextID++) index[tuple.id] = tuple tuples[key] = tuple } else { @@ -375,11 +378,11 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter return leftover } - override fun get(id: UUID): ItemStackWrapper { + override fun get(id: Long): ItemStackWrapper { return index[id]?.stack ?: ItemStackWrapper.EMPTY } - override fun extractStack(id: UUID, amount: BigInteger, simulate: Boolean): ItemStackWrapper { + override fun extractStack(id: Long, amount: BigInteger, simulate: Boolean): ItemStackWrapper { if (!amount.isPositive) return ItemStackWrapper.EMPTY diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageInterfaces.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageInterfaces.kt index 4537ec517..4d4aa435e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageInterfaces.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/entity/StorageInterfaces.kt @@ -1,5 +1,7 @@ package ru.dbotthepony.mc.otm.block.entity +import it.unimi.dsi.fastutil.longs.LongAVLTreeSet +import it.unimi.dsi.fastutil.longs.LongArraySet import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.nbt.CompoundTag @@ -272,9 +274,16 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : return StorageExporterMenu(containerID, inventory, this) } - private val relevantTuples = HashSet() + private val relevantTuples = LongArraySet() - override fun addStack(stack: ItemStackWrapper, id: UUID, provider: IStorageProvider) { + override val storageType: StorageStackType + get() = ITEM_STORAGE + + init { + cell.addStorageComponent(this) + } + + override fun addStack(stack: ItemStackWrapper, id: Long, provider: IStorageProvider) { if (!filter.match(stack.item)) { return } @@ -282,11 +291,11 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) : relevantTuples.add(id) } - override fun changeStack(stack: ItemStackWrapper, id: UUID, oldCount: BigInteger) { + override fun changeStack(stack: ItemStackWrapper, id: Long, oldCount: BigInteger) { // no-op } - override fun removeStack(stack: ItemStackWrapper, id: UUID) { + override fun removeStack(stack: ItemStackWrapper, id: Long) { relevantTuples.remove(id) } @@ -311,7 +320,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 916e50b9c..462835b92 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 @@ -1,12 +1,15 @@ package ru.dbotthepony.mc.otm.capability.drive +import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap import it.unimi.dsi.fastutil.objects.ObjectArraySet import kotlin.jvm.JvmOverloads import java.util.UUID import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.ListTag +import net.minecraft.nbt.LongTag import net.minecraft.nbt.Tag +import org.apache.logging.log4j.LogManager import ru.dbotthepony.mc.otm.core.BigInteger import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.core.isPositive @@ -16,7 +19,6 @@ import ru.dbotthepony.mc.otm.set import ru.dbotthepony.mc.otm.storage.* import java.math.BigInteger import java.util.ArrayList -import java.util.HashSet import java.util.stream.Stream abstract class AbstractMatteryDrive @JvmOverloads constructor( @@ -25,7 +27,7 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor var maxDifferentStacks: Int = 0xFFFF ) : IMatteryDrive { protected val tuples = HashMap>() - protected val tuplesByID = Object2ObjectAVLTreeMap>() + protected val tuplesByID: MutableMap> = Long2ObjectAVLTreeMap() override var isDirty = false set(value) { @@ -39,6 +41,8 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor var storedDifferentStacks = 0 protected set + protected var nextID = 0L + override var storedCount: BigInteger = BigInteger.ZERO protected set @@ -79,7 +83,7 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor val copy = stack.copy() as T copy.count = maxInsert - val state = StorageTuple(UUID.randomUUID(), copy) + val state = StorageTuple(nextID++, copy) tuples[key] = state tuplesByID[state.id] = state @@ -96,7 +100,7 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor } @Suppress("unchecked_cast") - override fun extractStack(id: UUID, amount: BigInteger, simulate: Boolean): T { + override fun extractStack(id: Long, amount: BigInteger, simulate: Boolean): T { val get = tuplesByID[id] ?: return storageType.empty @Suppress("NAME_SHADOWING") @@ -157,7 +161,6 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor val serialized = serializeStack(stack) if (serialized != null) { - serialized["id"] = longArrayOf(stack.id.mostSignificantBits, stack.id.leastSignificantBits) list.add(serialized) } } @@ -166,10 +169,17 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor } override fun deserializeNBT(nbt: CompoundTag) { + for (listener in listeners) { + for (get in tuples.values) { + listener.removeStack(get.stack, get.id) + } + } + tuples.clear() tuplesByID.clear() storedCount = BigInteger.ZERO storedDifferentStacks = 0 + // nextID = 0L nbt.ifHas("capacity") { driveCapacity = BigInteger(it) @@ -184,9 +194,7 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor if (stack != null) { storedCount += stack.count storedDifferentStacks++ - - val id = entry.getLongArray("id") - val tuple = StorageTuple(if (id.size == 2) UUID(id[0], id[1]) else UUID.randomUUID(), stack) + val tuple = StorageTuple(nextID++, stack) tuples[tuple.stack.key()] = tuple tuplesByID[tuple.id] = tuple } @@ -194,7 +202,7 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor } } - override fun get(id: UUID): T { + override fun get(id: Long): T { return tuplesByID[id]?.stack ?: storageType.empty } @@ -211,4 +219,8 @@ abstract class AbstractMatteryDrive @JvmOverloads constructor override fun removeListener(listener: IStorageEventConsumer): Boolean { return listeners.remove(listener) } + + companion object { + private val LOGGER = LogManager.getLogger() + } } \ No newline at end of file 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 af0926648..fdb34ff80 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 @@ -1,5 +1,6 @@ package ru.dbotthepony.mc.otm.compat.mekanism +import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap import it.unimi.dsi.fastutil.objects.Object2ObjectFunction @@ -36,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: UUID, + override val id: Long, var mark: Long ) : IStorageTuple @@ -46,11 +47,13 @@ private class QIOFrequencyAccess(val parent: QIOFrequency) : IStorageComponent get() = OverdriveThatMatters.INSTANCE.ITEM_STORAGE() - private val index = Object2ObjectAVLTreeMap() + private val index = Long2ObjectAVLTreeMap() private val tracked = HashMap() private val listeners = ArrayList>() - override fun get(id: UUID): ItemStackWrapper { + private var nextID = 0L + + override fun get(id: Long): ItemStackWrapper { return index[id]?.stack ?: ItemStackWrapper.EMPTY } @@ -87,7 +90,7 @@ private class QIOFrequencyAccess(val parent: QIOFrequency) : IStorageComponent { - data class NetworkedItem constructor(val id: Int, val stack: ItemStack, val upstreamId: UUID? = null) + data class NetworkedItem constructor(val id: Int, val stack: ItemStack, val upstreamId: Long? = null) + + override val storageType: StorageStackType + get() = ITEM_STORAGE protected var nextStackID = 0 // this (how client see and interact with) @@ -193,7 +194,7 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote: } // parent (e.g. VirtualComponent) - protected val upstreamState = HashMap() + protected val upstreamState = Long2ObjectAVLTreeMap() protected val networkBacklog = ArrayList() operator fun get(id: Int): NetworkedItem? = localState[id] @@ -231,8 +232,8 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote: return localState.values.size } - 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()) + 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()) protected fun network(fn: () -> Any) { if (!remote) { @@ -240,14 +241,14 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote: } } - override fun removeStack(stack: ItemStackWrapper, id: UUID) { + override fun removeStack(stack: ItemStackWrapper, id: Long) { 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: UUID) { + fun addObject(stack: ItemStack, id_upstream: Long) { check(!upstreamState.containsKey(id_upstream)) { "Already tracking ItemStack with upstream id $id_upstream!" } val state = NetworkedItem(nextStackID++, stack.copy(), id_upstream) @@ -257,7 +258,7 @@ open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote: network { StackAddPacket(menu.containerId, state.id, stack) } } - fun changeObject(id_upstream: UUID, new_count: Int) { + fun changeObject(id_upstream: Long, 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 aee94f2c3..2ab38155f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/API.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/API.kt @@ -81,21 +81,21 @@ interface IStorageEventProducer : IStorage { /** * Consumes events produced by [IStorageEventConsumer] */ -interface IStorageEventConsumer { +interface IStorageEventConsumer : IStorage { /** * Fired on whenever an object is added (to listener) we subscribed to */ - fun addStack(stack: T, id: UUID, provider: IStorageProvider) + fun addStack(stack: T, id: Long, provider: IStorageProvider) /** * Fired on whenever an object is changes on listener we subscribed to */ - fun changeStack(stack: T, id: UUID, oldCount: BigInteger) + fun changeStack(stack: T, id: Long, oldCount: BigInteger) /** * Fired on whenever an object is removed from listener we subscribed to */ - fun removeStack(stack: T, id: UUID) + fun removeStack(stack: T, id: Long) } interface IStorageAcceptor : IStorage { @@ -111,7 +111,7 @@ interface IStorageProvider : IStorageEventProducer { * @param id identifier of stack * @return stored object (not a copy). Do not edit it. */ - operator fun get(id: UUID): T + operator fun get(id: Long): T val stacks: Stream> @@ -123,7 +123,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: UUID, amount: BigInteger, simulate: Boolean): T + fun extractStack(id: Long, amount: BigInteger, simulate: Boolean): T fun addListenerAuto(listener: IStorageEventConsumer): Boolean { if (addListener(listener)) { @@ -150,6 +150,8 @@ interface IStorageProvider : IStorageEventProducer { } } +interface IStorageComponent : IStorageProvider, IStorageAcceptor + fun IStorageEventConsumer.changeStack(tuple: IStorageTuple, oldCount: BigInteger) { changeStack(tuple.stack, tuple.id, oldCount) } @@ -163,13 +165,11 @@ fun IStorageEventConsumer.removeStack(tuple: IStorageTupl } interface IStorageTuple { - val id: UUID + val id: Long val stack: T } -class StorageTuple(override val id: UUID, override val stack: T) : IStorageTuple - -interface IStorageComponent : IStorageProvider, IStorageAcceptor +class StorageTuple(override val id: Long, 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 23a207be5..e49692a19 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/storage/VirtualComponent.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/storage/VirtualComponent.kt @@ -1,18 +1,19 @@ package ru.dbotthepony.mc.otm.storage +import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap import it.unimi.dsi.fastutil.objects.ObjectArraySet import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage -import ru.dbotthepony.mc.otm.core.ImpreciseFraction import ru.dbotthepony.mc.otm.core.isPositive import ru.dbotthepony.mc.otm.core.isZero import java.math.BigInteger import java.util.* import java.util.stream.Stream import kotlin.collections.HashMap +import kotlin.reflect.full.isSubclassOf class RemoteTuple( override val stack: T, - override val id: UUID, + override val id: Long, val provider: IStorageProvider, val local: LocalTuple ) : IStorageTuple { @@ -21,7 +22,7 @@ class RemoteTuple( } override fun equals(other: Any?): Boolean { - return other is RemoteTuple<*> && other.id == id || other is UUID && other == id + return other is RemoteTuple<*> && other.id == id } override fun hashCode(): Int { @@ -29,7 +30,7 @@ class RemoteTuple( } } -class LocalTuple(override val stack: T, override val id: UUID, val tuples: ArrayList>) : IStorageTuple +class LocalTuple(override val stack: T, override val id: Long, val tuples: ArrayList>) : IStorageTuple open class VirtualComponent(type: StorageStackType) : IVirtualStorageComponent { constructor(type: Class) : this(StorageRegistry.get(type)) @@ -37,30 +38,39 @@ open class VirtualComponent(type: StorageStackType) : IVir override val storageType: StorageStackType = type // удаленный UUID -> Кортеж - protected val remoteByUUID: MutableMap> = HashMap() + protected val remoteTuples = Long2ObjectAVLTreeMap>() // локальный UUID -> Локальный кортеж - protected val localByUUID: MutableMap> = HashMap() + protected val localTuples = Long2ObjectAVLTreeMap>() // Стак -> Локальный кортеж стака - protected val tuples: MutableMap> = HashMap() + protected val hashedTuples: MutableMap> = HashMap() // ArrayList для скорости работы protected val listeners: MutableSet> = ObjectArraySet() - protected val set: 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) {} override fun add(identity: IStorage) { - if (set.add(identity)) { + if (!(identity.storageType::class.isSubclassOf(storageType::class))) + throw ClassCastException("Reified Generics: ${identity.storageType::class.qualifiedName} can not be cast into ${storageType::class.qualifiedName}") + + if (children.add(identity)) { if (identity is IStorageProvider) { identity.addListenerAuto(this) } else if (identity is IStorageEventProducer) { identity.addListener(this) } + if (identity is IStorageEventConsumer) { + addListenerAuto(identity) + } + if (identity is IStorageAcceptor) { consumers.add(identity) } @@ -70,13 +80,20 @@ open class VirtualComponent(type: StorageStackType) : IVir } override fun remove(identity: IStorage) { - if (set.remove(identity)) { + if (!(identity.storageType::class.isSubclassOf(storageType::class))) + throw ClassCastException("Reified Generics: ${identity.storageType::class.qualifiedName} can not be cast into ${storageType::class.qualifiedName}") + + if (children.remove(identity)) { if (identity is IStorageProvider) { identity.removeListenerAuto(this) } else if (identity is IStorageEventProducer) { identity.removeListener(this) } + if (identity is IStorageEventConsumer) { + removeListenerAuto(identity) + } + if (identity is IStorageAcceptor) { consumers.remove(identity) } @@ -86,12 +103,11 @@ open class VirtualComponent(type: StorageStackType) : IVir } override fun contains(identity: IStorage): Boolean { - return set.contains(identity) + return children.contains(identity) } override fun addListener(listener: IStorageEventConsumer): Boolean { - if (!listeners.contains(listener)) { - listeners.add(listener) + if (listeners.add(listener)) { return true } @@ -102,27 +118,27 @@ open class VirtualComponent(type: StorageStackType) : IVir return listeners.remove(listener) } - override fun get(id: UUID): T { - return localByUUID[id]?.stack ?: this.storageType.empty + override fun get(id: Long): T { + return localTuples[id]?.stack ?: this.storageType.empty } override val stacks: Stream> get() { - return ArrayList>(tuples.size).also { it.addAll(tuples.values) }.stream() + return ArrayList>(hashedTuples.size).also { it.addAll(hashedTuples.values) }.stream() } @Suppress("unchecked_cast") - override fun addStack(stack: T, id: UUID, provider: IStorageProvider) { - check(!remoteByUUID.containsKey(id)) { "Already tracking tuple with id $id" } + override fun addStack(stack: T, id: Long, provider: IStorageProvider) { + check(!remoteTuples.containsKey(id)) { "Already tracking tuple with id $id" } val key = stack.key() - var local: LocalTuple? = tuples[key] + var local: LocalTuple? = hashedTuples[key] var oldCount = BigInteger.ZERO val added = local == null if (local == null) { - local = LocalTuple(stack.copy() as T, UUID.randomUUID(), ArrayList>(1)) - localByUUID[local.id] = local - tuples[key] = local + local = LocalTuple(stack.copy() as T, nextID++, ArrayList>(1)) + localTuples[local.id] = local + hashedTuples[key] = local } else { oldCount = local.stack.count local.stack.grow(stack.count) @@ -130,7 +146,7 @@ open class VirtualComponent(type: StorageStackType) : IVir val remote = RemoteTuple(stack.copy() as T, id, provider, local) local.tuples.add(remote) - remoteByUUID[id] = remote + remoteTuples[id] = remote if (added) { for (listener in listeners) { @@ -143,9 +159,9 @@ open class VirtualComponent(type: StorageStackType) : IVir } } - override fun changeStack(stack: T, id: UUID, oldCount: BigInteger) { + override fun changeStack(stack: T, id: Long, oldCount: BigInteger) { require(stack.count.isPositive) - val tuple = remoteByUUID[id] ?: throw IllegalStateException("No such tuple with id $id") + val tuple = remoteTuples[id] ?: throw IllegalStateException("No such tuple with id $id") val diff = stack.count - tuple.stack.count tuple.stack.count = stack.count @@ -158,22 +174,22 @@ open class VirtualComponent(type: StorageStackType) : IVir } } - override fun removeStack(stack: T, id: UUID) { - val tuple = remoteByUUID[id] ?: throw IllegalStateException("No such tuple with id $id") + override fun removeStack(stack: T, id: Long) { + val tuple = remoteTuples[id] ?: throw IllegalStateException("No such tuple with id $id") tuple.local.stack.shrink(tuple.stack.count) tuple.local.tuples.remove(tuple) - remoteByUUID.remove(id) + remoteTuples.remove(id) val a = tuple.local.stack.count <= BigInteger.ZERO val b = tuple.local.tuples.size == 0 if (a || b) { check(a && b) { "View object is empty, but tuple list is not!" } - localByUUID.remove(tuple.local.id) + localTuples.remove(tuple.local.id) val key = stack.key() - checkNotNull(tuples.remove(key)) { "No such stack $key" } + checkNotNull(hashedTuples.remove(key)) { "No such stack $key" } for (listener in listeners) { listener.removeStack(tuple.local.stack, tuple.local.id) @@ -196,13 +212,13 @@ open class VirtualComponent(type: StorageStackType) : IVir } @Suppress("unchecked_cast") - override fun extractStack(id: UUID, amount: BigInteger, simulate: Boolean): T { + override fun extractStack(id: Long, amount: BigInteger, simulate: Boolean): T { if (!amount.isPositive) return this.storageType.empty @Suppress("name_shadowing") var amount = amount - val tuple: LocalTuple? = localByUUID[id] + val tuple: LocalTuple? = localTuples[id] if (tuple == null || amount.isZero) return this.storageType.empty @@ -302,9 +318,9 @@ open class PoweredComponent(open val parent: IStorageComponen return stack } - override fun get(id: UUID) = parent[id] + override fun get(id: Long) = parent[id] - override fun extractStack(id: UUID, amount: BigInteger, simulate: Boolean): T { + override fun extractStack(id: Long, amount: BigInteger, simulate: Boolean): T { val required = storageType.energyPerOperation * amount val energy = energyProvider.invoke() val extracted = energy.extractEnergyInner(required, true) @@ -358,9 +374,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: 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 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 add(identity: IStorage) = parent.add(identity) override fun remove(identity: IStorage) = parent.remove(identity)