diff --git a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java index ea1928e3..49010ac4 100644 --- a/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java +++ b/src/main/java/org/embeddedt/modernfix/mixin/perf/dynamic_resources/ModelBakeryMixin.java @@ -11,6 +11,7 @@ import com.google.common.collect.Sets; import com.google.gson.*; import com.mojang.datafixers.util.Pair; import com.mojang.math.Transformation; +import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import net.minecraft.Util; import net.minecraft.client.color.block.BlockColors; import net.minecraft.client.renderer.block.model.BlockModel; @@ -56,6 +57,7 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.function.BiConsumer; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; @@ -194,12 +196,24 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { return ImmutableList.of(); } + private static final int ERROR_THRESHOLD = 200; + + private void logOrSuppressError(Object2IntOpenHashMap suppressionMap, String type, ResourceLocation location, Throwable e) { + int numErrors; + synchronized (suppressionMap) { + numErrors = suppressionMap.computeInt(location.getNamespace(), (k, oldVal) -> (oldVal == null ? 1 : oldVal + 1)); + } + if(numErrors <= ERROR_THRESHOLD) + ModernFix.LOGGER.error("Error reading {} {}: {}", type, location, e); + } + /** * Load all blockstate JSONs and model files, collect textures. */ private void gatherModelMaterials(Set materialSet) { Stopwatch stopwatch = Stopwatch.createStarted(); List>> blockStateData = new ArrayList<>(); + final Object2IntOpenHashMap blockstateErrors = new Object2IntOpenHashMap<>(); for(ResourceLocation blockstate : blockStateFiles) { blockStateData.add(CompletableFuture.supplyAsync(() -> { ResourceLocation fileLocation = new ResourceLocation(blockstate.getNamespace(), "blockstates/" + blockstate.getPath() + ".json"); @@ -207,7 +221,7 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { JsonParser parser = new JsonParser(); return Pair.of(blockstate, parser.parse(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))); } catch(IOException | JsonParseException e) { - ModernFix.LOGGER.error("Error reading blockstate {}: {}", blockstate, e); + logOrSuppressError(blockstateErrors, "blockstate", blockstate, e); } return Pair.of(blockstate, null); }, ModernFix.resourceReloadExecutor())); @@ -256,11 +270,17 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { } } catch(RuntimeException e) { - ModernFix.LOGGER.error("Error with blockstate {}: {}", pair.getFirst(), e); + logOrSuppressError(blockstateErrors, "blockstate", pair.getFirst(), e); } } } + blockstateErrors.object2IntEntrySet().forEach(entry -> { + if(entry.getIntValue() > ERROR_THRESHOLD) { + ModernFix.LOGGER.error("Suppressed additional {} blockstate errors for domain {}", entry.getIntValue(), entry.getKey()); + } + }); + blockstateErrors.clear(); blockStateData = null; Map basicModels = new HashMap<>(); basicModels.put(MISSING_MODEL_LOCATION, (BlockModel)missingModel); @@ -278,7 +298,7 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { JsonParser parser = new JsonParser(); return Pair.of(model, parser.parse(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))); } catch(IOException | JsonParseException e) { - ModernFix.LOGGER.error("Error reading model {}: {}", fileLocation, e); + logOrSuppressError(blockstateErrors, "model", fileLocation, e); return Pair.of(fileLocation, null); } }, ModernFix.resourceReloadExecutor())); @@ -298,12 +318,17 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery { continue; } } catch(Throwable e) { - ModernFix.LOGGER.warn("Unable to parse {}: {}", pair.getFirst(), e); + logOrSuppressError(blockstateErrors, "model", pair.getFirst(), e); } basicModels.put(pair.getFirst(), (BlockModel)missingModel); } UVController.useDummyUv.set(Boolean.FALSE); } + blockstateErrors.object2IntEntrySet().forEach(entry -> { + if(entry.getIntValue() > ERROR_THRESHOLD) { + ModernFix.LOGGER.error("Suppressed additional {} model errors for domain {}", entry.getIntValue(), entry.getKey()); + } + }); modelFiles = null; Function modelGetter = loc -> { UnbakedModel m = basicModels.get(loc);