Skip to content

Commit e4e8052

Browse files
committed
Threaded Feature Generation
1 parent c35c681 commit e4e8052

File tree

7 files changed

+64
-22
lines changed

7 files changed

+64
-22
lines changed

src/main/java/org/yatopiamc/c2me/C2MEMod.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public void onInitialize() {
1515
final Metrics metrics = new Metrics(10514);
1616
metrics.addCustomChart(new Metrics.SimplePie("environmentType", () -> FabricLoader.getInstance().getEnvironmentType().name().toLowerCase(Locale.ENGLISH)));
1717
metrics.addCustomChart(new Metrics.SimplePie("useThreadedWorldGeneration", () -> String.valueOf(C2MEConfig.threadedWorldGenConfig.enabled)));
18+
metrics.addCustomChart(new Metrics.SimplePie("useThreadedWorldFeatureGeneration", () -> String.valueOf(C2MEConfig.threadedWorldGenConfig.allowThreadedFeatures)));
1819
metrics.addCustomChart(new Metrics.DrilldownPie("detailedMinecraftVersion", () -> ImmutableMap.of(MinecraftVersion.field_25319.getReleaseTarget(), ImmutableMap.of(MinecraftVersion.field_25319.getName(), 1))));
1920
}
2021
}

src/main/java/org/yatopiamc/c2me/common/config/C2MEConfig.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ public class C2MEConfig {
2323
.sync()
2424
.build();
2525
config.load();
26-
@SuppressWarnings("unused")
27-
CommentedConfig globalConfig = config.get("global"); // Unused for now
26+
2827
asyncIoConfig = new AsyncIoConfig(config.get("asyncIO"));
2928
threadedWorldGenConfig = new ThreadedWorldGenConfig(config.get("threadedWorldGen"));
29+
config.save();
3030
config.close();
3131
}
3232

