diff --git a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java index ab1ded3bc..17c91358c 100644 --- a/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java +++ b/common/src/lib/java/dev/engine_room/flywheel/lib/model/part/InstanceTree.java @@ -4,6 +4,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.NoSuchElementException; +import java.util.function.BiConsumer; import java.util.function.BiFunction; import java.util.function.Consumer; import java.util.function.ObjIntConsumer; @@ -170,6 +171,16 @@ public final class InstanceTree { } public void updateInstances(PoseStack poseStack) { + // Need to use an anonymous class so it can reference this. + updateInstancesInner(poseStack, new Walker() { + @Override + public void accept(InstanceTree child) { + child.updateInstancesInner(poseStack, this); + } + }); + } + + private void updateInstancesInner(PoseStack poseStack, Walker walker) { if (visible) { poseStack.pushPose(); translateAndRotate(poseStack); @@ -179,9 +190,9 @@ public final class InstanceTree { .setChanged(); } - for (InstanceTree child : children.values()) { - child.updateInstances(poseStack); - } + // Use the bare HashMap.forEach because .values() always allocates a new collection. + // We also don't want to store an array of children because that would statically use a lot more memory. + children.forEach(walker); poseStack.popPose(); } @@ -292,4 +303,14 @@ public final class InstanceTree { public interface ObjIntIntConsumer { void accept(T t, int i, int j); } + + // Helper interface for writing walking classes. + private interface Walker extends BiConsumer { + void accept(InstanceTree child); + + @Override + default void accept(String name, InstanceTree child) { + accept(child); + } + } }