package com.romangraef.jrconfig import com.romangraef.jrconfig.variables.* typealias ConfigVariableProvider = (ConfigSaveLoadProvider, String) -> ConfigVariable object Config { private var configProvider = mutableListOf() private val _usedPoints = mutableListOf() private val map: MutableMap, ConfigVariableProvider<*>> = mutableMapOf() private val proxyProvider: ConfigSaveLoadProvider = object : ConfigSaveLoadProvider { override fun provideData(point: String): String? = configProvider.map { it.provideData(point) }.filterNotNull().firstOrNull() override fun setData(point: String, data: String): Boolean = configProvider.asSequence().mapNotNull { it as? ConfigSaveLoadProvider }.map { it.setData(point, data) } .firstOrNull() ?: false } init { map[Double::class.java] = ::DoubleVariable map[Float::class.java] = ::FloatVariable map[Int::class.java] = ::IntegerVariable map[Long::class.java] = ::LongVariable map[String::class.java] = ::StringVariable } /** * A list of all registered points. This list is not necessarily complete. */ val usedPoints get() = _usedPoints.toList() @Suppress("UNCHECKED_CAST") @JvmStatic fun get(clazz: Class, point: String): ConfigVariable { _usedPoints.add(point) return (map[clazz] as? ConfigVariableProvider)?.invoke(proxyProvider, point) ?: throw ConfigMissingProviderException(clazz) } @JvmStatic fun > getEnum(enumClass: Class, point: String): ConfigVariable { _usedPoints.add(point) return EnumVariable(enumClass, proxyProvider, point) } inline fun get(point: String) = get(T::class.java, point) inline fun > getEnum(point: String) = getEnum(T::class.java, point) @JvmStatic fun registerConfigVariableProvider(clazz: Class, provider: ConfigVariableProvider) { map[clazz] = provider } inline fun registerConfigVariableProvider(noinline provider: ConfigVariableProvider) = registerConfigVariableProvider(T::class.java, provider) @JvmStatic fun use(provider: ConfigProvider) { configProvider.add(provider) } @JvmStatic fun useFirst(provider: ConfigProvider) { configProvider.add(0, provider) } @JvmStatic fun getString(point: String): ConfigVariable { return get(String::class.java, point) } }