[WIP] Config parser

This commit is contained in:
octarine-noise
2021-07-12 19:12:42 +02:00
parent 29ab544269
commit c8e79c22ff
12 changed files with 591 additions and 2 deletions

View File

@@ -0,0 +1,79 @@
package mods.betterfoliage.resource.discovery
import mods.betterfoliage.BetterFoliage
import mods.betterfoliage.config.match.MatchResult
import mods.betterfoliage.config.match.MatchRuleList
import mods.betterfoliage.config.match.Node
import mods.betterfoliage.util.HasLogger
import net.minecraft.client.renderer.model.BlockModel
import net.minecraft.client.renderer.model.VariantList
import net.minecraft.util.ResourceLocation
import org.apache.logging.log4j.Level
abstract class ParametrizedModelDiscovery : HasLogger() {
abstract fun processModel(ctx: ModelDiscoveryContext, params: Map<String, String>)
fun Map<String, String>.texture(key: String): ResourceLocation? {
val result = get(key)?.let { ResourceLocation(it) }
if (result == null) detailLogger.log(Level.WARN, "Cannot find texture parameter \"$key\"")
return result
}
}
class RuleProcessingContext(
val discovery: ModelDiscoveryContext
) {
val params = mutableMapOf("type" to "none")
}
class RuleBasedDiscovery : AbstractModelDiscovery() {
val discoverers = mutableMapOf<String, ParametrizedModelDiscovery>()
override fun processModel(ctx: ModelDiscoveryContext) = when(ctx.getUnbaked()) {
is VariantList -> processContainerModel(ctx)
is BlockModel -> processBlockModel(ctx)
else -> Unit
}
fun processBlockModel(ctx: ModelDiscoveryContext) {
val ruleCtx = RuleProcessingContext(ctx)
val rulesToCheck = BetterFoliage.blockConfig.rules.toMutableList()
val ruleResults = mutableListOf<MatchResult>()
var previousSize = 0
// stop processing if nothing changes anymore
while (rulesToCheck.size != previousSize) {
previousSize = rulesToCheck.size
val iterator = rulesToCheck.listIterator()
while (iterator.hasNext()) iterator.next().let { rule ->
// process single rule
MatchRuleList.visitRoot(ruleCtx, rule).let { result ->
ruleResults.add(result)
// remove rule from active list if:
// - rule succeeded (all directives returned success)
// - rule is invariant (result will always be the same)
if (result.isSuccess || result.isInvariant) iterator.remove()
}
}
}
// log result of rule processing
if (ruleResults.any { it.isSuccess }) {
detailLogger.log(Level.INFO, "================================")
detailLogger.log(Level.INFO, "block state: ${ctx.blockState}")
detailLogger.log(Level.INFO, "block class: ${ctx.blockState.block::class.java.name}")
detailLogger.log(Level.INFO, "model : ${ctx.modelLocation}")
detailLogger.log(Level.INFO, "--------------------------------")
ruleResults.forEach { result ->
if (result !is MatchResult.RootList || result.results.shouldLog())
result.log { source, message -> detailLogger.log(Level.INFO, "[$source] $message") }
}
}
discoverers[ruleCtx.params["type"]]?.processModel(ctx, ruleCtx.params)
}
fun List<MatchResult>.shouldLog() = all { it.isSuccess } || fold(false) { seenInvariantSuccess, result ->
seenInvariantSuccess || (result.isSuccess && result.isInvariant)
}
}