com.neko233.config233.repository.ConfigDataRepository.kt Maven / Gradle / Ivy
The newest version!
package com.neko233.config233.repository
import com.neko233.config233.annotation.ConfigUid233
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.memberProperties
import kotlin.reflect.jvm.javaField
/**
* 【配置数据仓库】
*
* 1、存储所有 ORM 后的数据
* 2、记录 change listener
*/
class ConfigDataRepository {
/**
* , List>
*/
private val typeToDataListMap = ConcurrentHashMap, List<*>>()
// , 该配置数据热更新的 Listener>
private val typeToChangeListenerMap = ConcurrentHashMap, MutableList>()
/**
* 项目才能放入数据
*/
internal fun put(
clazz: Class,
dataList: List,
) {
typeToDataListMap[clazz] = dataList
// 触发更新. 首次放入也会触发
val listenerList = typeToChangeListenerMap.getOrDefault(clazz, emptyList())
for (listener in listenerList) {
listener.onConfigDataChange(clazz, dataList)
}
}
@Suppress("UNCHECKED_CAST")
fun get(clazz: Class): List {
println("get data from configDataRepository: $clazz")
val resultList = typeToDataListMap[clazz]
return resultList as? List ?: emptyList()
}
fun getAll(): ConcurrentHashMap, List<*>> {
return typeToDataListMap
}
/**
* add 配置变更监听器
*/
fun addConfigChangeListener(clazz: Class, listener: ConfigDataChangeListener): ConfigDataRepository {
typeToChangeListenerMap.computeIfAbsent(clazz) { CopyOnWriteArrayList() }
.add(listener)
return this
}
/**
* remove 配置变更监听器
*/
fun removeConfigChangeListener(clazz: Class, listener: ConfigDataChangeListener): ConfigDataRepository {
typeToChangeListenerMap.computeIfAbsent(clazz) { CopyOnWriteArrayList() }
.remove(listener)
return this
}
/**
* remove 配置变更监听器
*/
fun removeAllConfigChangeListener(clazz: Class): ConfigDataRepository {
typeToChangeListenerMap.remove(clazz)
return this
}
/**
* 获取为 Map<唯一 id, data>
*/
@Suppress("UNCHECKED_CAST")
fun getUidMapByAnnotation(clazz: Class): Map {
val dataList = typeToDataListMap.getOrDefault(clazz, emptyList()) as List
return listToUidMapByFixedAnnotation(dataList)
}
@Suppress("FoldInitializerAndIfToElvis")
private fun listToUidMapByFixedAnnotation(list: List): Map {
if (list.isEmpty()) {
return emptyMap()
}
val first: Any = list.first() as Any
if (first == null) {
return emptyMap()
}
val uidField = first.javaClass.kotlin.memberProperties
.find { property ->
property.javaField?.getAnnotation(ConfigUid233::class.java) != null
}
?: error("No field annotated with @ConfigUid233 in class ${first.javaClass.simpleName}")
return list.associateBy { uidField.get(it as Any)!! }
}
}