add Context

This commit is contained in:
tursom 2022-04-05 20:24:30 +08:00
parent e11da44ac9
commit 00baa0c063
5 changed files with 98 additions and 0 deletions

View File

@ -0,0 +1,36 @@
package cn.tursom.core.context
import cn.tursom.core.uncheckedCast
import java.util.concurrent.atomic.AtomicInteger
class ArrayContextEnv : ContextEnv {
val envId = ContextEnv.newEnvId()
private val idGenerator = AtomicInteger()
override fun newContext(): Context = ArrayContext(envId, idGenerator)
override fun <T> newKey() = ContextKey<T>(envId, idGenerator.getAndIncrement())
private class ArrayContext(
override val envId: Int,
private val idGenerator: AtomicInteger,
) : Context {
private var array = arrayOfNulls<Any?>(idGenerator.get())
override operator fun <T> get(key: ContextKey<T>): T? {
checkEnv(key)
return if (array.size < key.id) {
null
} else {
array[key.id]?.uncheckedCast<T>()
}
}
override operator fun <T> set(key: ContextKey<T>, value: T) {
checkEnv(key)
if (array.size < key.id) {
array = array.copyOf(idGenerator.get())
}
array[key.id] = value
}
}
}

View File

@ -0,0 +1,15 @@
package cn.tursom.core.context
interface Context {
val envId: Int
operator fun <T> get(key: ContextKey<T>): T?
operator fun <T> set(key: ContextKey<T>, value: T)
fun checkEnv(key: ContextKey<*>) {
if (envId != key.envId) {
throw UnsupportedOperationException()
}
}
}

View File

@ -0,0 +1,13 @@
package cn.tursom.core.context
import java.util.concurrent.atomic.AtomicInteger
interface ContextEnv {
companion object {
private val contextEnvIdGenerator = AtomicInteger()
fun newEnvId() = contextEnvIdGenerator.incrementAndGet()
}
fun newContext(): Context
fun <T> newKey(): ContextKey<T>
}

View File

@ -0,0 +1,6 @@
package cn.tursom.core.context
data class ContextKey<T>(
val envId: Int,
val id: Int,
)

View File

@ -0,0 +1,28 @@
package cn.tursom.core.context
import cn.tursom.core.uncheckedCast
import java.util.concurrent.atomic.AtomicInteger
class HashMapContextEnv : ContextEnv {
val envId = ContextEnv.newEnvId()
private val idGenerator = AtomicInteger()
override fun newContext(): Context = HashMapContext(envId)
override fun <T> newKey() = ContextKey<T>(envId, idGenerator.getAndIncrement())
private class HashMapContext(
override val envId: Int,
) : Context {
private var map = HashMap<Int, Any?>()
override operator fun <T> get(key: ContextKey<T>): T? {
checkEnv(key)
return map[key.id]?.uncheckedCast<T>()
}
override operator fun <T> set(key: ContextKey<T>, value: T) {
checkEnv(key)
map[key.id] = value
}
}
}