From 9be5ca359d258cb40accca82365137c78bafe5dd Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Fri, 5 Jan 2024 23:50:10 +0700 Subject: [PATCH] Compute block shapes in background, reduces mod startup time to 1/3 of original --- .../ru/dbotthepony/mc/otm/block/Cables.kt | 4 +- .../dbotthepony/mc/otm/block/MatteryBlock.kt | 31 +++++++++----- .../mc/otm/block/decorative/EngineBlock.kt | 2 +- .../mc/otm/block/decorative/HoloSignBlock.kt | 2 +- .../mc/otm/block/matter/MatterPanelBlock.kt | 4 +- .../mc/otm/block/storage/StorageBusBlock.kt | 3 +- .../mc/otm/block/storage/StorageInterfaces.kt | 4 +- .../mc/otm/block/tech/EnergyCounterBlock.kt | 18 +++++--- .../block/tech/GravitationStabilizerBlock.kt | 34 ++++++++------- .../kotlin/ru/dbotthepony/mc/otm/core/Ext.kt | 11 +++++ .../mc/otm/core/collect/SupplierList.kt | 14 ++++++- .../mc/otm/core/collect/SupplierMap.kt | 42 ++++++++++++++----- 12 files changed, 117 insertions(+), 52 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/Cables.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/Cables.kt index e5bbdacc5..9b3cbd1d5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/Cables.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/Cables.kt @@ -55,8 +55,8 @@ abstract class CableBlock(properties: Properties) : MatteryBlock(properties) { ) } - protected fun generateShapes(halfCoreSize: Double): ImmutableMap { - return getShapeForEachState { getShapeFor(it, halfCoreSize) } + protected fun generateShapes(halfCoreSize: Double): Map { + return getShapeForEachStateMattery { getShapeFor(it, halfCoreSize) } } @Suppress("OVERRIDE_DEPRECATION") diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt index b1174f853..cd31ca398 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/MatteryBlock.kt @@ -5,6 +5,7 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap import it.unimi.dsi.fastutil.objects.Object2ObjectFunction import it.unimi.dsi.fastutil.objects.ObjectIterators import net.minecraft.ChatFormatting +import net.minecraft.Util import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.core.particles.DustParticleOptions @@ -32,41 +33,40 @@ import ru.dbotthepony.mc.otm.block.entity.IRedstoneControlled import ru.dbotthepony.mc.otm.block.entity.MatteryBlockEntity import ru.dbotthepony.mc.otm.block.entity.MatteryDeviceBlockEntity import ru.dbotthepony.mc.otm.block.entity.WorkerState -import ru.dbotthepony.mc.otm.client.isShiftDown -import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.core.ITooltippable import ru.dbotthepony.mc.otm.core.TranslatableComponent -import ru.dbotthepony.mc.otm.core.addAll import ru.dbotthepony.mc.otm.core.addDescriptionFunctions -import ru.dbotthepony.mc.otm.core.addDescriptionLines +import ru.dbotthepony.mc.otm.core.asSupplier +import ru.dbotthepony.mc.otm.core.collect.SupplierMap import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom import ru.dbotthepony.mc.otm.core.math.component1 import ru.dbotthepony.mc.otm.core.math.component2 import ru.dbotthepony.mc.otm.core.math.component3 -import ru.dbotthepony.mc.otm.core.stream import ru.dbotthepony.mc.otm.core.tagNotNull import ru.dbotthepony.mc.otm.once -import java.util.stream.Stream +import java.util.concurrent.Callable +import java.util.function.Function +import java.util.function.Supplier fun Block.getShapeForEachState(properties: List>, fn: (BlockState) -> VoxelShape): Map { - val builder = ImmutableMap.Builder() + val builder = Object2ObjectArrayMap>() if (properties.isEmpty()) { val shape = fn(stateDefinition.possibleStates.first()) for (state in stateDefinition.possibleStates) { - builder.put(state, shape) + builder.put(state, Supplier { shape }) } } else { - val cache = Object2ObjectArrayMap, VoxelShape>() + val cache = Object2ObjectArrayMap, Supplier>() for (state in stateDefinition.possibleStates) { - builder.put(state, cache.computeIfAbsent(properties.map { state[it] }, Object2ObjectFunction { fn(state) })) + builder.put(state, cache.computeIfAbsent(properties.map { state[it] }, Object2ObjectFunction { Util.backgroundExecutor().submit(Callable { fn(state) }).asSupplier() })) } } - return builder.build() + return SupplierMap(builder) } fun Block.getShapeForEachState(property: Property<*>, fn: (BlockState) -> VoxelShape): Map { @@ -107,6 +107,15 @@ open class MatteryBlock(properties: Properties = DEFAULT_PROPERTIES) : Block(pro super.setPlacedBy(level, blockPos, blockState, entity, itemStack) } + @Deprecated("Use OTM specific one", level = DeprecationLevel.ERROR, replaceWith = ReplaceWith("this.getShapeForEachStateMattery")) + override fun getShapeForEachState(mapper: Function): ImmutableMap { + return super.getShapeForEachState(mapper) + } + + fun getShapeForEachStateMattery(mapper: (BlockState) -> VoxelShape): Map { + return getShapeForEachState(ArrayList(stateDefinition.properties), mapper) + } + @Suppress("OVERRIDE_DEPRECATION") override fun use( blockState: BlockState, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/EngineBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/EngineBlock.kt index 8b2043ef4..dff575233 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/EngineBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/EngineBlock.kt @@ -33,7 +33,7 @@ class EngineBlock : RotatableMatteryBlock(Properties.of().mapColor(MapColor.COLO return BlockRotationFreedom.DIRECTIONAL } - private val shapes = getShapeForEachState { BlockShapes.ENGINE.rotateFromNorth(it[rotationProperty]).computeShape() } + private val shapes = getShapeForEachStateMattery { BlockShapes.ENGINE.rotateFromNorth(it[rotationProperty]).computeShape() } override fun getShape( p_60555_: BlockState, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/HoloSignBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/HoloSignBlock.kt index d54faef8e..6f878c493 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/HoloSignBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/decorative/HoloSignBlock.kt @@ -22,7 +22,7 @@ class HoloSignBlock : RotatableMatteryBlock(DEFAULT_MACHINE_PROPERTIES), EntityB return HoloSignBlockEntity(p_153215_, p_153216_) } - private val shapes = getShapeForEachState { BlockShapes.HOLO_SIGN.rotateFromNorth(it[rotationProperty]).computeShape() } + private val shapes = getShapeForEachStateMattery { BlockShapes.HOLO_SIGN.rotateFromNorth(it[rotationProperty]).computeShape() } override fun getShape( pState: BlockState, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/matter/MatterPanelBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/matter/MatterPanelBlock.kt index f8534819a..7de57144a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/matter/MatterPanelBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/matter/MatterPanelBlock.kt @@ -23,12 +23,12 @@ class MatterPanelBlock(val color: DyeColor?) : RotatableMatteryBlock(DEFAULT_MAC return MatterPanelBlockEntity(blockPos, blockState) } - private val shapes: ImmutableMap + private val shapes: Map init { registerDefaultState(getStateDefinition().any().setValue(BlockRotationFreedom.DIRECTIONAL.property, BlockRotation.SOUTH)) - shapes = getShapeForEachState { + shapes = getShapeForEachStateMattery { when (it[BlockRotationFreedom.DIRECTIONAL.property].front) { Direction.NORTH -> Shapes.box( 0.0, diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/storage/StorageBusBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/storage/StorageBusBlock.kt index 1f5f3f58e..151bfa1c9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/storage/StorageBusBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/storage/StorageBusBlock.kt @@ -22,6 +22,7 @@ import ru.dbotthepony.mc.otm.block.CableBlock import ru.dbotthepony.mc.otm.block.RotatableMatteryBlock import ru.dbotthepony.mc.otm.block.entity.MatteryPoweredBlockEntity import ru.dbotthepony.mc.otm.block.entity.storage.StorageBusBlockEntity +import ru.dbotthepony.mc.otm.block.getShapeForEachState import ru.dbotthepony.mc.otm.capability.energy.WorkerEnergyStorage import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.math.BlockRotation @@ -88,7 +89,7 @@ class StorageBusBlock : RotatableMatteryBlock(DEFAULT_MACHINE_PROPERTIES), Entit return BlockEntityTicker { _, _, _, tile -> if (tile is StorageBusBlockEntity) tile.tick() } } - private val shapes = getShapeForEachState { + private val shapes = getShapeForEachStateMattery { Shapes.joinUnoptimized(CableBlock.getShapeFor(it, 0.185), BlockShapes.STORAGE_BUS.rotateFromNorth(it[rotationProperty]).computeShape(), BooleanOp.OR) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/storage/StorageInterfaces.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/storage/StorageInterfaces.kt index 243af2941..b842c3d3c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/storage/StorageInterfaces.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/storage/StorageInterfaces.kt @@ -89,7 +89,7 @@ class StorageImporterBlock : RotatableMatteryBlock(DEFAULT_MACHINE_PROPERTIES), MatteryPoweredBlockEntity.appendHoverText(itemStack, blockAccessor, components, tooltipType) } - private val shapes = getShapeForEachState { + private val shapes = getShapeForEachStateMattery { Shapes.joinUnoptimized(CableBlock.getShapeFor(it, 0.185), BlockShapes.STORAGE_IMPORTER.rotateFromNorth(it[rotationProperty]).computeShape(), BooleanOp.OR) } @@ -162,7 +162,7 @@ class StorageExporterBlock : RotatableMatteryBlock(DEFAULT_MACHINE_PROPERTIES), return super.getStateForPlacement(context)?.setValue(BlockRotationFreedom.DIRECTIONAL.property, BlockRotation.of(-context.clickedFace)) } - private val shapes = getShapeForEachState { + private val shapes = getShapeForEachStateMattery { Shapes.joinUnoptimized(CableBlock.getShapeFor(it, 0.185), BlockShapes.STORAGE_EXPORTER.rotateFromNorth(it[rotationProperty]).computeShape(), BooleanOp.OR) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EnergyCounterBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EnergyCounterBlock.kt index 6e0e61f94..5f3d50d2b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EnergyCounterBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/EnergyCounterBlock.kt @@ -1,5 +1,7 @@ package ru.dbotthepony.mc.otm.block.tech +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap +import net.minecraft.Util import net.minecraft.core.BlockPos import net.minecraft.core.Direction import net.minecraft.world.item.context.BlockPlaceContext @@ -15,12 +17,14 @@ import net.minecraft.world.level.block.state.StateDefinition import net.minecraft.world.level.block.state.properties.EnumProperty import net.minecraft.world.phys.shapes.CollisionContext import net.minecraft.world.phys.shapes.VoxelShape -import ru.dbotthepony.mc.otm.SERVER_IS_LIVE import ru.dbotthepony.mc.otm.block.MatteryBlock import ru.dbotthepony.mc.otm.block.entity.tech.EnergyCounterBlockEntity -import ru.dbotthepony.mc.otm.once +import ru.dbotthepony.mc.otm.core.asSupplier +import ru.dbotthepony.mc.otm.core.collect.SupplierMap import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.shapes.BlockShapes +import java.util.concurrent.Callable +import java.util.function.Supplier class EnergyCounterBlock : MatteryBlock(DEFAULT_MACHINE_PROPERTIES), EntityBlock { override fun newBlockEntity(blockPos: BlockPos, blockState: BlockState): BlockEntity { @@ -63,9 +67,11 @@ class EnergyCounterBlock : MatteryBlock(DEFAULT_MACHINE_PROPERTIES), EntityBlock p_49915_.add(INPUT_DIRECTION, IF_DIRECTION) } - private val SHAPES = HashMap() + private val shapes: Map init { + val shapes = Object2ObjectOpenHashMap>() + for (state in stateDefinition.possibleStates) { val input: Direction = state.getValue(INPUT_DIRECTION) val iface: Direction = state.getValue(IF_DIRECTION) @@ -101,8 +107,10 @@ class EnergyCounterBlock : MatteryBlock(DEFAULT_MACHINE_PROPERTIES), EntityBlock } } - SHAPES[state] = shape.computeShape() + shapes[state] = Util.backgroundExecutor().submit(Callable { shape.computeShape() }).asSupplier() } + + this.shapes = SupplierMap(shapes) } override fun getShape( @@ -111,7 +119,7 @@ class EnergyCounterBlock : MatteryBlock(DEFAULT_MACHINE_PROPERTIES), EntityBlock p_60557_: BlockPos, p_60558_: CollisionContext ): VoxelShape { - return SHAPES[blockState] ?: super.getShape(blockState, p_60556_, p_60557_, p_60558_) + return shapes[blockState] ?: super.getShape(blockState, p_60556_, p_60557_, p_60558_) } companion object { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/GravitationStabilizerBlock.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/GravitationStabilizerBlock.kt index 0367b5564..fb79e1f1a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/GravitationStabilizerBlock.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/block/tech/GravitationStabilizerBlock.kt @@ -28,11 +28,13 @@ import ru.dbotthepony.mc.otm.block.addSimpleDescription import ru.dbotthepony.mc.otm.block.entity.tech.GravitationStabilizerBlockEntity import ru.dbotthepony.mc.otm.block.entity.blackhole.BlackHoleBlockEntity import ru.dbotthepony.mc.otm.block.entity.WorkerState +import ru.dbotthepony.mc.otm.core.collect.SupplierList import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom import ru.dbotthepony.mc.otm.core.math.plus import ru.dbotthepony.mc.otm.core.math.times import ru.dbotthepony.mc.otm.core.needsNoPowerDescription +import ru.dbotthepony.mc.otm.core.runInBackground import ru.dbotthepony.mc.otm.oncePre import ru.dbotthepony.mc.otm.registry.MBlockEntities import ru.dbotthepony.mc.otm.registry.MBlocks @@ -140,7 +142,7 @@ class BlockGravitationStabilizer : RotatableMatteryBlock(props), EntityBlock { p_60557_: BlockPos, p_60558_: CollisionContext ): VoxelShape { - return SHAPES[p_60555_[BlockRotationFreedom.DIRECTIONAL].ordinal] + return shapes[p_60555_[BlockRotationFreedom.DIRECTIONAL].ordinal] } init { @@ -151,13 +153,13 @@ class BlockGravitationStabilizer : RotatableMatteryBlock(props), EntityBlock { } companion object { - private val SHAPES = arrayOf( - BlockShapes.GRAVITATION_STABILIZER.rotateAroundX(PI / 2).computeShape(), - BlockShapes.GRAVITATION_STABILIZER.rotateAroundX(-PI / 2).computeShape(), - BlockShapes.GRAVITATION_STABILIZER.computeShape(), - BlockShapes.GRAVITATION_STABILIZER.rotateFromSouth(Direction.NORTH).computeShape(), - BlockShapes.GRAVITATION_STABILIZER.rotateFromSouth(Direction.WEST).computeShape(), - BlockShapes.GRAVITATION_STABILIZER.rotateFromSouth(Direction.EAST).computeShape() + private val shapes = SupplierList.ofFuture( + runInBackground { BlockShapes.GRAVITATION_STABILIZER.rotateAroundX(PI / 2).computeShape() }, + runInBackground { BlockShapes.GRAVITATION_STABILIZER.rotateAroundX(-PI / 2).computeShape() }, + runInBackground { BlockShapes.GRAVITATION_STABILIZER.computeShape() }, + runInBackground { BlockShapes.GRAVITATION_STABILIZER.rotateFromSouth(Direction.NORTH).computeShape() }, + runInBackground { BlockShapes.GRAVITATION_STABILIZER.rotateFromSouth(Direction.WEST).computeShape() }, + runInBackground { BlockShapes.GRAVITATION_STABILIZER.rotateFromSouth(Direction.EAST).computeShape() }, ) fun getBoundingBlock(level: Level, blockState: BlockState, blockPos: BlockPos): BlockState { @@ -206,7 +208,7 @@ class BlockGravitationStabilizerLens : RotatableMatteryBlock(props) { p_60557_: BlockPos, p_60558_: CollisionContext ): VoxelShape { - return SHAPES[p_60555_[BlockRotationFreedom.DIRECTIONAL].front.ordinal] + return shapes[p_60555_[BlockRotationFreedom.DIRECTIONAL].front.ordinal] } companion object { @@ -218,13 +220,13 @@ class BlockGravitationStabilizerLens : RotatableMatteryBlock(props) { return blockPos + blockState.getValue(BlockRotationFreedom.DIRECTIONAL.property).front.opposite.normal } - private val SHAPES = arrayOf( - BlockShapes.GRAVITATION_STABILIZER_LENS.rotateAroundX(PI / 2).computeShape(), - BlockShapes.GRAVITATION_STABILIZER_LENS.rotateAroundX(-PI / 2).computeShape(), - BlockShapes.GRAVITATION_STABILIZER_LENS.computeShape(), - BlockShapes.GRAVITATION_STABILIZER_LENS.rotateFromSouth(Direction.NORTH).computeShape(), - BlockShapes.GRAVITATION_STABILIZER_LENS.rotateFromSouth(Direction.WEST).computeShape(), - BlockShapes.GRAVITATION_STABILIZER_LENS.rotateFromSouth(Direction.EAST).computeShape() + private val shapes = SupplierList.ofFuture( + runInBackground { BlockShapes.GRAVITATION_STABILIZER_LENS.rotateAroundX(PI / 2).computeShape() }, + runInBackground { BlockShapes.GRAVITATION_STABILIZER_LENS.rotateAroundX(-PI / 2).computeShape() }, + runInBackground { BlockShapes.GRAVITATION_STABILIZER_LENS.computeShape() }, + runInBackground { BlockShapes.GRAVITATION_STABILIZER_LENS.rotateFromSouth(Direction.NORTH).computeShape() }, + runInBackground { BlockShapes.GRAVITATION_STABILIZER_LENS.rotateFromSouth(Direction.WEST).computeShape() }, + runInBackground { BlockShapes.GRAVITATION_STABILIZER_LENS.rotateFromSouth(Direction.EAST).computeShape() }, ) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt index 6e5a286b9..deb2df51e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/Ext.kt @@ -11,6 +11,7 @@ import com.google.gson.JsonElement import com.google.gson.JsonObject import com.google.gson.JsonPrimitive import it.unimi.dsi.fastutil.objects.ObjectComparators +import net.minecraft.Util import net.minecraft.core.BlockPos import net.minecraft.nbt.CompoundTag import net.minecraft.nbt.NbtAccounter @@ -52,6 +53,8 @@ import java.math.BigInteger import java.util.Arrays import java.util.Spliterators import java.util.UUID +import java.util.concurrent.Callable +import java.util.concurrent.Future import java.util.function.Consumer import java.util.function.Supplier import java.util.stream.Stream @@ -86,6 +89,14 @@ fun Map<*, V>.asSupplierArray(): Array> { return result as Array> } +fun Future.asSupplier(): Supplier { + return Supplier { get() } +} + +fun runInBackground(block: Callable): Future { + return Util.backgroundExecutor().submit(block) +} + operator fun IItemHandler.get(index: Int): ItemStack = getStackInSlot(index) operator fun JsonObject.set(s: String, value: JsonElement) = add(s, value) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/SupplierList.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/SupplierList.kt index e45cb685b..ec1764c55 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/SupplierList.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/SupplierList.kt @@ -1,5 +1,7 @@ package ru.dbotthepony.mc.otm.core.collect +import ru.dbotthepony.mc.otm.core.stream +import java.util.concurrent.Future import java.util.function.Supplier import java.util.stream.Stream @@ -12,7 +14,7 @@ class SupplierList : AbstractList { } constructor(getters: Stream>) : super() { - this.getters = getters.toArray(::arrayOfNulls) + this.getters = getters.toArray { arrayOfNulls>(it) } } constructor(vararg getters: Supplier) : super() { @@ -29,4 +31,14 @@ class SupplierList : AbstractList { override fun get(index: Int): T { return getters[index].get() } + + companion object { + fun ofLazy(vararg values: Lazy): SupplierList { + return SupplierList(values.stream().map { Supplier { it.value } }) + } + + fun ofFuture(vararg values: Future): SupplierList { + return SupplierList(values.stream().map { Supplier { it.get() } }) + } + } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/SupplierMap.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/SupplierMap.kt index 7211301a9..4c0527a99 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/SupplierMap.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/collect/SupplierMap.kt @@ -1,31 +1,53 @@ package ru.dbotthepony.mc.otm.core.collect +import com.google.common.collect.ImmutableMap import com.google.common.collect.ImmutableSet +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap +import ru.dbotthepony.mc.otm.core.stream import java.util.function.Supplier import java.util.stream.Stream -class SupplierMap : AbstractMap { +class SupplierMap(values: Stream>>) : Map { + private val backing = Object2ObjectOpenHashMap>() override val entries: Set> + override val keys: Set + get() = backing.keys + override val size: Int + get() = entries.size + override val values: Collection - constructor(vararg mValues: Pair>) : super() { - entries = ImmutableSet.copyOf(mValues.map { Entry(it.first, it.second) }) + init { + values.forEach { + backing[it.first] = it.second + } + + entries = ImmutableSet.copyOf(backing.entries.map { Entry(it.key, it.value) }) + this.values = SupplierList(backing.values) } - constructor(mValues: Collection>>) : super() { - entries = ImmutableSet.copyOf(mValues.map { Entry(it.first, it.second) }) + override fun containsKey(key: K): Boolean { + return key in keys } - constructor(mValues: Stream>>) : super() { - entries = mValues.map { Entry(it.first, it.second) }.collect(ImmutableSet.toImmutableSet()) + override fun containsValue(value: T): Boolean { + return value in values } - constructor(mValues: Map T>) : super() { - entries = ImmutableSet.copyOf(mValues.map { Entry(it.key, it.value) }) + override fun get(key: K): T? { + return backing[key]?.get() } + override fun isEmpty(): Boolean { + return entries.isEmpty() + } + + constructor(vararg mValues: Pair>) : this((mValues as Array>>).stream()) + constructor(mValues: Collection>>) : this(mValues.stream()) + constructor(mValues: Map>) : this(mValues.entries.stream().map { it.key to it.value }) + private inner class Entry( override val key: K, - private val getter: Supplier + val getter: Supplier ) : Map.Entry { override val value: T get() = getter.get()