87 lines
3.2 KiB
Kotlin
87 lines
3.2 KiB
Kotlin
package ru.dbotthepony.kstarbound.item
|
|
|
|
import com.google.gson.JsonElement
|
|
import it.unimi.dsi.fastutil.objects.Object2ObjectFunction
|
|
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap
|
|
import org.apache.logging.log4j.LogManager
|
|
import ru.dbotthepony.kstarbound.IStarboundFile
|
|
import ru.dbotthepony.kstarbound.Starbound
|
|
import ru.dbotthepony.kstarbound.defs.actor.player.RecipeDefinition
|
|
import ru.dbotthepony.kstarbound.json.JsonPatch
|
|
import java.util.*
|
|
import java.util.concurrent.ConcurrentLinkedQueue
|
|
import java.util.concurrent.Future
|
|
import kotlin.collections.ArrayList
|
|
|
|
object RecipeRegistry {
|
|
private val LOGGER = LogManager.getLogger()
|
|
|
|
data class Entry(val value: RecipeDefinition, val json: JsonElement, val file: IStarboundFile)
|
|
|
|
private val recipesInternal = ArrayList<Entry>()
|
|
private val group2recipesInternal = Object2ObjectOpenHashMap<String, ArrayList<Entry>>()
|
|
private val group2recipesBacking = Object2ObjectOpenHashMap<String, List<Entry>>()
|
|
private val output2recipesInternal = Object2ObjectOpenHashMap<String, ArrayList<Entry>>()
|
|
private val output2recipesBacking = Object2ObjectOpenHashMap<String, List<Entry>>()
|
|
private val input2recipesInternal = Object2ObjectOpenHashMap<String, ArrayList<Entry>>()
|
|
private val input2recipesBacking = Object2ObjectOpenHashMap<String, List<Entry>>()
|
|
|
|
val recipes: List<Entry> = Collections.unmodifiableList(recipesInternal)
|
|
val group2recipes: Map<String, List<Entry>> = Collections.unmodifiableMap(group2recipesBacking)
|
|
val output2recipes: Map<String, List<Entry>> = Collections.unmodifiableMap(output2recipesBacking)
|
|
val input2recipes: Map<String, List<Entry>> = Collections.unmodifiableMap(input2recipesBacking)
|
|
|
|
private val tasks = ConcurrentLinkedQueue<Entry>()
|
|
|
|
private fun add(recipe: Entry) {
|
|
val value = recipe.value
|
|
recipesInternal.add(recipe)
|
|
|
|
for (group in value.groups) {
|
|
group2recipesInternal.computeIfAbsent(group, Object2ObjectFunction { p ->
|
|
ArrayList<Entry>(1).also {
|
|
group2recipesBacking[p as String] = Collections.unmodifiableList(it)
|
|
}
|
|
}).add(recipe)
|
|
}
|
|
|
|
output2recipesInternal.computeIfAbsent(value.output.name, Object2ObjectFunction { p ->
|
|
ArrayList<Entry>(1).also {
|
|
output2recipesBacking[p as String] = Collections.unmodifiableList(it)
|
|
}
|
|
}).add(recipe)
|
|
|
|
for (input in value.input) {
|
|
input2recipesInternal.computeIfAbsent(input.name, Object2ObjectFunction { p ->
|
|
ArrayList<Entry>(1).also {
|
|
input2recipesBacking[p as String] = Collections.unmodifiableList(it)
|
|
}
|
|
}).add(recipe)
|
|
}
|
|
}
|
|
|
|
fun finishLoad() {
|
|
tasks.forEach { add(it) }
|
|
tasks.clear()
|
|
}
|
|
|
|
fun load(fileTree: Map<String, Collection<IStarboundFile>>, patchTree: Map<String, List<IStarboundFile>>): List<Future<*>> {
|
|
val files = fileTree["recipe"] ?: return emptyList()
|
|
|
|
val recipes by lazy { Starbound.gson.getAdapter(RecipeDefinition::class.java) }
|
|
|
|
return files.map { listedFile ->
|
|
Starbound.EXECUTOR.submit {
|
|
try {
|
|
val json = JsonPatch.apply(Starbound.ELEMENTS_ADAPTER.read(listedFile.jsonReader()), patchTree[listedFile.computeFullPath()])
|
|
|
|
val value = recipes.fromJsonTree(json)
|
|
tasks.add(Entry(value, json, listedFile))
|
|
} catch (err: Throwable) {
|
|
LOGGER.error("Loading recipe definition file $listedFile", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|