From 18156579a68f274c92794b01393397770251ce2b Mon Sep 17 00:00:00 2001 From: ishland Date: Thu, 13 Jul 2023 17:21:14 +0800 Subject: [PATCH] perf: improve chunk transition speed --- .../access/IThreadedAnvilChunkStorage.java | 4 ++ .../worldgen/mixin/MixinChunkHolder.java | 43 +++++++++++++++++++ .../c2me-threading-worldgen.mixins.json | 1 + 3 files changed, 48 insertions(+) create mode 100644 c2me-threading-worldgen/src/main/java/com/ishland/c2me/threading/worldgen/mixin/MixinChunkHolder.java diff --git a/c2me-base/src/main/java/com/ishland/c2me/base/mixin/access/IThreadedAnvilChunkStorage.java b/c2me-base/src/main/java/com/ishland/c2me/base/mixin/access/IThreadedAnvilChunkStorage.java index 74315c06..edbe2aa3 100644 --- a/c2me-base/src/main/java/com/ishland/c2me/base/mixin/access/IThreadedAnvilChunkStorage.java +++ b/c2me-base/src/main/java/com/ishland/c2me/base/mixin/access/IThreadedAnvilChunkStorage.java @@ -5,6 +5,7 @@ import net.minecraft.server.world.ServerWorld; import net.minecraft.server.world.ThreadedAnvilChunkStorage; import net.minecraft.util.math.ChunkPos; +import net.minecraft.util.thread.ThreadExecutor; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.gen.Accessor; import org.spongepowered.asm.mixin.gen.Invoker; @@ -30,4 +31,7 @@ public interface IThreadedAnvilChunkStorage { @Invoker void invokeReleaseLightTicket(ChunkPos pos); + @Accessor + ThreadExecutor getMainThreadExecutor(); + } diff --git a/c2me-threading-worldgen/src/main/java/com/ishland/c2me/threading/worldgen/mixin/MixinChunkHolder.java b/c2me-threading-worldgen/src/main/java/com/ishland/c2me/threading/worldgen/mixin/MixinChunkHolder.java new file mode 100644 index 00000000..aac6b667 --- /dev/null +++ b/c2me-threading-worldgen/src/main/java/com/ishland/c2me/threading/worldgen/mixin/MixinChunkHolder.java @@ -0,0 +1,43 @@ +package com.ishland.c2me.threading.worldgen.mixin; + +import com.ishland.c2me.base.mixin.access.IThreadedAnvilChunkStorage; +import com.ishland.c2me.threading.worldgen.common.Config; +import com.mojang.datafixers.util.Either; +import net.minecraft.server.world.ChunkHolder; +import net.minecraft.server.world.ThreadedAnvilChunkStorage; +import net.minecraft.util.thread.ThreadExecutor; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.ChunkStatus; +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.Redirect; + +import java.util.concurrent.CompletableFuture; + +@Mixin(value = ChunkHolder.class, priority = 1110) +public abstract class MixinChunkHolder { + + @Shadow public abstract CompletableFuture> getChunkAt(ChunkStatus targetStatus, ThreadedAnvilChunkStorage chunkStorage); + + @Redirect(method = "getChunkAt", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/world/ThreadedAnvilChunkStorage;getChunk(Lnet/minecraft/server/world/ChunkHolder;Lnet/minecraft/world/chunk/ChunkStatus;)Ljava/util/concurrent/CompletableFuture;")) + private CompletableFuture> redirectGetChunk(ThreadedAnvilChunkStorage instance, ChunkHolder holder, ChunkStatus requiredStatus) { + if (requiredStatus == ChunkStatus.EMPTY) { + return instance.getChunk(holder, requiredStatus); + } else { + return this.getChunkAt(requiredStatus.getPrevious(), instance) + .thenComposeAsync( + unused -> instance.getChunk(holder, requiredStatus), + Config.asyncScheduling ? Runnable::run : r -> { + final ThreadExecutor executor = ((IThreadedAnvilChunkStorage) instance).getMainThreadExecutor(); + if (executor.isOnThread()) { + r.run(); + } else { + executor.execute(r); + } + } + ); + } + } + +} diff --git a/c2me-threading-worldgen/src/main/resources/c2me-threading-worldgen.mixins.json b/c2me-threading-worldgen/src/main/resources/c2me-threading-worldgen.mixins.json index 51e88e73..c4605ca9 100644 --- a/c2me-threading-worldgen/src/main/resources/c2me-threading-worldgen.mixins.json +++ b/c2me-threading-worldgen/src/main/resources/c2me-threading-worldgen.mixins.json @@ -5,6 +5,7 @@ "plugin": "com.ishland.c2me.base.common.ModuleMixinPlugin", "mixins": [ "MixinChunkGenerator", + "MixinChunkHolder", "MixinChunkRegion", "MixinChunkStatus", "MixinNoiseChunkGenerator",