Do not deserialize model JSONs in parallel
Some Forge model loaders attempt to read more models while deserializing, which causes issues
This commit is contained in:
parent
08fd01c09f
commit
80a4585efd
|
|
@ -59,55 +59,12 @@ public abstract class ModelBakeryMixin {
|
||||||
|
|
||||||
@Shadow @Final private Map<ResourceLocation, IUnbakedModel> topLevelModels;
|
@Shadow @Final private Map<ResourceLocation, IUnbakedModel> topLevelModels;
|
||||||
@Shadow @Final protected IResourceManager resourceManager;
|
@Shadow @Final protected IResourceManager resourceManager;
|
||||||
private Map<ResourceLocation, BlockModel> deserializedModelCache = null;
|
|
||||||
private Map<ResourceLocation, List<Pair<String, BlockModelDefinition>>> deserializedBlockstateCache = null;
|
private Map<ResourceLocation, List<Pair<String, BlockModelDefinition>>> deserializedBlockstateCache = null;
|
||||||
private boolean useModelCache = false;
|
|
||||||
|
|
||||||
@Inject(method = "loadBlockModel", at = @At("HEAD"), cancellable = true)
|
|
||||||
private void useCachedModel(ResourceLocation location, CallbackInfoReturnable<BlockModel> cir) {
|
|
||||||
if(useModelCache && deserializedModelCache != null) {
|
|
||||||
BlockModel model = deserializedModelCache.get(location);
|
|
||||||
if(model != null)
|
|
||||||
cir.setReturnValue(model);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private BlockModel loadModelSafely(ResourceLocation location) {
|
|
||||||
try {
|
|
||||||
return this.loadBlockModel(location);
|
|
||||||
} catch(Throwable e) {
|
|
||||||
ModernFix.LOGGER.warn("Model " + location + " will not be preloaded");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "processLoading", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/IProfiler;popPush(Ljava/lang/String;)V", ordinal = 0))
|
@Inject(method = "processLoading", at = @At(value = "INVOKE", target = "Lnet/minecraft/profiler/IProfiler;popPush(Ljava/lang/String;)V", ordinal = 0))
|
||||||
private void preloadJsonModels(IProfiler profilerIn, int maxMipmapLevel, CallbackInfo ci) {
|
private void preloadJsonModels(IProfiler profilerIn, int maxMipmapLevel, CallbackInfo ci) {
|
||||||
profilerIn.popPush("loadjsons");
|
profilerIn.popPush("loadblockstates");
|
||||||
AsyncStopwatch.measureAndLogSerialRunningTime("Parallel JSON loading", () -> {
|
|
||||||
useModelCache = false;
|
|
||||||
this.deserializedModelCache = new ConcurrentHashMap<>();
|
|
||||||
Collection<ResourceLocation> modelLocations = Minecraft.getInstance().getResourceManager().listResources("models", p -> {
|
|
||||||
if(!p.endsWith(".json"))
|
|
||||||
return false;
|
|
||||||
for(int i = 0; i < p.length(); i++) {
|
|
||||||
if(!ResourceLocation.validPathChar(p.charAt(i)))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
ArrayList<CompletableFuture<Void>> futures = new ArrayList<>();
|
|
||||||
for(ResourceLocation location : modelLocations) {
|
|
||||||
futures.add(CompletableFuture.runAsync(() -> {
|
|
||||||
ResourceLocation modelPath = new ResourceLocation(location.getNamespace(), location.getPath().substring(7, location.getPath().length() - 5));
|
|
||||||
BlockModel model = this.loadModelSafely(modelPath);
|
|
||||||
if(model != null)
|
|
||||||
this.deserializedModelCache.put(modelPath, model);
|
|
||||||
}, Util.backgroundExecutor()));
|
|
||||||
}
|
|
||||||
CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
|
|
||||||
useModelCache = true;
|
|
||||||
});
|
|
||||||
AsyncStopwatch.measureAndLogSerialRunningTime("Parallel blockstate loading", () -> {
|
AsyncStopwatch.measureAndLogSerialRunningTime("Parallel blockstate loading", () -> {
|
||||||
ThreadLocal<BlockModelDefinition.ContainerHolder> containerHolder = ThreadLocal.withInitial(BlockModelDefinition.ContainerHolder::new);
|
ThreadLocal<BlockModelDefinition.ContainerHolder> containerHolder = ThreadLocal.withInitial(BlockModelDefinition.ContainerHolder::new);
|
||||||
this.deserializedBlockstateCache = new ConcurrentHashMap<>();
|
this.deserializedBlockstateCache = new ConcurrentHashMap<>();
|
||||||
|
|
@ -145,9 +102,7 @@ public abstract class ModelBakeryMixin {
|
||||||
|
|
||||||
@Inject(method = "processLoading", at = @At("RETURN"), remap = false)
|
@Inject(method = "processLoading", at = @At("RETURN"), remap = false)
|
||||||
private void clearModelCache(IProfiler profilerIn, int maxMipmapLevel, CallbackInfo ci) {
|
private void clearModelCache(IProfiler profilerIn, int maxMipmapLevel, CallbackInfo ci) {
|
||||||
deserializedModelCache.clear();
|
|
||||||
deserializedBlockstateCache.clear();
|
deserializedBlockstateCache.clear();
|
||||||
useModelCache = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<?> replacementList = null;
|
private List<?> replacementList = null;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user