Switch to another way to do the world gen. Now more mod compat!

This commit is contained in:
tom lee
2022-02-12 22:00:09 +08:00
parent f0994fff75
commit ef0023ef39
13 changed files with 145 additions and 95 deletions
@@ -34,5 +34,6 @@ public class DependencySetup {
SingletonHandler.bind(IVersionConstants.class, VersionConstants.INSTANCE);
SingletonHandler.bind(IWrapperFactory.class, WrapperFactory.INSTANCE);
DependencySetupDoneCheck.isDone = true;
}
}
@@ -0,0 +1,7 @@
package com.seibel.lod.common.wrappers;
public class DependencySetupDoneCheck
{
public static boolean isDone = false;
}
@@ -233,6 +233,12 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
public static final LodThreadFactory threadFactory = new LodThreadFactory("Gen-Worker-Thread", Thread.MIN_PRIORITY);
public static ThreadLocal<Boolean> isDistantGeneratorThread = new ThreadLocal<Boolean>();
public static boolean isCurrentThreadDistantGeneratorThread() {
return (isDistantGeneratorThread.get() != null);
}
public ExecutorService executors = Executors.newFixedThreadPool(
CONFIG.client().advanced().threading().getNumberOfWorldGenerationThreads(), threadFactory);
@@ -462,33 +468,35 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
{
int targetIndex = referencedChunks.offsetOf(centreIndex, ox, oy);
ChunkAccess target = referencedChunks.get(targetIndex);
target.setLightCorrect(true);
if (target instanceof LevelChunk)
((LevelChunk) target).setClientLightReady(true);
ChunkWrapper wrappedChunk = new ChunkWrapper(target, region);
if (!wrappedChunk.isLightCorrect()) {
throw new RuntimeException("The generated chunk somehow has isLightCorrect() returning false");
}
boolean isFull = target.getStatus() == ChunkStatus.FULL || target instanceof LevelChunk;
boolean isPartial = target.isOldNoiseGeneration();
if (isFull)
{
if (ENABLE_LOAD_EVENT_LOGGING)
ClientApi.LOGGER.info("Detected full existing chunk at {}", target.getPos());
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, new ChunkWrapper(target, region),
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
new LodBuilderConfig(DistanceGenerationMode.FULL), true, e.genAllDetails);
}
else if (isPartial)
{
if (ENABLE_LOAD_EVENT_LOGGING)
ClientApi.LOGGER.info("Detected old existing chunk at {}", target.getPos());
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, new ChunkWrapper(target, region),
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
new LodBuilderConfig(generationMode), true, e.genAllDetails);
}
else if (target.getStatus() == ChunkStatus.EMPTY && generationMode == DistanceGenerationMode.NONE)
{
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, new ChunkWrapper(target, region),
params.lodBuilder.generateLodNodeFromChunk(params.lodDim,wrappedChunk,
LodBuilderConfig.getFillVoidConfig(), true, e.genAllDetails);
}
else
{
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, new ChunkWrapper(target, region),
params.lodBuilder.generateLodNodeFromChunk(params.lodDim, wrappedChunk,
new LodBuilderConfig(generationMode), true, e.genAllDetails);
}
if (e.lightMode == LightGenerationMode.FANCY || isFull)
@@ -566,6 +574,10 @@ public final class BatchGenerationEnvironment extends AbstractBatchGenerationEnv
{
if (p instanceof ProtoChunk)
((ProtoChunk) p).setLightCorrect(true);
if (p instanceof LevelChunk) {
((LevelChunk) p).setLightCorrect(true);
((LevelChunk) p).setClientLightReady(true);
}
});
break;
}
@@ -46,7 +46,12 @@ public final class GenerationEvent
future = generationGroup.executors.submit(() ->
{
generationGroup.generateLodFromList(this);
BatchGenerationEnvironment.isDistantGeneratorThread.set(true);
try {
generationGroup.generateLodFromList(this);
} finally {
BatchGenerationEnvironment.isDistantGeneratorThread.remove();
}
});
}
@@ -34,21 +34,7 @@ public final class StepBiomes {
}
public final ChunkStatus STATUS = ChunkStatus.BIOMES;
//FIXME: Bug with TerraBlender Mod!
private ChunkAccess createBiomes(ChunkGenerator generator, Registry<Biome> registry, Blender blender, StructureFeatureManager structureFeatureManager, ChunkAccess chunkAccess) {
if (generator instanceof NoiseBasedChunkGenerator) {
((NoiseBasedChunkGenerator) generator).doCreateBiomes(registry, blender, structureFeatureManager, chunkAccess);
return chunkAccess;
} else if (generator instanceof FlatLevelSource || generator instanceof DebugLevelSource) {
chunkAccess.fillBiomesFromNoise(generator.getBiomeSource()::getNoiseBiome, generator.climateSampler());
return chunkAccess;
} else {
return environment.joinSync(generator.fillFromNoise(Runnable::run, blender, structureFeatureManager, chunkAccess));
}
}
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
@@ -62,8 +48,8 @@ public final class StepBiomes {
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepBiomes: "+chunk.getPos());
chunk = createBiomes(environment.params.generator, environment.params.biomes, Blender.of(worldGenRegion),
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
chunk = environment.joinSync(environment.params.generator.createBiomes(environment.params.biomes, Runnable::run, Blender.of(worldGenRegion),
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
}
}
}
@@ -52,6 +52,7 @@ public final class StepLight {
} catch (Exception e) {
e.printStackTrace();
}
if (chunk instanceof LevelChunk) ((LevelChunk)chunk).setClientLightReady(true);
chunk.setLightCorrect(true);
}
lightEngine.runUpdates(Integer.MAX_VALUE, true, true);
@@ -36,31 +36,6 @@ public final class StepNoise {
}
public final ChunkStatus STATUS = ChunkStatus.NOISE;
private ChunkAccess NoiseBased$fillFromNoise(NoiseBasedChunkGenerator generator, Blender blender, StructureFeatureManager structureFeatureManager, ChunkAccess chunkAccess) {
NoiseSettings noiseSettings = generator.settings.get().noiseSettings();
LevelHeightAccessor levelHeightAccessor = chunkAccess.getHeightAccessorForGeneration();
int i = Math.max(noiseSettings.minY(), levelHeightAccessor.getMinBuildHeight());
int j = Math.min(noiseSettings.minY() + noiseSettings.height(), levelHeightAccessor.getMaxBuildHeight());
int k = Mth.intFloorDiv(i, noiseSettings.getCellHeight());
int l = Mth.intFloorDiv(j - i, noiseSettings.getCellHeight());
if (l <= 0) {
return chunkAccess;
}
int m = chunkAccess.getSectionIndex(l * noiseSettings.getCellHeight() - 1 + i);
int n = chunkAccess.getSectionIndex(i);
HashSet<LevelChunkSection> set = Sets.newHashSet();
for (int o = m; o >= n; --o) {
LevelChunkSection levelChunkSection = chunkAccess.getSection(o);
levelChunkSection.acquire();
set.add(levelChunkSection);
}
chunkAccess = generator.doFill(blender, structureFeatureManager, chunkAccess, k, l);
for (LevelChunkSection levelChunkSection : set) {
levelChunkSection.release();
};
return chunkAccess;
}
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
@@ -75,13 +50,8 @@ public final class StepNoise {
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepNoise: "+chunk.getPos());
if (environment.params.generator instanceof NoiseBasedChunkGenerator) {
chunk = NoiseBased$fillFromNoise((NoiseBasedChunkGenerator)environment.params.generator,Blender.of(worldGenRegion),
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
} else {
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
chunk = environment.joinSync(environment.params.generator.fillFromNoise(Runnable::run, Blender.of(worldGenRegion),
tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk));
}
}
}
}
@@ -35,44 +35,6 @@ public final class StepStructureReference {
public final ChunkStatus STATUS = ChunkStatus.STRUCTURE_REFERENCES;
private void createReferences(WorldGenRegion worldGenLevel, StructureFeatureManager structureFeatureManager,
ChunkAccess chunkAccess) {
ChunkPos chunkPos = chunkAccess.getPos();
int j = chunkPos.x;
int k = chunkPos.z;
int l = chunkPos.getMinBlockX();
int m = chunkPos.getMinBlockZ();
SectionPos sectionPos = SectionPos.bottomOf(chunkAccess);
for (int n = j - 8; n <= j + 8; n++) {
for (int o = k - 8; o <= k + 8; o++) {
if (!worldGenLevel.hasChunk(n, o))
continue;
long p = ChunkPos.asLong(n, o);
for (StructureStart<?> structureStart : worldGenLevel.getChunk(n, o).getAllStarts().values()) {
try {
if (structureStart.isValid()
&& structureStart.getBoundingBox().intersects(l, m, l + 15, m + 15)) {
structureFeatureManager.addReferenceForFeature(sectionPos, structureStart.getFeature(),
p, chunkAccess);
}
} catch (Exception exception) {
CrashReport crashReport = CrashReport.forThrowable(exception,
"Generating structure reference");
CrashReportCategory crashReportCategory = crashReport.addCategory("Structure");
crashReportCategory.setDetail("Id",
() -> Registry.STRUCTURE_FEATURE.getKey(structureStart.getFeature()).toString());
crashReportCategory.setDetail("Name", () -> structureStart.getFeature().getFeatureName());
crashReportCategory.setDetail("Class",
() -> structureStart.getFeature().getClass().getCanonicalName());
throw new ReportedException(crashReport);
}
}
}
}
}
public void generateGroup(ThreadedParameters tParams, WorldGenRegion worldGenRegion,
List<ChunkAccess> chunks) {
@@ -86,7 +48,7 @@ public final class StepStructureReference {
for (ChunkAccess chunk : chunksToDo) {
// System.out.println("StepStructureReference: "+chunk.getPos());
createReferences(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
environment.params.generator.createReferences(worldGenRegion, tParams.structFeat.forWorldGenRegion(worldGenRegion), chunk);
}
}
}
+1 -1
Submodule core updated: 50819c30da...fbbccf4739
@@ -0,0 +1,52 @@
package com.seibel.lod.fabric.mixins;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.seibel.lod.common.wrappers.DependencySetupDoneCheck;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.util.DummyRunExecutorService;
import net.minecraft.Util;
@Mixin(Util.class)
public class MixinUtilBackgroudThread
{
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Runnable;",
at = @At("HEAD"), cancellable = true)
private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable<Runnable> ci)
{
if (DependencySetupDoneCheck.isDone && BatchGenerationEnvironment.isCurrentThreadDistantGeneratorThread())
{
//ClientApi.LOGGER.info("util wrapThreadWithTaskName(Runnable) triggered");
ci.setReturnValue(r);
}
}
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/util/function/Supplier;)Ljava/util/function/Supplier;",
at = @At("HEAD"), cancellable = true)
private static void overrideUtil$wrapThreadWithTaskNameForSupplier(String string, Supplier<?> r, CallbackInfoReturnable<Supplier<?>> ci)
{
if (DependencySetupDoneCheck.isDone && BatchGenerationEnvironment.isCurrentThreadDistantGeneratorThread())
{
//ClientApi.LOGGER.info("util wrapThreadWithTaskName(Supplier) triggered");
ci.setReturnValue(r);
}
}
@Inject(method = "backgroundExecutor", at = @At("HEAD"), cancellable = true)
private static void overrideUtil$backgroundExecutor(CallbackInfoReturnable<ExecutorService> ci)
{
if (DependencySetupDoneCheck.isDone && BatchGenerationEnvironment.isCurrentThreadDistantGeneratorThread())
{
//ClientApi.LOGGER.info("util backgroundExecutor triggered");
ci.setReturnValue(new DummyRunExecutorService());
}
}
}
@@ -5,6 +5,7 @@
"compatibilityLevel": "JAVA_17",
"mixins": [
"unsafe.MixinThreadingDectector",
"MixinUtilBackgroudThread",
"events.MixinServerLevel"
],
"client": [
@@ -0,0 +1,52 @@
package com.seibel.lod.forge.mixins;
import java.util.concurrent.ExecutorService;
import java.util.function.Supplier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.seibel.lod.common.wrappers.DependencySetupDoneCheck;
import com.seibel.lod.common.wrappers.worldGeneration.BatchGenerationEnvironment;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.util.DummyRunExecutorService;
import net.minecraft.Util;
@Mixin(Util.class)
public class MixinUtilBackgroudThread
{
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/lang/Runnable;)Ljava/lang/Runnable;",
at = @At("HEAD"), cancellable = true)
private static void overrideUtil$wrapThreadWithTaskName(String string, Runnable r, CallbackInfoReturnable<Runnable> ci)
{
if (DependencySetupDoneCheck.isDone && BatchGenerationEnvironment.isCurrentThreadDistantGeneratorThread())
{
//ClientApi.LOGGER.info("util wrapThreadWithTaskName(Runnable) triggered");
ci.setReturnValue(r);
}
}
@Inject(method = "wrapThreadWithTaskName(Ljava/lang/String;Ljava/util/function/Supplier;)Ljava/util/function/Supplier;",
at = @At("HEAD"), cancellable = true)
private static void overrideUtil$wrapThreadWithTaskNameForSupplier(String string, Supplier<?> r, CallbackInfoReturnable<Supplier<?>> ci)
{
if (DependencySetupDoneCheck.isDone && BatchGenerationEnvironment.isCurrentThreadDistantGeneratorThread())
{
//ClientApi.LOGGER.info("util wrapThreadWithTaskName(Supplier) triggered");
ci.setReturnValue(r);
}
}
@Inject(method = "backgroundExecutor", at = @At("HEAD"), cancellable = true)
private static void overrideUtil$backgroundExecutor(CallbackInfoReturnable<ExecutorService> ci)
{
if (DependencySetupDoneCheck.isDone && BatchGenerationEnvironment.isCurrentThreadDistantGeneratorThread())
{
//ClientApi.LOGGER.info("util backgroundExecutor triggered");
ci.setReturnValue(new DummyRunExecutorService());
}
}
}
+1
View File
@@ -4,6 +4,7 @@
"package": "com.seibel.lod.forge.mixins",
"compatibilityLevel": "JAVA_17",
"mixins": [
"MixinUtilBackgroudThread"
],
"client": [
"MixinOptionsScreen",