@@ -54,16 +54,26 @@ public AsyncIoConfig(CommentedConfig config) {
5454
public static class ThreadedWorldGenConfig {
5555
public final boolean enabled;
5656
public final int parallelism;
57+
public final boolean allowThreadedFeatures;
5758

5859
public ThreadedWorldGenConfig(CommentedConfig config) {
5960
Preconditions.checkNotNull(config, "threadedWorldGen config is not present");
61+
upgrade(config);
6062
enabled = config.getOrElse("enabled", false);
6163
int configuredParallelism = config.getIntOrElse("parallelism", -1);
6264
Preconditions.checkArgument(configuredParallelism >= -1 && configuredParallelism != 0 && configuredParallelism <= 0x7fff, "Invalid parallelism");
6365
if (configuredParallelism == -1)
6466
parallelism = Math.min(6, Runtime.getRuntime().availableProcessors());
6567
else
6668
parallelism = configuredParallelism;
69+
allowThreadedFeatures = config.getOrElse("allowThreadedFeatures", false);
70+
}
71+
72+
private void upgrade(CommentedConfig config) {
73+
if (!config.contains("allowThreadedFeatures")) {
74+
config.set("allowThreadedFeatures", false);
75+
config.setComment("allowThreadedFeatures", " Whether to allow feature generation (world decorations like trees, ores and etc.) run in parallel");
76+
}
6777
}
6878
}
6979

src/main/java/org/yatopiamc/c2me/common/threading/worldgen/ChunkStatusUtils.java

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import com.ibm.asyncutil.locks.AsyncNamedLock;
55
import net.minecraft.util.math.ChunkPos;
66
import net.minecraft.world.chunk.ChunkStatus;
7+
import org.yatopiamc.c2me.common.config.C2MEConfig;
78
import org.yatopiamc.c2me.common.threading.GlobalExecutors;
89
import org.yatopiamc.c2me.common.util.AsyncCombinedLock;
910
import org.yatopiamc.c2me.common.util.AsyncNamedLockDelegateAsyncLock;
@@ -14,25 +15,28 @@
1415
import java.util.concurrent.CompletableFuture;
1516
import java.util.function.Supplier;
1617

18+
import static org.yatopiamc.c2me.common.threading.worldgen.ChunkStatusThreadingType.AS_IS;
19+
import static org.yatopiamc.c2me.common.threading.worldgen.ChunkStatusThreadingType.PARALLELIZED;
20+
import static org.yatopiamc.c2me.common.threading.worldgen.ChunkStatusThreadingType.SINGLE_THREADED;
21+
1722
public class ChunkStatusUtils {
1823

1924
public static ChunkStatusThreadingType getThreadingType(final ChunkStatus status) {
20-
switch (status.getId()) {
21-
case "structure_starts":
22-
case "structure_references":
23-
case "biomes":
24-
case "noise":
25-
case "surface":
26-
case "carvers":
27-
case "liquid_carvers":
28-
case "heightmaps":
29-
return ChunkStatusThreadingType.PARALLELIZED;
30-
case "spawn":
31-
case "features":
32-
return ChunkStatusThreadingType.SINGLE_THREADED;
33-
default:
34-
return ChunkStatusThreadingType.AS_IS;
25+
if (status.equals(ChunkStatus.STRUCTURE_STARTS)
26+
|| status.equals(ChunkStatus.STRUCTURE_REFERENCES)
27+
|| status.equals(ChunkStatus.BIOMES)
28+
|| status.equals(ChunkStatus.NOISE)
29+
|| status.equals(ChunkStatus.SURFACE)
30+
|| status.equals(ChunkStatus.CARVERS)
31+
|| status.equals(ChunkStatus.LIQUID_CARVERS)
32+
|| status.equals(ChunkStatus.HEIGHTMAPS)) {
33+
return PARALLELIZED;
34+
} else if (status.equals(ChunkStatus.SPAWN)) {
35+
return SINGLE_THREADED;
36+
} else if (status.equals(ChunkStatus.FEATURES)) {
37+
return C2MEConfig.threadedWorldGenConfig.allowThreadedFeatures ? PARALLELIZED : SINGLE_THREADED;
3538
}
39+
return AS_IS;
3640
}
3741

3842
public static <T> CompletableFuture<T> runChunkGenWithLock(ChunkPos target, int radius, AsyncNamedLock<ChunkPos> chunkLock, Supplier<CompletableFuture<T>> action) {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.yatopiamc.c2me.mixin.threading.chunkio;
2+
3+
import net.minecraft.server.world.ServerChunkManager;
4+
import net.minecraft.util.thread.ThreadExecutor;
5+
import org.spongepowered.asm.mixin.Dynamic;
6+
import org.spongepowered.asm.mixin.Mixin;
7+
import org.spongepowered.asm.mixin.injection.At;
8+
import org.spongepowered.asm.mixin.injection.Inject;
9+
import org.spongepowered.asm.mixin.injection.Redirect;
10+
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
11+
12+
@Mixin(ServerChunkManager.MainThreadExecutor.class)
13+
public abstract class MixinServerChunkManagerMainThreadExecutor extends ThreadExecutor<Runnable> {
14+
15+
protected MixinServerChunkManagerMainThreadExecutor(String name) {
16+
super(name);
17+
}
18+
19+
@Inject(method = "runTask", at = @At("RETURN"))
20+
private void onPostRunTask(CallbackInfoReturnable<Boolean> cir) {
21+
super.runTask();
22+
}
23+
24+
}

src/main/resources/c2me.accesswidener

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@ accessible class net/minecraft/world/chunk/ChunkStatus$SimpleGenerationTas
44
accessible class net/minecraft/world/chunk/ChunkStatus$LoadTask
55
accessible class net/minecraft/world/chunk/ChunkStatus$GenerationTask
66
accessible class net/minecraft/world/storage/StorageIoWorker$Result
7+
accessible class net/minecraft/server/world/ServerChunkManager$MainThreadExecutor
78

89
accessible method net/minecraft/world/storage/RegionBasedStorage <init> (Ljava/io/File;Z)V
910
accessible method net/minecraft/world/storage/RegionBasedStorage getRegionFile (Lnet/minecraft/util/math/ChunkPos;)Lnet/minecraft/world/storage/RegionFile;
1011
accessible method net/minecraft/world/storage/RegionBasedStorage write (Lnet/minecraft/util/math/ChunkPos;Lnet/minecraft/nbt/CompoundTag;)V
1112
accessible method net/minecraft/util/collection/WeightedList <init> (Ljava/util/List;)V
13+
accessible method net/minecraft/server/world/ServerChunkManager tick ()Z
1214

1315
accessible field net/minecraft/world/storage/StorageIoWorker$Result nbt Lnet/minecraft/nbt/CompoundTag;
1416
accessible field net/minecraft/world/storage/StorageIoWorker$Result future Ljava/util/concurrent/CompletableFuture;

src/main/resources/c2me.mixins.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
"threading.chunkio.MixinLightingProvider",
1111
"threading.chunkio.MixinScheduledTick",
1212
"threading.chunkio.MixinSerializingRegionBasedStorage",
13+
"threading.chunkio.MixinServerChunkManagerMainThreadExecutor",
1314
"threading.chunkio.MixinServerTickScheduler",
1415
"threading.chunkio.MixinSimpleTickScheduler",
1516
"threading.chunkio.MixinStorageIoWorker",
Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
# Global settings
2-
[global]
3-
41
# Configuration for async io system
52
[asyncIO]
6-
# Serializer executor parallelism
7-
serializerParallelism = -1
83
# IO worker executor parallelism
94
ioWorkerParallelism = -1
5+
# Serializer executor parallelism
6+
serializerParallelism = -1
107

118
# Configuration for threaded world generation
129
[threadedWorldGen]
1310
# Whether to enable this feature
1411
enabled = true
1512
# World generation worker executor parallelism
1613
parallelism = -1
14+
# Whether to allow feature generation (world decorations like trees, ores and etc.) run in parallel
15+
allowThreadedFeatures = false
16+

0 commit comments

Comments
 (0)