From e5fc516ef1e8dbe5f977b61fb7f4d888808414ad Mon Sep 17 00:00:00 2001 From: Graham Date: Sat, 29 May 2021 21:48:40 +0100 Subject: [PATCH] Add base classes for encoding/decoding configs Signed-off-by: Graham --- .../cache/config/ArchiveConfigTypeList.kt | 29 +++++++++++++ .../org/openrs2/cache/config/ConfigType.kt | 21 ++++++++++ .../openrs2/cache/config/ConfigTypeList.kt | 42 +++++++++++++++++++ .../cache/config/GroupConfigTypeList.kt | 21 ++++++++++ 4 files changed, 113 insertions(+) create mode 100644 cache/src/main/kotlin/org/openrs2/cache/config/ArchiveConfigTypeList.kt create mode 100644 cache/src/main/kotlin/org/openrs2/cache/config/ConfigType.kt create mode 100644 cache/src/main/kotlin/org/openrs2/cache/config/ConfigTypeList.kt create mode 100644 cache/src/main/kotlin/org/openrs2/cache/config/GroupConfigTypeList.kt diff --git a/cache/src/main/kotlin/org/openrs2/cache/config/ArchiveConfigTypeList.kt b/cache/src/main/kotlin/org/openrs2/cache/config/ArchiveConfigTypeList.kt new file mode 100644 index 00000000..4269bc62 --- /dev/null +++ b/cache/src/main/kotlin/org/openrs2/cache/config/ArchiveConfigTypeList.kt @@ -0,0 +1,29 @@ +package org.openrs2.cache.config + +import org.openrs2.cache.Cache + +public abstract class ArchiveConfigTypeList( + cache: Cache, + archive: Int, + private val fileBits: Int +) : ConfigTypeList(cache, archive) { + private val fileMask = (1 shl fileBits) - 1 + + override fun calculateCapacity(): Int { + val archiveCapacity = cache.capacity(archive) + if (archiveCapacity == 0) { + return 0 + } + + val groupCapacity = cache.capacity(archive, archiveCapacity - 1) + return ((archiveCapacity - 1) shl fileBits) or groupCapacity + } + + override fun getGroupId(id: Int): Int { + return id ushr fileBits + } + + override fun getFileId(id: Int): Int { + return id and fileMask + } +} diff --git a/cache/src/main/kotlin/org/openrs2/cache/config/ConfigType.kt b/cache/src/main/kotlin/org/openrs2/cache/config/ConfigType.kt new file mode 100644 index 00000000..b760d565 --- /dev/null +++ b/cache/src/main/kotlin/org/openrs2/cache/config/ConfigType.kt @@ -0,0 +1,21 @@ +package org.openrs2.cache.config + +import io.netty.buffer.ByteBuf + +public abstract class ConfigType( + public val id: Int +) { + public abstract fun read(buf: ByteBuf, code: Int) + public abstract fun write(buf: ByteBuf) + + public fun read(buf: ByteBuf) { + while (true) { + val code = buf.readUnsignedByte().toInt() + if (code == 0) { + break + } + + read(buf, code) + } + } +} diff --git a/cache/src/main/kotlin/org/openrs2/cache/config/ConfigTypeList.kt b/cache/src/main/kotlin/org/openrs2/cache/config/ConfigTypeList.kt new file mode 100644 index 00000000..abc9315b --- /dev/null +++ b/cache/src/main/kotlin/org/openrs2/cache/config/ConfigTypeList.kt @@ -0,0 +1,42 @@ +package org.openrs2.cache.config + +import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap +import org.openrs2.buffer.use +import org.openrs2.cache.Cache + +public abstract class ConfigTypeList( + protected val cache: Cache, + protected val archive: Int +) { + private val types = Int2ObjectOpenHashMap() + + public val capacity: Int by lazy { + calculateCapacity() + } + + public operator fun get(id: Int): T? { + var type = types[id] + if (type != null) { + return type + } + + val group = getGroupId(id) + val file = getFileId(id) + if (!cache.exists(archive, group, file)) { + // TODO(gpe): the client returns an empty config - should we do that? + return null + } + + cache.read(archive, group, file).use { buf -> + type = allocate(id) + type.read(buf) + types[id] = type + return type + } + } + + protected abstract fun allocate(id: Int): T + protected abstract fun calculateCapacity(): Int + protected abstract fun getGroupId(id: Int): Int + protected abstract fun getFileId(id: Int): Int +} diff --git a/cache/src/main/kotlin/org/openrs2/cache/config/GroupConfigTypeList.kt b/cache/src/main/kotlin/org/openrs2/cache/config/GroupConfigTypeList.kt new file mode 100644 index 00000000..0b72ffbb --- /dev/null +++ b/cache/src/main/kotlin/org/openrs2/cache/config/GroupConfigTypeList.kt @@ -0,0 +1,21 @@ +package org.openrs2.cache.config + +import org.openrs2.cache.Cache + +public abstract class GroupConfigTypeList( + cache: Cache, + archive: Int, + private val group: Int +) : ConfigTypeList(cache, archive) { + override fun calculateCapacity(): Int { + return cache.capacity(archive, group) + } + + override fun getGroupId(id: Int): Int { + return group + } + + override fun getFileId(id: Int): Int { + return id + } +}