diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java index 898253bb0..b81502d1f 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/DrawManager.java @@ -8,6 +8,8 @@ import java.util.Queue; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentLinkedQueue; +import org.jetbrains.annotations.Nullable; + import com.mojang.datafixers.util.Pair; import dev.engine_room.flywheel.api.RenderContext; @@ -106,7 +108,13 @@ public abstract class DrawManager> { return false; } - protected static > Map, Int2ObjectMap>>>> doCrumblingSort(Class clazz, List crumblingBlocks) { + @FunctionalInterface + protected interface State2Instancer> { + // I tried using a plain Function, I> here, but it exploded with type errors. + @Nullable I apply(InstanceHandleImpl.State state); + } + + protected static > Map, Int2ObjectMap>>>> doCrumblingSort(List crumblingBlocks, State2Instancer cast) { Map, Int2ObjectMap>>>> byType = new HashMap<>(); for (Engine.CrumblingBlock block : crumblingBlocks) { int progress = block.progress(); @@ -123,16 +131,12 @@ public abstract class DrawManager> { continue; } - InstanceHandleImpl.State abstractInstancer = impl.state; - // AbstractInstancer directly implement HandleState, so this check is valid. - if (!clazz.isInstance(abstractInstancer)) { - // This rejects instances that were created by a different engine, - // and also instances that are hidden or deleted. + var instancer = cast.apply(impl.state); + + if (instancer == null) { continue; } - var instancer = clazz.cast(abstractInstancer); - byType.computeIfAbsent(new GroupKey<>(instancer.type, instancer.environment), $ -> new Int2ObjectArrayMap<>()) .computeIfAbsent(progress, $ -> new ArrayList<>()) .add(Pair.of(instancer, impl)); diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java index 4b14df6b2..8a6dd5e4b 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectDrawManager.java @@ -189,7 +189,7 @@ public class IndirectDrawManager extends DrawManager> { } public void renderCrumbling(List crumblingBlocks) { - var byType = doCrumblingSort(IndirectInstancer.class, crumblingBlocks); + var byType = doCrumblingSort(crumblingBlocks, IndirectInstancer::fromState); if (byType.isEmpty()) { return; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectInstancer.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectInstancer.java index 5e182a663..1291e9a77 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectInstancer.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/indirect/IndirectInstancer.java @@ -74,6 +74,14 @@ public class IndirectInstancer extends AbstractInstancer return new InstanceHandleImpl[ObjectStorage.PAGE_SIZE]; } + @Nullable + public static IndirectInstancer fromState(InstanceHandleImpl.State handle) { + if (handle instanceof InstancePage instancer) { + return instancer.parent; + } + return null; + } + private static final class InstancePage implements InstanceHandleImpl.State { private final IndirectInstancer parent; private final int pageNo; diff --git a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java index 3d2cf0c76..88526f360 100644 --- a/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java +++ b/common/src/backend/java/dev/engine_room/flywheel/backend/engine/instancing/InstancedDrawManager.java @@ -147,7 +147,15 @@ public class InstancedDrawManager extends DrawManager> { @Override public void renderCrumbling(List crumblingBlocks) { // Sort draw calls into buckets, so we don't have to do as many shader binds. - var byType = doCrumblingSort(InstancedInstancer.class, crumblingBlocks); + var byType = doCrumblingSort(crumblingBlocks, handle -> { + // AbstractInstancer directly implement HandleState, so this check is valid. + if (handle instanceof InstancedInstancer instancer) { + return instancer; + } + // This rejects instances that were created by a different engine, + // and also instances that are hidden or deleted. + return null; + }); if (byType.isEmpty()) { return;