diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java index 994286d14..9c9d94e1e 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java @@ -8,6 +8,7 @@ import com.jozufozu.flywheel.core.Contexts; import com.jozufozu.flywheel.core.shader.WorldProgram; import com.jozufozu.flywheel.event.BeginFrameEvent; import com.jozufozu.flywheel.event.RenderLayerEvent; +import com.jozufozu.flywheel.util.ChunkIter; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; @@ -58,8 +59,9 @@ public class InstanceWorld { * Instantiate all the necessary instances to render the given world. */ public void loadAll(ClientLevel world) { - // FIXME: no more global blockEntity list - // world.blockEntityList.forEach(tileEntityInstanceManager::add); + ChunkIter.forEachChunk(world, chunk -> { + chunk.getBlockEntities().values().forEach(tileEntityInstanceManager::add); + }); world.entitiesForRendering() .forEach(entityInstanceManager::add); } diff --git a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java index a4b454362..a61b81a63 100644 --- a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java +++ b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java @@ -5,6 +5,7 @@ import java.util.ArrayList; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher; import com.jozufozu.flywheel.light.LightUpdater; +import com.jozufozu.flywheel.util.ChunkIter; import net.minecraft.client.Minecraft; import net.minecraft.client.multiplayer.ClientLevel; @@ -47,6 +48,12 @@ public class ForgeEvents { } } + @SubscribeEvent + public static void unloadWorld(WorldEvent.Unload event) { + LevelAccessor world = event.getWorld(); + ChunkIter._unload(world); + } + @SubscribeEvent public static void tickLight(TickEvent.ClientTickEvent e) { if (e.phase == TickEvent.Phase.END && Backend.isGameActive()) diff --git a/src/main/java/com/jozufozu/flywheel/mixin/LeakChunkStorageArrayMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/LeakChunkStorageArrayMixin.java new file mode 100644 index 000000000..1a9bce762 --- /dev/null +++ b/src/main/java/com/jozufozu/flywheel/mixin/LeakChunkStorageArrayMixin.java @@ -0,0 +1,39 @@ +package com.jozufozu.flywheel.mixin; + +import java.util.concurrent.atomic.AtomicReferenceArray; + +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import com.jozufozu.flywheel.util.ChunkIter; + +import net.minecraft.client.multiplayer.ClientChunkCache; +import net.minecraft.world.level.chunk.LevelChunk; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +/** + * In order to iterate over all loaded chunks, we do something absolutely foul. + * + *
+ * By stealing the reference to the backing array of the chunk storage when it is constructed, we gain 0 maintenance + * access to the full array of loaded chunks. + *
+ */ +@OnlyIn(Dist.CLIENT) +@Mixin(targets = "net.minecraft.client.multiplayer.ClientChunkCache$Storage") +public class LeakChunkStorageArrayMixin { + + @Shadow + @Final + AtomicReferenceArray