From e34a99b38c0c61b0d78fc7c9d1499a06201a0daa Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Sat, 14 Mar 2026 14:59:45 -0400 Subject: [PATCH] Simplify chunk unload logic & fix events not being fired when INACCESSIBLE chunks are unloaded --- .../release_protochunks/ChunkMapMixin.java | 32 +++++++------------ .../ThreadedLevelLightEngineAccessor.java | 12 ------- 2 files changed, 12 insertions(+), 32 deletions(-) delete mode 100644 src/main/java/org/embeddedt/modernfix/common/mixin/perf/release_protochunks/ThreadedLevelLightEngineAccessor.java diff --git a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/release_protochunks/ChunkMapMixin.java b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/release_protochunks/ChunkMapMixin.java index 959da87c..abbe5e73 100644 --- a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/release_protochunks/ChunkMapMixin.java +++ b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/release_protochunks/ChunkMapMixin.java @@ -10,8 +10,6 @@ import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkLevel; import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.FullChunkStatus; -import net.minecraft.server.level.ThreadedLevelLightEngine; -import net.minecraft.server.level.progress.ChunkProgressListener; import net.minecraft.util.thread.BlockableEventLoop; import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.chunk.ChunkAccess; @@ -27,7 +25,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.Executor; import java.util.function.BooleanSupplier; @@ -37,20 +34,16 @@ public abstract class ChunkMapMixin implements ISuspendedHolderTrackingChunkMap @Final public Long2ObjectLinkedOpenHashMap updatingChunkMap; - @Shadow - protected abstract boolean save(ChunkAccess chunk); - - @Shadow - @Final - private ChunkProgressListener progressListener; - @Shadow - @Final - private ThreadedLevelLightEngine lightEngine; - @Shadow @Final private BlockableEventLoop mainThreadExecutor; + @Shadow + protected abstract void lambda$scheduleUnload$14(ChunkHolder holder, CompletableFuture chunkToSaveFuture, long chunkPos, ChunkAccess chunk); + + @Shadow + @Final + public Long2ObjectLinkedOpenHashMap pendingUnloads; private final LongOpenHashSet mfix$protoChunksToDrop = new LongOpenHashSet(); /** @@ -85,16 +78,15 @@ public abstract class ChunkMapMixin implements ISuspendedHolderTrackingChunkMap // All generation work done, so we can suspend and remove from set dropIterator.remove(); - ChunkAccess chunk = holder.getChunkToSave().getNow(null); - if (chunk != null) { - this.save(chunk); // flush protochunk to disk - } + var chunkToSaveFuture = holder.getChunkToSave(); + + // Execute the logic inside scheduleUnload() inline, without delegating to a queue + // When this returns it is safe to release any data the ChunkHolder holds + this.pendingUnloads.put(pos, holder); + this.lambda$scheduleUnload$14(holder, chunkToSaveFuture, pos, chunkToSaveFuture.getNow(null)); ((IClearableChunkHolder)holder).mfix$resetProtoChunkFutures(); - this.progressListener.onStatusChange(holder.getPos(), null); - ((ThreadedLevelLightEngineAccessor)this.lightEngine).mfix$invokeUpdateChunkStatus(holder.getPos()); - this.lightEngine.tryScheduleUpdate(); suspended++; } } diff --git a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/release_protochunks/ThreadedLevelLightEngineAccessor.java b/src/main/java/org/embeddedt/modernfix/common/mixin/perf/release_protochunks/ThreadedLevelLightEngineAccessor.java deleted file mode 100644 index cbebcb6a..00000000 --- a/src/main/java/org/embeddedt/modernfix/common/mixin/perf/release_protochunks/ThreadedLevelLightEngineAccessor.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.embeddedt.modernfix.common.mixin.perf.release_protochunks; - -import net.minecraft.server.level.ThreadedLevelLightEngine; -import net.minecraft.world.level.ChunkPos; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.gen.Invoker; - -@Mixin(ThreadedLevelLightEngine.class) -public interface ThreadedLevelLightEngineAccessor { - @Invoker("updateChunkStatus") - void mfix$invokeUpdateChunkStatus(ChunkPos pos); -}