diff --git a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java index e5a2b7365..a473beac3 100644 --- a/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java +++ b/projects/common/src/client/java/dan200/computercraft/client/model/turtle/TurtleModelParts.java @@ -28,8 +28,10 @@ /** * Combines several individual models together to form a turtle. + * + * @param The type of the resulting "baked model". */ -public final class TurtleModelParts { +public final class TurtleModelParts { private static final Transformation identity, flip; static { @@ -42,7 +44,7 @@ public final class TurtleModelParts { flip = new Transformation(stack.last().pose()); } - public record Combination( + private record Combination( boolean colour, @Nullable ITurtleUpgrade leftUpgrade, @Nullable ITurtleUpgrade rightUpgrade, @@ -55,6 +57,7 @@ public record Combination( private final BakedModel familyModel; private final BakedModel colourModel; private final Function transformer; + private final Function buildModel; /** * A cache of {@link TransformedModel} to the transformed {@link BakedModel}. This helps us pool the transformed @@ -62,13 +65,23 @@ public record Combination( */ private final Map transformCache = new HashMap<>(); - public TurtleModelParts(BakedModel familyModel, BakedModel colourModel, ModelTransformer transformer) { + /** + * A cache of {@link Combination}s to the combined model. + */ + private final Map modelCache = new HashMap<>(); + + public TurtleModelParts(BakedModel familyModel, BakedModel colourModel, ModelTransformer transformer, Function, T> combineModel) { this.familyModel = familyModel; this.colourModel = colourModel; this.transformer = x -> transformer.transform(x.getModel(), x.getMatrix()); + buildModel = x -> combineModel.apply(buildModel(x)); } - public Combination getCombination(ItemStack stack) { + public T getModel(ItemStack stack) { + return modelCache.computeIfAbsent(getCombination(stack), buildModel); + } + + private Combination getCombination(ItemStack stack) { var christmas = Holiday.getCurrent() == Holiday.CHRISTMAS; if (!(stack.getItem() instanceof TurtleItem turtle)) { @@ -85,7 +98,7 @@ public Combination getCombination(ItemStack stack) { return new Combination(colour != -1, leftUpgrade, rightUpgrade, overlay, christmas, flip); } - public List buildModel(Combination combo) { + private List buildModel(Combination combo) { var mc = Minecraft.getInstance(); var modelManager = mc.getItemRenderer().getItemModelShaper().getModelManager(); @@ -109,7 +122,7 @@ public List buildModel(Combination combo) { return parts; } - public BakedModel transform(BakedModel model, Transformation transformation) { + private BakedModel transform(BakedModel model, Transformation transformation) { if (transformation.equals(Transformation.identity())) return model; return transformCache.computeIfAbsent(new TransformedModel(model, transformation), transformer); } diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/CompositeBakedModel.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/CompositeBakedModel.java index aa22ac224..177094cdc 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/client/model/CompositeBakedModel.java +++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/CompositeBakedModel.java @@ -25,6 +25,10 @@ public CompositeBakedModel(List models) { this.models = models; } + public static BakedModel of(List models) { + return models.size() == 1 ? models.get(0) : new CompositeBakedModel(models); + } + @Override public List getQuads(@Nullable BlockState blockState, @Nullable Direction face, RandomSource rand) { @SuppressWarnings({ "unchecked", "rawtypes" }) diff --git a/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java b/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java index 28ba06bf2..704350b1a 100644 --- a/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java +++ b/projects/fabric/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java @@ -14,8 +14,6 @@ import net.minecraft.world.item.ItemStack; import javax.annotation.Nullable; -import java.util.HashMap; -import java.util.Map; /** * The custom model for turtle items, which renders tools and overlays as part of the model. @@ -23,28 +21,22 @@ * @see TurtleModelParts */ public class TurtleModel extends ForwardingBakedModel { - private final TurtleModelParts parts; + private final TurtleModelParts parts; - private final Map cachedModels = new HashMap<>(); private final ItemOverrides overrides = new ItemOverrides() { @Override public BakedModel resolve(BakedModel model, ItemStack stack, @Nullable ClientLevel level, @Nullable LivingEntity entity, int seed) { - return cachedModels.computeIfAbsent(parts.getCombination(stack), TurtleModel.this::buildModel); + return parts.getModel(stack); } }; public TurtleModel(BakedModel familyModel, BakedModel colourModel) { wrapped = familyModel; - parts = new TurtleModelParts(familyModel, colourModel, TransformedBakedModel::new); + parts = new TurtleModelParts<>(familyModel, colourModel, TransformedBakedModel::new, CompositeBakedModel::of); } @Override public ItemOverrides getOverrides() { return overrides; } - - private BakedModel buildModel(TurtleModelParts.Combination combo) { - var models = parts.buildModel(combo); - return models.size() == 1 ? models.get(0) : new CompositeBakedModel(models); - } } diff --git a/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java b/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java index f4ebbe78d..257e48699 100644 --- a/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java +++ b/projects/forge/src/client/java/dan200/computercraft/client/model/turtle/TurtleModel.java @@ -11,9 +11,8 @@ import net.minecraft.world.item.ItemStack; import net.minecraftforge.client.model.BakedModelWrapper; -import java.util.HashMap; import java.util.List; -import java.util.Map; +import java.util.function.Function; /** * The custom model for turtle items, which renders tools and overlays as part of the model. @@ -21,12 +20,11 @@ * @see TurtleModelParts */ public class TurtleModel extends BakedModelWrapper { - private final TurtleModelParts parts; - private final Map> cachedModels = new HashMap<>(); + private final TurtleModelParts> parts; public TurtleModel(BakedModel familyModel, BakedModel colourModel) { super(familyModel); - parts = new TurtleModelParts(familyModel, colourModel, TransformedBakedModel::new); + parts = new TurtleModelParts<>(familyModel, colourModel, TransformedBakedModel::new, Function.identity()); } @Override @@ -37,6 +35,6 @@ public BakedModel applyTransform(ItemDisplayContext transform, PoseStack poseSta @Override public List getRenderPasses(ItemStack stack, boolean fabulous) { - return cachedModels.computeIfAbsent(parts.getCombination(stack), parts::buildModel); + return parts.getModel(stack); } }