Allow concurrent retrieval of models from the cache
This commit is contained in:
parent
e5cd9f57b5
commit
882f4832df
|
|
@ -236,67 +236,77 @@ public abstract class ModelBakeryMixin {
|
||||||
* @reason synchronize
|
* @reason synchronize
|
||||||
*/
|
*/
|
||||||
@Overwrite
|
@Overwrite
|
||||||
public synchronized UnbakedModel getModel(ResourceLocation modelLocation) {
|
public UnbakedModel getModel(ResourceLocation modelLocation) {
|
||||||
if(modelLocation.equals(MISSING_MODEL_LOCATION))
|
if(modelLocation.equals(MISSING_MODEL_LOCATION))
|
||||||
return missingModel;
|
return missingModel;
|
||||||
if (this.unbakedCache.containsKey(modelLocation)) {
|
UnbakedModel existing = this.unbakedCache.get(modelLocation);
|
||||||
return this.unbakedCache.get(modelLocation);
|
if (existing != null) {
|
||||||
} else if (this.loadingStack.contains(modelLocation)) {
|
return existing;
|
||||||
throw new IllegalStateException("Circular reference while loading " + modelLocation);
|
|
||||||
} else {
|
} else {
|
||||||
this.loadingStack.add(modelLocation);
|
synchronized(this) {
|
||||||
UnbakedModel iunbakedmodel = missingModel;
|
if (this.loadingStack.contains(modelLocation)) {
|
||||||
|
throw new IllegalStateException("Circular reference while loading " + modelLocation);
|
||||||
|
} else {
|
||||||
|
this.loadingStack.add(modelLocation);
|
||||||
|
UnbakedModel iunbakedmodel = missingModel;
|
||||||
|
|
||||||
while(!this.loadingStack.isEmpty()) {
|
while(!this.loadingStack.isEmpty()) {
|
||||||
ResourceLocation resourcelocation = this.loadingStack.iterator().next();
|
ResourceLocation resourcelocation = this.loadingStack.iterator().next();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!this.unbakedCache.containsKey(resourcelocation)) {
|
if (!this.unbakedCache.containsKey(resourcelocation)) {
|
||||||
if(debugDynamicModelLoading)
|
if(debugDynamicModelLoading)
|
||||||
LOGGER.info("Loading {}", resourcelocation);
|
LOGGER.info("Loading {}", resourcelocation);
|
||||||
this.loadModel(resourcelocation);
|
this.loadModel(resourcelocation);
|
||||||
|
// TODO: in theory the cache can get evicted right here and we lose the model
|
||||||
|
// very unlikely to occur though
|
||||||
|
}
|
||||||
|
} catch (ModelBakery.BlockStateDefinitionException var9) {
|
||||||
|
LOGGER.warn(var9.getMessage());
|
||||||
|
this.unbakedCache.put(resourcelocation, iunbakedmodel);
|
||||||
|
} catch (Exception var10) {
|
||||||
|
LOGGER.warn("Unable to load model: '{}' referenced from: {}: {}", resourcelocation, modelLocation, var10);
|
||||||
|
this.unbakedCache.put(resourcelocation, iunbakedmodel);
|
||||||
|
} finally {
|
||||||
|
this.loadingStack.remove(resourcelocation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (ModelBakery.BlockStateDefinitionException var9) {
|
|
||||||
LOGGER.warn(var9.getMessage());
|
return this.unbakedCache.getOrDefault(modelLocation, iunbakedmodel);
|
||||||
this.unbakedCache.put(resourcelocation, iunbakedmodel);
|
|
||||||
} catch (Exception var10) {
|
|
||||||
LOGGER.warn("Unable to load model: '{}' referenced from: {}: {}", resourcelocation, modelLocation, var10);
|
|
||||||
this.unbakedCache.put(resourcelocation, iunbakedmodel);
|
|
||||||
} finally {
|
|
||||||
this.loadingStack.remove(resourcelocation);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.unbakedCache.getOrDefault(modelLocation, iunbakedmodel);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Overwrite
|
@Overwrite
|
||||||
public synchronized BakedModel getBakedModel(ResourceLocation arg, ModelState arg2, Function<Material, TextureAtlasSprite> textureGetter) {
|
public BakedModel getBakedModel(ResourceLocation arg, ModelState arg2, Function<Material, TextureAtlasSprite> textureGetter) {
|
||||||
Triple<ResourceLocation, Transformation, Boolean> triple = Triple.of(arg, arg2.getRotation(), arg2.isUvLocked());
|
Triple<ResourceLocation, Transformation, Boolean> triple = Triple.of(arg, arg2.getRotation(), arg2.isUvLocked());
|
||||||
if (this.bakedCache.containsKey(triple)) {
|
BakedModel existing = this.bakedCache.get(triple);
|
||||||
return this.bakedCache.get(triple);
|
if (existing != null) {
|
||||||
|
return existing;
|
||||||
} else if (this.atlasSet == null) {
|
} else if (this.atlasSet == null) {
|
||||||
throw new IllegalStateException("bake called too early");
|
throw new IllegalStateException("bake called too early");
|
||||||
} else {
|
} else {
|
||||||
if(debugDynamicModelLoading)
|
synchronized (this) {
|
||||||
LOGGER.info("Baking {}", arg);
|
if(debugDynamicModelLoading)
|
||||||
UnbakedModel iunbakedmodel = this.getModel(arg);
|
LOGGER.info("Baking {}", arg);
|
||||||
iunbakedmodel.getMaterials(this::getModel, new HashSet<>());
|
UnbakedModel iunbakedmodel = this.getModel(arg);
|
||||||
BakedModel ibakedmodel = null;
|
iunbakedmodel.getMaterials(this::getModel, new HashSet<>());
|
||||||
if (iunbakedmodel instanceof BlockModel) {
|
BakedModel ibakedmodel = null;
|
||||||
BlockModel blockmodel = (BlockModel)iunbakedmodel;
|
if (iunbakedmodel instanceof BlockModel) {
|
||||||
if (blockmodel.getRootModel() == GENERATION_MARKER) {
|
BlockModel blockmodel = (BlockModel)iunbakedmodel;
|
||||||
ibakedmodel = ITEM_MODEL_GENERATOR.generateBlockModel(textureGetter, blockmodel).bake((ModelBakery)(Object)this, blockmodel, this.atlasSet::getSprite, arg2, arg, false);
|
if (blockmodel.getRootModel() == GENERATION_MARKER) {
|
||||||
|
ibakedmodel = ITEM_MODEL_GENERATOR.generateBlockModel(textureGetter, blockmodel).bake((ModelBakery)(Object)this, blockmodel, this.atlasSet::getSprite, arg2, arg, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if(ibakedmodel == null) {
|
||||||
|
ibakedmodel = iunbakedmodel.bake((ModelBakery) (Object) this, textureGetter, arg2, arg);
|
||||||
|
}
|
||||||
|
DynamicModelBakeEvent event = new DynamicModelBakeEvent(arg, iunbakedmodel, ibakedmodel, (ModelLoader)(Object)this);
|
||||||
|
ModLoader.get().postEvent(event);
|
||||||
|
this.bakedCache.put(triple, event.getModel());
|
||||||
|
return event.getModel();
|
||||||
}
|
}
|
||||||
if(ibakedmodel == null) {
|
|
||||||
ibakedmodel = iunbakedmodel.bake((ModelBakery) (Object) this, textureGetter, arg2, arg);
|
|
||||||
}
|
|
||||||
DynamicModelBakeEvent event = new DynamicModelBakeEvent(arg, iunbakedmodel, ibakedmodel, (ModelLoader)(Object)this);
|
|
||||||
ModLoader.get().postEvent(event);
|
|
||||||
this.bakedCache.put(triple, event.getModel());
|
|
||||||
return event.getModel();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user