All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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)!! }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy