aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinnea Gräf <nea@nea.moe>2025-10-13 18:17:42 +0200
committerLinnea Gräf <nea@nea.moe>2025-10-13 18:26:42 +0200
commit72347d1e5b10061a30b177de4574c1044a7f7c4c (patch)
treeba5a5c68a8bb175a24d037939858fe04477d351c
parent9b6c8f21f86385c993c0e34ba4b31348cae200cd (diff)
downloadFirmament-72347d1e5b10061a30b177de4574c1044a7f7c4c.tar.gz
Firmament-72347d1e5b10061a30b177de4574c1044a7f7c4c.tar.bz2
Firmament-72347d1e5b10061a30b177de4574c1044a7f7c4c.zip
fix: performance of serializing virtual inventory
-rw-r--r--src/main/kotlin/features/inventory/storageoverlay/VirtualInventory.kt44
-rw-r--r--src/main/kotlin/gui/config/storage/FirstLevelSplitJsonFolder.kt1
-rw-r--r--src/main/kotlin/util/MC.kt3
3 files changed, 32 insertions, 16 deletions
diff --git a/src/main/kotlin/features/inventory/storageoverlay/VirtualInventory.kt b/src/main/kotlin/features/inventory/storageoverlay/VirtualInventory.kt
index 83e0d19..4e40cf1 100644
--- a/src/main/kotlin/features/inventory/storageoverlay/VirtualInventory.kt
+++ b/src/main/kotlin/features/inventory/storageoverlay/VirtualInventory.kt
@@ -4,6 +4,8 @@ import io.ktor.util.decodeBase64Bytes
import io.ktor.util.encodeBase64
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
+import java.util.concurrent.CompletableFuture
+import kotlinx.coroutines.async
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
@@ -18,6 +20,8 @@ import net.minecraft.nbt.NbtIo
import net.minecraft.nbt.NbtList
import net.minecraft.nbt.NbtOps
import net.minecraft.nbt.NbtSizeTracker
+import moe.nea.firmament.Firmament
+import moe.nea.firmament.features.inventory.storageoverlay.VirtualInventory.Serializer.writeToByteArray
import moe.nea.firmament.util.ErrorUtil
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.mc.TolerantRegistriesOps
@@ -28,6 +32,10 @@ data class VirtualInventory(
) {
val rows = stacks.size / 9
+ val serializationCache = CompletableFuture.supplyAsync {
+ writeToByteArray(this)
+ }
+
init {
assert(stacks.size % 9 == 0)
assert(stacks.size / 9 in 1..5)
@@ -35,6 +43,25 @@ data class VirtualInventory(
object Serializer : KSerializer<VirtualInventory> {
+ fun writeToByteArray(value: VirtualInventory): ByteArray {
+ val list = NbtList()
+ val ops = getOps()
+ value.stacks.forEach {
+ if (it.isEmpty) list.add(NbtCompound())
+ else list.add(ErrorUtil.catch("Could not serialize item") {
+ ItemStack.CODEC.encode(
+ it,
+ ops,
+ NbtCompound()
+ ).orThrow
+ }
+ .or { NbtCompound() })
+ }
+ val baos = ByteArrayOutputStream()
+ NbtIo.writeCompressed(NbtCompound().also { it.put(INVENTORY, list) }, baos)
+ return baos.toByteArray()
+ }
+
const val INVENTORY = "INVENTORY"
override val descriptor: SerialDescriptor
get() = PrimitiveSerialDescriptor("VirtualInventory", PrimitiveKind.STRING)
@@ -53,23 +80,10 @@ data class VirtualInventory(
} ?: listOf())
}
- fun getOps() = TolerantRegistriesOps(NbtOps.INSTANCE, MC.currentOrDefaultRegistries)
+ fun getOps() = MC.currentOrDefaultRegistryNbtOps
override fun serialize(encoder: Encoder, value: VirtualInventory) {
- val list = NbtList()
- val ops = getOps()
- value.stacks.forEach {
- if (it.isEmpty) list.add(NbtCompound())
- else list.add(ErrorUtil.catch("Could not serialize item") {
- ItemStack.CODEC.encode(it,
- ops,
- NbtCompound()).orThrow
- }
- .or { NbtCompound() })
- }
- val baos = ByteArrayOutputStream()
- NbtIo.writeCompressed(NbtCompound().also { it.put(INVENTORY, list) }, baos)
- encoder.encodeString(baos.toByteArray().encodeBase64())
+ encoder.encodeString(value.serializationCache.get().encodeBase64())
}
}
}
diff --git a/src/main/kotlin/gui/config/storage/FirstLevelSplitJsonFolder.kt b/src/main/kotlin/gui/config/storage/FirstLevelSplitJsonFolder.kt
index 3c672bf..b92488a 100644
--- a/src/main/kotlin/gui/config/storage/FirstLevelSplitJsonFolder.kt
+++ b/src/main/kotlin/gui/config/storage/FirstLevelSplitJsonFolder.kt
@@ -17,6 +17,7 @@ import kotlin.io.path.nameWithoutExtension
import kotlin.io.path.outputStream
import moe.nea.firmament.Firmament
+// TODO: make this class write / read async
class FirstLevelSplitJsonFolder(
val context: ConfigLoadContext,
val folder: Path
diff --git a/src/main/kotlin/util/MC.kt b/src/main/kotlin/util/MC.kt
index 33b0bb3..ed5cac3 100644
--- a/src/main/kotlin/util/MC.kt
+++ b/src/main/kotlin/util/MC.kt
@@ -32,6 +32,7 @@ import net.minecraft.util.math.BlockPos
import net.minecraft.world.World
import moe.nea.firmament.events.TickEvent
import moe.nea.firmament.events.WorldReadyEvent
+import moe.nea.firmament.util.mc.TolerantRegistriesOps
object MC {
@@ -121,7 +122,7 @@ object MC {
val defaultRegistries: RegistryWrapper.WrapperLookup by lazy { BuiltinRegistries.createWrapperLookup() }
val defaultRegistryNbtOps by lazy { RegistryOps.of(NbtOps.INSTANCE, defaultRegistries) }
inline val currentOrDefaultRegistries get() = currentRegistries ?: defaultRegistries
- val currentOrDefaultRegistryNbtOps get() = RegistryOps.of(NbtOps.INSTANCE, currentOrDefaultRegistries)
+ val currentOrDefaultRegistryNbtOps get() = TolerantRegistriesOps(NbtOps.INSTANCE, currentOrDefaultRegistries)
val defaultItems: RegistryWrapper.Impl<Item> by lazy { defaultRegistries.getOrThrow(RegistryKeys.ITEM) }
var currentTick = 0
var lastWorld: World? = null