Move IDs to Longs again, update storage class hierarchy
maybe use ints? IDK
This commit is contained in:
parent
cb5cb44848
commit
50cac6d1b5
@ -1,6 +1,7 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity
|
package ru.dbotthepony.mc.otm.block.entity
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap
|
||||||
import net.minecraft.core.BlockPos
|
import net.minecraft.core.BlockPos
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
@ -43,7 +44,7 @@ import kotlin.collections.ArrayList
|
|||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
|
|
||||||
private class SlotTuple(val slot: Int, val stack: ItemStack)
|
private class SlotTuple(val slot: Int, val stack: ItemStack)
|
||||||
private class TrackedTuple(override val stack: ItemStackWrapper, override val id: UUID) : IStorageTuple<ItemStackWrapper> {
|
private class TrackedTuple(override val stack: ItemStackWrapper, override val id: Long) : IStorageTuple<ItemStackWrapper> {
|
||||||
val children = Int2ObjectAVLTreeMap<SlotTuple>()
|
val children = Int2ObjectAVLTreeMap<SlotTuple>()
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
@ -186,10 +187,12 @@ 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> {
|
||||||
override val storageType: StorageStackType<ItemStackWrapper>
|
override val storageType: StorageStackType<ItemStackWrapper>
|
||||||
get() = OverdriveThatMatters.INSTANCE.ITEM_STORAGE()
|
get() = ITEM_STORAGE
|
||||||
|
|
||||||
private val listeners = ArrayList<IStorageEventConsumer<ItemStackWrapper>>()
|
private val listeners = ArrayList<IStorageEventConsumer<ItemStackWrapper>>()
|
||||||
|
|
||||||
|
private var nextID = 0L
|
||||||
|
|
||||||
override fun addListener(listener: IStorageEventConsumer<ItemStackWrapper>): Boolean {
|
override fun addListener(listener: IStorageEventConsumer<ItemStackWrapper>): Boolean {
|
||||||
if (!listeners.contains(listener)) {
|
if (!listeners.contains(listener)) {
|
||||||
listeners.add(listener)
|
listeners.add(listener)
|
||||||
@ -206,7 +209,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
private var scanned = arrayOfNulls<ItemStack>(0)
|
private var scanned = arrayOfNulls<ItemStack>(0)
|
||||||
private var scannedMap = arrayOfNulls<TrackedTuple>(0)
|
private var scannedMap = arrayOfNulls<TrackedTuple>(0)
|
||||||
private val tuples = HashMap<ItemStackWrapper, TrackedTuple>()
|
private val tuples = HashMap<ItemStackWrapper, TrackedTuple>()
|
||||||
private val index = HashMap<UUID, TrackedTuple>()
|
private val index = Long2ObjectAVLTreeMap<TrackedTuple>()
|
||||||
|
|
||||||
private fun removeTracked(slot: Int) {
|
private fun removeTracked(slot: Int) {
|
||||||
scanned[slot] = null
|
scanned[slot] = null
|
||||||
@ -257,7 +260,7 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
var oldCount = BigInteger.ZERO
|
var oldCount = BigInteger.ZERO
|
||||||
|
|
||||||
if (added) {
|
if (added) {
|
||||||
tuple = TrackedTuple(storageStack, UUID.randomUUID())
|
tuple = TrackedTuple(storageStack, nextID++)
|
||||||
index[tuple.id] = tuple
|
index[tuple.id] = tuple
|
||||||
tuples[key] = tuple
|
tuples[key] = tuple
|
||||||
} else {
|
} else {
|
||||||
@ -375,11 +378,11 @@ class StorageBusBlockEntity(blockPos: BlockPos, blockState: BlockState) : Matter
|
|||||||
return leftover
|
return leftover
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun get(id: UUID): ItemStackWrapper {
|
override fun get(id: Long): ItemStackWrapper {
|
||||||
return index[id]?.stack ?: ItemStackWrapper.EMPTY
|
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)
|
if (!amount.isPositive)
|
||||||
return ItemStackWrapper.EMPTY
|
return ItemStackWrapper.EMPTY
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package ru.dbotthepony.mc.otm.block.entity
|
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.BlockPos
|
||||||
import net.minecraft.core.Direction
|
import net.minecraft.core.Direction
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
@ -272,9 +274,16 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
return StorageExporterMenu(containerID, inventory, this)
|
return StorageExporterMenu(containerID, inventory, this)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val relevantTuples = HashSet<UUID>()
|
private val relevantTuples = LongArraySet()
|
||||||
|
|
||||||
override fun addStack(stack: ItemStackWrapper, id: UUID, provider: IStorageProvider<ItemStackWrapper>) {
|
override val storageType: StorageStackType<ItemStackWrapper>
|
||||||
|
get() = ITEM_STORAGE
|
||||||
|
|
||||||
|
init {
|
||||||
|
cell.addStorageComponent(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun addStack(stack: ItemStackWrapper, id: Long, provider: IStorageProvider<ItemStackWrapper>) {
|
||||||
if (!filter.match(stack.item)) {
|
if (!filter.match(stack.item)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -282,11 +291,11 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
relevantTuples.add(id)
|
relevantTuples.add(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun changeStack(stack: ItemStackWrapper, id: UUID, oldCount: BigInteger) {
|
override fun changeStack(stack: ItemStackWrapper, id: Long, oldCount: BigInteger) {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun removeStack(stack: ItemStackWrapper, id: UUID) {
|
override fun removeStack(stack: ItemStackWrapper, id: Long) {
|
||||||
relevantTuples.remove(id)
|
relevantTuples.remove(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,7 +320,7 @@ class StorageExporterBlockEntity(blockPos: BlockPos, blockState: BlockState) :
|
|||||||
override val targetCapability: Capability<IItemHandler>
|
override val targetCapability: Capability<IItemHandler>
|
||||||
get() = CapabilityItemHandler.ITEM_HANDLER_CAPABILITY
|
get() = CapabilityItemHandler.ITEM_HANDLER_CAPABILITY
|
||||||
|
|
||||||
private val exportStacks: Stream<Pair<UUID, ItemStackWrapper>>
|
private val exportStacks: Stream<Pair<Long, ItemStackWrapper>>
|
||||||
get() {
|
get() {
|
||||||
val view = cell.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: return Stream.empty()
|
val view = cell.storageGraph?.getVirtualComponent(ITEM_STORAGE) ?: return Stream.empty()
|
||||||
return relevantTuples.stream().map { it to view[it] }
|
return relevantTuples.stream().map { it to view[it] }
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package ru.dbotthepony.mc.otm.capability.drive
|
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.Object2ObjectAVLTreeMap
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||||
import kotlin.jvm.JvmOverloads
|
import kotlin.jvm.JvmOverloads
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import net.minecraft.nbt.CompoundTag
|
import net.minecraft.nbt.CompoundTag
|
||||||
import net.minecraft.nbt.ListTag
|
import net.minecraft.nbt.ListTag
|
||||||
|
import net.minecraft.nbt.LongTag
|
||||||
import net.minecraft.nbt.Tag
|
import net.minecraft.nbt.Tag
|
||||||
|
import org.apache.logging.log4j.LogManager
|
||||||
import ru.dbotthepony.mc.otm.core.BigInteger
|
import ru.dbotthepony.mc.otm.core.BigInteger
|
||||||
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
|
||||||
@ -16,7 +19,6 @@ import ru.dbotthepony.mc.otm.set
|
|||||||
import ru.dbotthepony.mc.otm.storage.*
|
import ru.dbotthepony.mc.otm.storage.*
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.HashSet
|
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
|
|
||||||
abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor(
|
abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor(
|
||||||
@ -25,7 +27,7 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
|
|||||||
var maxDifferentStacks: Int = 0xFFFF
|
var maxDifferentStacks: Int = 0xFFFF
|
||||||
) : IMatteryDrive<T> {
|
) : IMatteryDrive<T> {
|
||||||
protected val tuples = HashMap<T, IStorageTuple<T>>()
|
protected val tuples = HashMap<T, IStorageTuple<T>>()
|
||||||
protected val tuplesByID = Object2ObjectAVLTreeMap<UUID, IStorageTuple<T>>()
|
protected val tuplesByID: MutableMap<Long, IStorageTuple<T>> = Long2ObjectAVLTreeMap()
|
||||||
|
|
||||||
override var isDirty = false
|
override var isDirty = false
|
||||||
set(value) {
|
set(value) {
|
||||||
@ -39,6 +41,8 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
|
|||||||
var storedDifferentStacks = 0
|
var storedDifferentStacks = 0
|
||||||
protected set
|
protected set
|
||||||
|
|
||||||
|
protected var nextID = 0L
|
||||||
|
|
||||||
override var storedCount: BigInteger = BigInteger.ZERO
|
override var storedCount: BigInteger = BigInteger.ZERO
|
||||||
protected set
|
protected set
|
||||||
|
|
||||||
@ -79,7 +83,7 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
|
|||||||
val copy = stack.copy() as T
|
val copy = stack.copy() as T
|
||||||
copy.count = maxInsert
|
copy.count = maxInsert
|
||||||
|
|
||||||
val state = StorageTuple(UUID.randomUUID(), copy)
|
val state = StorageTuple(nextID++, copy)
|
||||||
tuples[key] = state
|
tuples[key] = state
|
||||||
tuplesByID[state.id] = state
|
tuplesByID[state.id] = state
|
||||||
|
|
||||||
@ -96,7 +100,7 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unchecked_cast")
|
@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
|
val get = tuplesByID[id] ?: return storageType.empty
|
||||||
|
|
||||||
@Suppress("NAME_SHADOWING")
|
@Suppress("NAME_SHADOWING")
|
||||||
@ -157,7 +161,6 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
|
|||||||
val serialized = serializeStack(stack)
|
val serialized = serializeStack(stack)
|
||||||
|
|
||||||
if (serialized != null) {
|
if (serialized != null) {
|
||||||
serialized["id"] = longArrayOf(stack.id.mostSignificantBits, stack.id.leastSignificantBits)
|
|
||||||
list.add(serialized)
|
list.add(serialized)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -166,10 +169,17 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun deserializeNBT(nbt: CompoundTag) {
|
override fun deserializeNBT(nbt: CompoundTag) {
|
||||||
|
for (listener in listeners) {
|
||||||
|
for (get in tuples.values) {
|
||||||
|
listener.removeStack(get.stack, get.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tuples.clear()
|
tuples.clear()
|
||||||
tuplesByID.clear()
|
tuplesByID.clear()
|
||||||
storedCount = BigInteger.ZERO
|
storedCount = BigInteger.ZERO
|
||||||
storedDifferentStacks = 0
|
storedDifferentStacks = 0
|
||||||
|
// nextID = 0L
|
||||||
|
|
||||||
nbt.ifHas("capacity") {
|
nbt.ifHas("capacity") {
|
||||||
driveCapacity = BigInteger(it)
|
driveCapacity = BigInteger(it)
|
||||||
@ -184,9 +194,7 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
|
|||||||
if (stack != null) {
|
if (stack != null) {
|
||||||
storedCount += stack.count
|
storedCount += stack.count
|
||||||
storedDifferentStacks++
|
storedDifferentStacks++
|
||||||
|
val tuple = StorageTuple(nextID++, stack)
|
||||||
val id = entry.getLongArray("id")
|
|
||||||
val tuple = StorageTuple(if (id.size == 2) UUID(id[0], id[1]) else UUID.randomUUID(), stack)
|
|
||||||
tuples[tuple.stack.key()] = tuple
|
tuples[tuple.stack.key()] = tuple
|
||||||
tuplesByID[tuple.id] = tuple
|
tuplesByID[tuple.id] = tuple
|
||||||
}
|
}
|
||||||
@ -194,7 +202,7 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun get(id: UUID): T {
|
override fun get(id: Long): T {
|
||||||
return tuplesByID[id]?.stack ?: storageType.empty
|
return tuplesByID[id]?.stack ?: storageType.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,4 +219,8 @@ abstract class AbstractMatteryDrive<T : IStorageStack> @JvmOverloads constructor
|
|||||||
override fun removeListener(listener: IStorageEventConsumer<T>): Boolean {
|
override fun removeListener(listener: IStorageEventConsumer<T>): Boolean {
|
||||||
return listeners.remove(listener)
|
return listeners.remove(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val LOGGER = LogManager.getLogger()
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package ru.dbotthepony.mc.otm.compat.mekanism
|
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.Object2ObjectAVLTreeMap
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
|
import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap
|
||||||
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
||||||
@ -36,7 +37,7 @@ private val QIO_LOCATION = ResourceLocation(OverdriveThatMatters.MOD_ID, "item_s
|
|||||||
private class QIOTuple(
|
private class QIOTuple(
|
||||||
val mekanismItem: HashedItem,
|
val mekanismItem: HashedItem,
|
||||||
override val stack: ItemStackWrapper,
|
override val stack: ItemStackWrapper,
|
||||||
override val id: UUID,
|
override val id: Long,
|
||||||
var mark: Long
|
var mark: Long
|
||||||
) : IStorageTuple<ItemStackWrapper>
|
) : IStorageTuple<ItemStackWrapper>
|
||||||
|
|
||||||
@ -46,11 +47,13 @@ private class QIOFrequencyAccess(val parent: QIOFrequency) : IStorageComponent<I
|
|||||||
override val storageType: StorageStackType<ItemStackWrapper>
|
override val storageType: StorageStackType<ItemStackWrapper>
|
||||||
get() = OverdriveThatMatters.INSTANCE.ITEM_STORAGE()
|
get() = OverdriveThatMatters.INSTANCE.ITEM_STORAGE()
|
||||||
|
|
||||||
private val index = Object2ObjectAVLTreeMap<UUID, QIOTuple>()
|
private val index = Long2ObjectAVLTreeMap<QIOTuple>()
|
||||||
private val tracked = HashMap<HashedItem, QIOTuple>()
|
private val tracked = HashMap<HashedItem, QIOTuple>()
|
||||||
private val listeners = ArrayList<IStorageEventConsumer<ItemStackWrapper>>()
|
private val listeners = ArrayList<IStorageEventConsumer<ItemStackWrapper>>()
|
||||||
|
|
||||||
override fun get(id: UUID): ItemStackWrapper {
|
private var nextID = 0L
|
||||||
|
|
||||||
|
override fun get(id: Long): ItemStackWrapper {
|
||||||
return index[id]?.stack ?: ItemStackWrapper.EMPTY
|
return index[id]?.stack ?: ItemStackWrapper.EMPTY
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +90,7 @@ private class QIOFrequencyAccess(val parent: QIOFrequency) : IStorageComponent<I
|
|||||||
return inserted
|
return inserted
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun extractStack(id: UUID, amount: BigInteger, simulate: Boolean): ItemStackWrapper {
|
override fun extractStack(id: Long, amount: BigInteger, simulate: Boolean): ItemStackWrapper {
|
||||||
// Because there is no simulate method on QIO array, we have to simulate it by ourselves.
|
// Because there is no simulate method on QIO array, we have to simulate it by ourselves.
|
||||||
// ASSUMPTION: We can ALWAYS remove items from QIO grid.
|
// ASSUMPTION: We can ALWAYS remove items from QIO grid.
|
||||||
|
|
||||||
@ -158,7 +161,7 @@ private class QIOFrequencyAccess(val parent: QIOFrequency) : IStorageComponent<I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val tuple = QIOTuple(at, ItemStackWrapper(at.stack).also { it.count = value.count.toBigInteger() }, UUID.randomUUID(), mark)
|
val tuple = QIOTuple(at, ItemStackWrapper(at.stack).also { it.count = value.count.toBigInteger() }, nextID++, mark)
|
||||||
index[tuple.id] = tuple
|
index[tuple.id] = tuple
|
||||||
|
|
||||||
for (listener in listeners) {
|
for (listener in listeners) {
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package ru.dbotthepony.mc.otm.graph.storage
|
package ru.dbotthepony.mc.otm.graph.storage
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||||
import net.minecraft.world.level.Level
|
import net.minecraft.world.level.Level
|
||||||
import net.minecraftforge.common.util.LazyOptional
|
import net.minecraftforge.common.util.LazyOptional
|
||||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
||||||
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
import ru.dbotthepony.mc.otm.graph.Graph6Node
|
||||||
import ru.dbotthepony.mc.otm.storage.IStorage
|
import ru.dbotthepony.mc.otm.storage.IStorage
|
||||||
|
import ru.dbotthepony.mc.otm.storage.IStorageEventConsumer
|
||||||
import ru.dbotthepony.mc.otm.storage.IStorageStack
|
import ru.dbotthepony.mc.otm.storage.IStorageStack
|
||||||
import ru.dbotthepony.mc.otm.storage.StorageStackType
|
import ru.dbotthepony.mc.otm.storage.StorageStackType
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.menu.data
|
|||||||
|
|
||||||
import com.mojang.blaze3d.platform.InputConstants
|
import com.mojang.blaze3d.platform.InputConstants
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap
|
||||||
import net.minecraft.client.Minecraft
|
import net.minecraft.client.Minecraft
|
||||||
import net.minecraft.client.gui.screens.Screen
|
import net.minecraft.client.gui.screens.Screen
|
||||||
import net.minecraft.network.FriendlyByteBuf
|
import net.minecraft.network.FriendlyByteBuf
|
||||||
@ -17,10 +18,7 @@ import ru.dbotthepony.mc.otm.core.ImpreciseFraction
|
|||||||
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
||||||
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
import ru.dbotthepony.mc.otm.network.MatteryNetworking
|
||||||
import ru.dbotthepony.mc.otm.network.SetCarriedPacket
|
import ru.dbotthepony.mc.otm.network.SetCarriedPacket
|
||||||
import ru.dbotthepony.mc.otm.storage.IStorageComponent
|
import ru.dbotthepony.mc.otm.storage.*
|
||||||
import ru.dbotthepony.mc.otm.storage.IStorageEventConsumer
|
|
||||||
import ru.dbotthepony.mc.otm.storage.IStorageProvider
|
|
||||||
import ru.dbotthepony.mc.otm.storage.ItemStackWrapper
|
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
@ -157,7 +155,10 @@ class StackRemovePacket(val id: Int, val stackID: Int) {
|
|||||||
* Creates a virtual, slotless container for Player to interaction with.
|
* Creates a virtual, slotless container for Player to interaction with.
|
||||||
*/
|
*/
|
||||||
open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote: Boolean) : IStorageEventConsumer<ItemStackWrapper> {
|
open class NetworkedItemView(val ply: Player, val menu: MatteryMenu, val remote: Boolean) : IStorageEventConsumer<ItemStackWrapper> {
|
||||||
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<ItemStackWrapper>
|
||||||
|
get() = ITEM_STORAGE
|
||||||
|
|
||||||
protected var nextStackID = 0
|
protected var nextStackID = 0
|
||||||
// this (how client see and interact with)
|
// 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)
|
// parent (e.g. VirtualComponent)
|
||||||
protected val upstreamState = HashMap<UUID, NetworkedItem>()
|
protected val upstreamState = Long2ObjectAVLTreeMap<NetworkedItem>()
|
||||||
protected val networkBacklog = ArrayList<Any>()
|
protected val networkBacklog = ArrayList<Any>()
|
||||||
|
|
||||||
operator fun get(id: Int): NetworkedItem? = localState[id]
|
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
|
return localState.values.size
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addStack(stack: ItemStackWrapper, id: UUID, provider: IStorageProvider<ItemStackWrapper>) = addObject(stack.stack, id)
|
override fun addStack(stack: ItemStackWrapper, id: Long, provider: IStorageProvider<ItemStackWrapper>) = addObject(stack.stack, id)
|
||||||
override fun changeStack(stack: ItemStackWrapper, id: UUID, oldCount: BigInteger) = changeObject(id, stack.count.toInt())
|
override fun changeStack(stack: ItemStackWrapper, id: Long, oldCount: BigInteger) = changeObject(id, stack.count.toInt())
|
||||||
|
|
||||||
protected fun network(fn: () -> Any) {
|
protected fun network(fn: () -> Any) {
|
||||||
if (!remote) {
|
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!")
|
val get = upstreamState[id] ?: throw IllegalStateException("Unknown ItemStack with upstream id $id!")
|
||||||
upstreamState.remove(id)
|
upstreamState.remove(id)
|
||||||
localState.remove(get.id)
|
localState.remove(get.id)
|
||||||
network { StackRemovePacket(menu.containerId, 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!" }
|
check(!upstreamState.containsKey(id_upstream)) { "Already tracking ItemStack with upstream id $id_upstream!" }
|
||||||
|
|
||||||
val state = NetworkedItem(nextStackID++, stack.copy(), 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) }
|
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!")
|
val get = upstreamState[id_upstream] ?: throw IllegalStateException("Unknown ItemStack with upstream id $id_upstream!")
|
||||||
get.stack.count = new_count
|
get.stack.count = new_count
|
||||||
network { StackChangePacket(menu.containerId, get.id, new_count) }
|
network { StackChangePacket(menu.containerId, get.id, new_count) }
|
||||||
|
@ -81,21 +81,21 @@ interface IStorageEventProducer<T : IStorageStack> : IStorage<T> {
|
|||||||
/**
|
/**
|
||||||
* Consumes events produced by [IStorageEventConsumer]
|
* Consumes events produced by [IStorageEventConsumer]
|
||||||
*/
|
*/
|
||||||
interface IStorageEventConsumer<T : IStorageStack> {
|
interface IStorageEventConsumer<T : IStorageStack> : IStorage<T> {
|
||||||
/**
|
/**
|
||||||
* Fired on whenever an object is added (to listener) we subscribed to
|
* Fired on whenever an object is added (to listener) we subscribed to
|
||||||
*/
|
*/
|
||||||
fun addStack(stack: T, id: UUID, provider: IStorageProvider<T>)
|
fun addStack(stack: T, id: Long, provider: IStorageProvider<T>)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fired on whenever an object is changes on listener we subscribed to
|
* 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
|
* 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<T : IStorageStack> : IStorage<T> {
|
interface IStorageAcceptor<T : IStorageStack> : IStorage<T> {
|
||||||
@ -111,7 +111,7 @@ interface IStorageProvider<T : IStorageStack> : IStorageEventProducer<T> {
|
|||||||
* @param id identifier of stack
|
* @param id identifier of stack
|
||||||
* @return stored object (not a copy). Do not edit it.
|
* @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<IStorageTuple<T>>
|
val stacks: Stream<IStorageTuple<T>>
|
||||||
|
|
||||||
@ -123,7 +123,7 @@ interface IStorageProvider<T : IStorageStack> : IStorageEventProducer<T> {
|
|||||||
* @param simulate whenever to simulate the action or not
|
* @param simulate whenever to simulate the action or not
|
||||||
* @return copy of object, with amount of units actually extracted
|
* @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<T>): Boolean {
|
fun addListenerAuto(listener: IStorageEventConsumer<T>): Boolean {
|
||||||
if (addListener(listener)) {
|
if (addListener(listener)) {
|
||||||
@ -150,6 +150,8 @@ interface IStorageProvider<T : IStorageStack> : IStorageEventProducer<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface IStorageComponent<T : IStorageStack> : IStorageProvider<T>, IStorageAcceptor<T>
|
||||||
|
|
||||||
fun <T : IStorageStack> IStorageEventConsumer<T>.changeStack(tuple: IStorageTuple<T>, oldCount: BigInteger) {
|
fun <T : IStorageStack> IStorageEventConsumer<T>.changeStack(tuple: IStorageTuple<T>, oldCount: BigInteger) {
|
||||||
changeStack(tuple.stack, tuple.id, oldCount)
|
changeStack(tuple.stack, tuple.id, oldCount)
|
||||||
}
|
}
|
||||||
@ -163,13 +165,11 @@ fun <T : IStorageStack> IStorageEventConsumer<T>.removeStack(tuple: IStorageTupl
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface IStorageTuple<T : IStorageStack> {
|
interface IStorageTuple<T : IStorageStack> {
|
||||||
val id: UUID
|
val id: Long
|
||||||
val stack: T
|
val stack: T
|
||||||
}
|
}
|
||||||
|
|
||||||
class StorageTuple<T : IStorageStack>(override val id: UUID, override val stack: T) : IStorageTuple<T>
|
class StorageTuple<T : IStorageStack>(override val id: Long, override val stack: T) : IStorageTuple<T>
|
||||||
|
|
||||||
interface IStorageComponent<T : IStorageStack> : IStorageProvider<T>, IStorageAcceptor<T>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component which (most time) proxy other components (combine their contents into single view)
|
* Component which (most time) proxy other components (combine their contents into single view)
|
||||||
|
@ -1,18 +1,19 @@
|
|||||||
package ru.dbotthepony.mc.otm.storage
|
package ru.dbotthepony.mc.otm.storage
|
||||||
|
|
||||||
|
import it.unimi.dsi.fastutil.longs.Long2ObjectAVLTreeMap
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
import it.unimi.dsi.fastutil.objects.ObjectArraySet
|
||||||
import ru.dbotthepony.mc.otm.capability.IMatteryEnergyStorage
|
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.isPositive
|
||||||
import ru.dbotthepony.mc.otm.core.isZero
|
import ru.dbotthepony.mc.otm.core.isZero
|
||||||
import java.math.BigInteger
|
import java.math.BigInteger
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
import kotlin.collections.HashMap
|
import kotlin.collections.HashMap
|
||||||
|
import kotlin.reflect.full.isSubclassOf
|
||||||
|
|
||||||
class RemoteTuple<T : IStorageStack>(
|
class RemoteTuple<T : IStorageStack>(
|
||||||
override val stack: T,
|
override val stack: T,
|
||||||
override val id: UUID,
|
override val id: Long,
|
||||||
val provider: IStorageProvider<T>,
|
val provider: IStorageProvider<T>,
|
||||||
val local: LocalTuple<T>
|
val local: LocalTuple<T>
|
||||||
) : IStorageTuple<T> {
|
) : IStorageTuple<T> {
|
||||||
@ -21,7 +22,7 @@ class RemoteTuple<T : IStorageStack>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
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 {
|
override fun hashCode(): Int {
|
||||||
@ -29,7 +30,7 @@ class RemoteTuple<T : IStorageStack>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class LocalTuple<T : IStorageStack>(override val stack: T, override val id: UUID, val tuples: ArrayList<RemoteTuple<T>>) : IStorageTuple<T>
|
class LocalTuple<T : IStorageStack>(override val stack: T, override val id: Long, val tuples: ArrayList<RemoteTuple<T>>) : IStorageTuple<T>
|
||||||
|
|
||||||
open class VirtualComponent<T : IStorageStack>(type: StorageStackType<T>) : IVirtualStorageComponent<T> {
|
open class VirtualComponent<T : IStorageStack>(type: StorageStackType<T>) : IVirtualStorageComponent<T> {
|
||||||
constructor(type: Class<T>) : this(StorageRegistry.get(type))
|
constructor(type: Class<T>) : this(StorageRegistry.get(type))
|
||||||
@ -37,30 +38,39 @@ open class VirtualComponent<T : IStorageStack>(type: StorageStackType<T>) : IVir
|
|||||||
override val storageType: StorageStackType<T> = type
|
override val storageType: StorageStackType<T> = type
|
||||||
|
|
||||||
// удаленный UUID -> Кортеж
|
// удаленный UUID -> Кортеж
|
||||||
protected val remoteByUUID: MutableMap<UUID, RemoteTuple<T>> = HashMap()
|
protected val remoteTuples = Long2ObjectAVLTreeMap<RemoteTuple<T>>()
|
||||||
|
|
||||||
// локальный UUID -> Локальный кортеж
|
// локальный UUID -> Локальный кортеж
|
||||||
protected val localByUUID: MutableMap<UUID, LocalTuple<T>> = HashMap()
|
protected val localTuples = Long2ObjectAVLTreeMap<LocalTuple<T>>()
|
||||||
|
|
||||||
// Стак -> Локальный кортеж стака
|
// Стак -> Локальный кортеж стака
|
||||||
protected val tuples: MutableMap<T, LocalTuple<T>> = HashMap()
|
protected val hashedTuples: MutableMap<T, LocalTuple<T>> = HashMap()
|
||||||
|
|
||||||
// ArrayList для скорости работы
|
// ArrayList для скорости работы
|
||||||
protected val listeners: MutableSet<IStorageEventConsumer<T>> = ObjectArraySet()
|
protected val listeners: MutableSet<IStorageEventConsumer<T>> = ObjectArraySet()
|
||||||
protected val set: MutableSet<IStorage<T>> = ObjectArraySet()
|
protected val children: MutableSet<IStorage<T>> = ObjectArraySet()
|
||||||
protected val consumers: MutableSet<IStorageAcceptor<T>> = ObjectArraySet()
|
protected val consumers: MutableSet<IStorageAcceptor<T>> = ObjectArraySet()
|
||||||
|
|
||||||
|
private var nextID = 0L
|
||||||
|
|
||||||
protected open fun onAdd(identity: IStorage<T>) {}
|
protected open fun onAdd(identity: IStorage<T>) {}
|
||||||
protected open fun onRemove(identity: IStorage<T>) {}
|
protected open fun onRemove(identity: IStorage<T>) {}
|
||||||
|
|
||||||
override fun add(identity: IStorage<T>) {
|
override fun add(identity: IStorage<T>) {
|
||||||
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<T>) {
|
if (identity is IStorageProvider<T>) {
|
||||||
identity.addListenerAuto(this)
|
identity.addListenerAuto(this)
|
||||||
} else if (identity is IStorageEventProducer<T>) {
|
} else if (identity is IStorageEventProducer<T>) {
|
||||||
identity.addListener(this)
|
identity.addListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (identity is IStorageEventConsumer<T>) {
|
||||||
|
addListenerAuto(identity)
|
||||||
|
}
|
||||||
|
|
||||||
if (identity is IStorageAcceptor<T>) {
|
if (identity is IStorageAcceptor<T>) {
|
||||||
consumers.add(identity)
|
consumers.add(identity)
|
||||||
}
|
}
|
||||||
@ -70,13 +80,20 @@ open class VirtualComponent<T : IStorageStack>(type: StorageStackType<T>) : IVir
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun remove(identity: IStorage<T>) {
|
override fun remove(identity: IStorage<T>) {
|
||||||
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<T>) {
|
if (identity is IStorageProvider<T>) {
|
||||||
identity.removeListenerAuto(this)
|
identity.removeListenerAuto(this)
|
||||||
} else if (identity is IStorageEventProducer<T>) {
|
} else if (identity is IStorageEventProducer<T>) {
|
||||||
identity.removeListener(this)
|
identity.removeListener(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (identity is IStorageEventConsumer<T>) {
|
||||||
|
removeListenerAuto(identity)
|
||||||
|
}
|
||||||
|
|
||||||
if (identity is IStorageAcceptor<T>) {
|
if (identity is IStorageAcceptor<T>) {
|
||||||
consumers.remove(identity)
|
consumers.remove(identity)
|
||||||
}
|
}
|
||||||
@ -86,12 +103,11 @@ open class VirtualComponent<T : IStorageStack>(type: StorageStackType<T>) : IVir
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun contains(identity: IStorage<T>): Boolean {
|
override fun contains(identity: IStorage<T>): Boolean {
|
||||||
return set.contains(identity)
|
return children.contains(identity)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun addListener(listener: IStorageEventConsumer<T>): Boolean {
|
override fun addListener(listener: IStorageEventConsumer<T>): Boolean {
|
||||||
if (!listeners.contains(listener)) {
|
if (listeners.add(listener)) {
|
||||||
listeners.add(listener)
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,27 +118,27 @@ open class VirtualComponent<T : IStorageStack>(type: StorageStackType<T>) : IVir
|
|||||||
return listeners.remove(listener)
|
return listeners.remove(listener)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun get(id: UUID): T {
|
override fun get(id: Long): T {
|
||||||
return localByUUID[id]?.stack ?: this.storageType.empty
|
return localTuples[id]?.stack ?: this.storageType.empty
|
||||||
}
|
}
|
||||||
|
|
||||||
override val stacks: Stream<IStorageTuple<T>> get() {
|
override val stacks: Stream<IStorageTuple<T>> get() {
|
||||||
return ArrayList<IStorageTuple<T>>(tuples.size).also { it.addAll(tuples.values) }.stream()
|
return ArrayList<IStorageTuple<T>>(hashedTuples.size).also { it.addAll(hashedTuples.values) }.stream()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unchecked_cast")
|
@Suppress("unchecked_cast")
|
||||||
override fun addStack(stack: T, id: UUID, provider: IStorageProvider<T>) {
|
override fun addStack(stack: T, id: Long, provider: IStorageProvider<T>) {
|
||||||
check(!remoteByUUID.containsKey(id)) { "Already tracking tuple with id $id" }
|
check(!remoteTuples.containsKey(id)) { "Already tracking tuple with id $id" }
|
||||||
|
|
||||||
val key = stack.key()
|
val key = stack.key()
|
||||||
var local: LocalTuple<T>? = tuples[key]
|
var local: LocalTuple<T>? = hashedTuples[key]
|
||||||
var oldCount = BigInteger.ZERO
|
var oldCount = BigInteger.ZERO
|
||||||
val added = local == null
|
val added = local == null
|
||||||
|
|
||||||
if (local == null) {
|
if (local == null) {
|
||||||
local = LocalTuple(stack.copy() as T, UUID.randomUUID(), ArrayList<RemoteTuple<T>>(1))
|
local = LocalTuple(stack.copy() as T, nextID++, ArrayList<RemoteTuple<T>>(1))
|
||||||
localByUUID[local.id] = local
|
localTuples[local.id] = local
|
||||||
tuples[key] = local
|
hashedTuples[key] = local
|
||||||
} else {
|
} else {
|
||||||
oldCount = local.stack.count
|
oldCount = local.stack.count
|
||||||
local.stack.grow(stack.count)
|
local.stack.grow(stack.count)
|
||||||
@ -130,7 +146,7 @@ open class VirtualComponent<T : IStorageStack>(type: StorageStackType<T>) : IVir
|
|||||||
|
|
||||||
val remote = RemoteTuple(stack.copy() as T, id, provider, local)
|
val remote = RemoteTuple(stack.copy() as T, id, provider, local)
|
||||||
local.tuples.add(remote)
|
local.tuples.add(remote)
|
||||||
remoteByUUID[id] = remote
|
remoteTuples[id] = remote
|
||||||
|
|
||||||
if (added) {
|
if (added) {
|
||||||
for (listener in listeners) {
|
for (listener in listeners) {
|
||||||
@ -143,9 +159,9 @@ open class VirtualComponent<T : IStorageStack>(type: StorageStackType<T>) : IVir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun changeStack(stack: T, id: UUID, oldCount: BigInteger) {
|
override fun changeStack(stack: T, id: Long, oldCount: BigInteger) {
|
||||||
require(stack.count.isPositive)
|
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
|
val diff = stack.count - tuple.stack.count
|
||||||
tuple.stack.count = stack.count
|
tuple.stack.count = stack.count
|
||||||
@ -158,22 +174,22 @@ open class VirtualComponent<T : IStorageStack>(type: StorageStackType<T>) : IVir
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun removeStack(stack: T, id: UUID) {
|
override fun removeStack(stack: T, id: Long) {
|
||||||
val tuple = remoteByUUID[id] ?: throw IllegalStateException("No such tuple with id $id")
|
val tuple = remoteTuples[id] ?: throw IllegalStateException("No such tuple with id $id")
|
||||||
|
|
||||||
tuple.local.stack.shrink(tuple.stack.count)
|
tuple.local.stack.shrink(tuple.stack.count)
|
||||||
tuple.local.tuples.remove(tuple)
|
tuple.local.tuples.remove(tuple)
|
||||||
|
|
||||||
remoteByUUID.remove(id)
|
remoteTuples.remove(id)
|
||||||
|
|
||||||
val a = tuple.local.stack.count <= BigInteger.ZERO
|
val a = tuple.local.stack.count <= BigInteger.ZERO
|
||||||
val b = tuple.local.tuples.size == 0
|
val b = tuple.local.tuples.size == 0
|
||||||
|
|
||||||
if (a || b) {
|
if (a || b) {
|
||||||
check(a && b) { "View object is empty, but tuple list is not!" }
|
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()
|
val key = stack.key()
|
||||||
checkNotNull(tuples.remove(key)) { "No such stack $key" }
|
checkNotNull(hashedTuples.remove(key)) { "No such stack $key" }
|
||||||
|
|
||||||
for (listener in listeners) {
|
for (listener in listeners) {
|
||||||
listener.removeStack(tuple.local.stack, tuple.local.id)
|
listener.removeStack(tuple.local.stack, tuple.local.id)
|
||||||
@ -196,13 +212,13 @@ open class VirtualComponent<T : IStorageStack>(type: StorageStackType<T>) : IVir
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("unchecked_cast")
|
@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)
|
if (!amount.isPositive)
|
||||||
return this.storageType.empty
|
return this.storageType.empty
|
||||||
|
|
||||||
@Suppress("name_shadowing")
|
@Suppress("name_shadowing")
|
||||||
var amount = amount
|
var amount = amount
|
||||||
val tuple: LocalTuple<T>? = localByUUID[id]
|
val tuple: LocalTuple<T>? = localTuples[id]
|
||||||
|
|
||||||
if (tuple == null || amount.isZero)
|
if (tuple == null || amount.isZero)
|
||||||
return this.storageType.empty
|
return this.storageType.empty
|
||||||
@ -302,9 +318,9 @@ open class PoweredComponent<T : IStorageStack>(open val parent: IStorageComponen
|
|||||||
return stack
|
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 required = storageType.energyPerOperation * amount
|
||||||
val energy = energyProvider.invoke()
|
val energy = energyProvider.invoke()
|
||||||
val extracted = energy.extractEnergyInner(required, true)
|
val extracted = energy.extractEnergyInner(required, true)
|
||||||
@ -358,9 +374,9 @@ open class PoweredVirtualComponent<T : IStorageStack>(override val parent: IVirt
|
|||||||
constructor(parent: Class<T>, energy: IMatteryEnergyStorage) : this(VirtualComponent(parent), { energy })
|
constructor(parent: Class<T>, energy: IMatteryEnergyStorage) : this(VirtualComponent(parent), { energy })
|
||||||
constructor(parent: StorageStackType<T>, energy: IMatteryEnergyStorage) : this(VirtualComponent(parent), { energy })
|
constructor(parent: StorageStackType<T>, energy: IMatteryEnergyStorage) : this(VirtualComponent(parent), { energy })
|
||||||
|
|
||||||
override fun addStack(stack: T, id: UUID, provider: IStorageProvider<T>) = parent.addStack(stack, id, provider)
|
override fun addStack(stack: T, id: Long, provider: IStorageProvider<T>) = parent.addStack(stack, id, provider)
|
||||||
override fun changeStack(stack: T, id: UUID, oldCount: BigInteger) = parent.changeStack(stack, id, oldCount)
|
override fun changeStack(stack: T, id: Long, oldCount: BigInteger) = parent.changeStack(stack, id, oldCount)
|
||||||
override fun removeStack(stack: T, id: UUID) = parent.removeStack(stack, id)
|
override fun removeStack(stack: T, id: Long) = parent.removeStack(stack, id)
|
||||||
|
|
||||||
override fun add(identity: IStorage<T>) = parent.add(identity)
|
override fun add(identity: IStorage<T>) = parent.add(identity)
|
||||||
override fun remove(identity: IStorage<T>) = parent.remove(identity)
|
override fun remove(identity: IStorage<T>) = parent.remove(identity)
|
||||||
|
Loading…
Reference in New Issue
Block a user