forked from openrs2/openrs2
parent
e0ec3781ae
commit
e5fc516ef1
@ -0,0 +1,29 @@ |
||||
package org.openrs2.cache.config |
||||
|
||||
import org.openrs2.cache.Cache |
||||
|
||||
public abstract class ArchiveConfigTypeList<T : ConfigType>( |
||||
cache: Cache, |
||||
archive: Int, |
||||
private val fileBits: Int |
||||
) : ConfigTypeList<T>(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 |
||||
} |
||||
} |
@ -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) |
||||
} |
||||
} |
||||
} |
@ -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<T : ConfigType>( |
||||
protected val cache: Cache, |
||||
protected val archive: Int |
||||
) { |
||||
private val types = Int2ObjectOpenHashMap<T>() |
||||
|
||||
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 |
||||
} |
@ -0,0 +1,21 @@ |
||||
package org.openrs2.cache.config |
||||
|
||||
import org.openrs2.cache.Cache |
||||
|
||||
public abstract class GroupConfigTypeList<T : ConfigType>( |
||||
cache: Cache, |
||||
archive: Int, |
||||
private val group: Int |
||||
) : ConfigTypeList<T>(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 |
||||
} |
||||
} |
Loading…
Reference in new issue