From acc5e7af9896b60d00ce90914576edeff69491d5 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 11 Dec 2021 21:40:43 -0600 Subject: [PATCH] Add support for different Core behavior in different MC versions --- .../core/builders/lodBuilding/LodBuilder.java | 16 +++++----- .../worldGeneration/LodWorldGenerator.java | 17 +++++++---- .../wrapperInterfaces/IVersionConstants.java | 24 +++++++++++++++ .../wrapperInterfaces/IWrapperFactory.java | 5 +--- .../config/ILodConfigWrapperSingleton.java | 30 ++++++++++++++----- 5 files changed, 66 insertions(+), 26 deletions(-) create mode 100644 src/main/java/com/seibel/lod/core/wrapperInterfaces/IVersionConstants.java diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java index 0dcb6abdd..c9fe74560 100644 --- a/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/LodBuilder.java @@ -22,7 +22,6 @@ package com.seibel.lod.core.builders.lodBuilding; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -import com.seibel.lod.core.api.ClientApi; import com.seibel.lod.core.enums.config.DistanceGenerationMode; import com.seibel.lod.core.enums.config.HorizontalResolution; import com.seibel.lod.core.objects.lod.LodDimension; @@ -36,12 +35,10 @@ import com.seibel.lod.core.util.LodThreadFactory; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.SingletonHandler; import com.seibel.lod.core.util.ThreadMapUtil; -import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; -import com.seibel.lod.core.wrapperInterfaces.block.AbstractBlockPosWrapper; +import com.seibel.lod.core.wrapperInterfaces.IVersionConstants; import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorSingletonWrapper; import com.seibel.lod.core.wrapperInterfaces.block.IBlockColorWrapper; import com.seibel.lod.core.wrapperInterfaces.block.IBlockShapeWrapper; -import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftWrapper; @@ -55,18 +52,19 @@ import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper; * @author Cola * @author Leonardo Amato * @author James Seibel - * @version 10-22-2021 + * @version 12-11-2021 */ -@SuppressWarnings("GrazieInspection") public class LodBuilder +@SuppressWarnings("GrazieInspection") +public class LodBuilder { private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class); private static final IBlockColorSingletonWrapper BLOCK_COLOR = SingletonHandler.get(IBlockColorSingletonWrapper.class); - private static final IWrapperFactory FACTORY = SingletonHandler.get(IWrapperFactory.class); + private static final IVersionConstants VERSION_CONSTANTS = SingletonHandler.get(IVersionConstants.class); /** If no blocks are found in the area in determineBottomPointForArea return this */ - public static final short DEFAULT_DEPTH = 0; + public static final short DEFAULT_DEPTH = (short) VERSION_CONSTANTS.getMinimumWorldHeight(); /** If no blocks are found in the area in determineHeightPointForArea return this */ - public static final short DEFAULT_HEIGHT = 0; + public static final short DEFAULT_HEIGHT = (short) VERSION_CONSTANTS.getMinimumWorldHeight(); /** Minecraft's max light value */ public static final short DEFAULT_MAX_LIGHT = 15; diff --git a/src/main/java/com/seibel/lod/core/builders/worldGeneration/LodWorldGenerator.java b/src/main/java/com/seibel/lod/core/builders/worldGeneration/LodWorldGenerator.java index 83d1ef3dd..5489f43d1 100644 --- a/src/main/java/com/seibel/lod/core/builders/worldGeneration/LodWorldGenerator.java +++ b/src/main/java/com/seibel/lod/core/builders/worldGeneration/LodWorldGenerator.java @@ -26,7 +26,6 @@ import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicInteger; import com.google.common.util.concurrent.ThreadFactoryBuilder; -import com.seibel.lod.core.api.ClientApi; import com.seibel.lod.core.builders.lodBuilding.LodBuilder; import com.seibel.lod.core.enums.config.DistanceGenerationMode; import com.seibel.lod.core.objects.PosToGenerateContainer; @@ -36,6 +35,7 @@ import com.seibel.lod.core.util.LevelPosUtil; import com.seibel.lod.core.util.LodThreadFactory; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.util.SingletonHandler; +import com.seibel.lod.core.wrapperInterfaces.IVersionConstants; import com.seibel.lod.core.wrapperInterfaces.IWrapperFactory; import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper; import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton; @@ -47,13 +47,14 @@ import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractWorldGenera * A singleton that handles all long distance LOD world generation. * @author Leonardo Amato * @author James Seibel - * @version 9-25-2021 + * @version 12-11-2021 */ public class LodWorldGenerator { private static final IMinecraftWrapper MC = SingletonHandler.get(IMinecraftWrapper.class); private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class); private static final IWrapperFactory WRAPPER_FACTORY = SingletonHandler.get(IWrapperFactory.class); + private static final IVersionConstants VERSION_CONSTANTS = SingletonHandler.get(IVersionConstants.class); /** This holds the thread used to create LOD generation requests off the main thread. */ @@ -199,9 +200,13 @@ public class LodWorldGenerator generatorThreadRunning = false; } }); - if (WRAPPER_FACTORY.isWorldGeneratorSingleThreaded()) { + + if (VERSION_CONSTANTS.isWorldGeneratorSingleThreaded(CONFIG.client().worldGenerator().getDistanceGenerationMode())) + { generatorFunc.run(); - } else { + } + else + { mainGenThread.execute(generatorFunc); } } // if distanceGenerationMode != DistanceGenerationMode.NONE && !generatorThreadRunning @@ -227,8 +232,8 @@ public class LodWorldGenerator Runnable method = (() -> {generateChunk(newPos, newGenerationMode, newLodBuilder, newLodDimension, serverWorld);}); - if (CONFIG.client().worldGenerator().getDistanceGenerationMode() == DistanceGenerationMode.FULL - || WRAPPER_FACTORY.isWorldGeneratorSingleThreaded()) + if (newGenerationMode == DistanceGenerationMode.FULL + || VERSION_CONSTANTS.isWorldGeneratorSingleThreaded(newGenerationMode)) { // if we are using FULL generation there is no reason // to queue up a bunch of generation requests, diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/IVersionConstants.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/IVersionConstants.java new file mode 100644 index 000000000..8f5f3f578 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/IVersionConstants.java @@ -0,0 +1,24 @@ +package com.seibel.lod.core.wrapperInterfaces; + +import com.seibel.lod.core.enums.config.DistanceGenerationMode; + +/** + * A singleton that contains variables specific to each version of Minecraft + * which can be used to change how DH-Core runs. + * For example: After MC 1.17 blocks can be negative, which changes how we generate LODs. + * + * @author James Seibel + * @version 12-11-2021 + */ +public interface IVersionConstants +{ + /** @returns the minimum height blocks can be generated */ + int getMinimumWorldHeight(); + + + /** + * @Returns True if the given DistanceGenerationMode can be run on our own thread.
+ * False if the generation must be run on Minecraft's server thread. + */ + boolean isWorldGeneratorSingleThreaded(DistanceGenerationMode distanceGenerationMode); +} diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/IWrapperFactory.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/IWrapperFactory.java index 980cdcf31..15ab5ee46 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/IWrapperFactory.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/IWrapperFactory.java @@ -30,7 +30,7 @@ import com.seibel.lod.core.wrapperInterfaces.worldGeneration.AbstractWorldGenera * This handles creating abstract wrapper objects. * * @author James Seibel - * @version 11-18-2021 + * @version 12-11-2021 */ public interface IWrapperFactory { @@ -45,7 +45,4 @@ public interface IWrapperFactory AbstractWorldGeneratorWrapper createWorldGenerator(LodBuilder newLodBuilder, LodDimension newLodDimension, IWorldWrapper worldWrapper); - - // FIXME: A temp getter for chunk gen mutli thread settings. Using default for backward compatibility - default boolean isWorldGeneratorSingleThreaded() {return false;} } diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java index 70b4c1492..44234f945 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/config/ILodConfigWrapperSingleton.java @@ -34,6 +34,7 @@ import com.seibel.lod.core.enums.rendering.FogDistance; import com.seibel.lod.core.enums.rendering.FogDrawMode; import com.seibel.lod.core.objects.MinDefaultMax; import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.wrapperInterfaces.IVersionConstants; /** * This holds the config defaults, setters/getters @@ -41,7 +42,7 @@ import com.seibel.lod.core.util.LodUtil; * the options that should be implemented in a configWrapperSingleton. * * @author James Seibel - * @version 12-9-2021 + * @version 12-11-2021 */ public interface ILodConfigWrapperSingleton { @@ -269,9 +270,16 @@ public interface ILodConfigWrapperSingleton void setGenerationPriority(GenerationPriority newGenerationPriority); DistanceGenerationMode DISTANCE_GENERATION_MODE_DEFAULT = DistanceGenerationMode.SURFACE; - String DISTANCE_GENERATION_MODE_DESC = "" + public static String getDistanceGenerationModeDesc(IVersionConstants versionConstants) + { + return "" + " How detailed should fake chunks be generated outside the vanilla render distance? \n" + "\n" + + " The times are the amount of time it took one of the developer's PC to generate \n" + + " one chunk in Minecraft 1.16.5 and may be inaccurate for different Minecraft versions. \n" + + " They are included to give a rough estimate as to how the different options \n" + + " may perform in comparison to each other. \n" + + "\n" + " " + DistanceGenerationMode.NONE + " \n" + " Don't run the distance generator. \n" + " No CPU usage - Fastest \n" @@ -280,35 +288,36 @@ public interface ILodConfigWrapperSingleton + " Only generate the biomes and use the biome's \n" + " grass color, water color, or snow color. \n" + " Doesn't generate height, everything is shown at sea level. \n" - + " Multithreaded - Fastest (2-5 ms) \n" + + " " + multiOrSingleThreadText(versionConstants, DistanceGenerationMode.BIOME_ONLY) + " - Fastest (2-5 ms) \n" + "\n" + " " + DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT + " \n" + " Same as " + DistanceGenerationMode.BIOME_ONLY + ", except instead \n" + " of always using sea level as the LOD height \n" + " different biome types (mountain, ocean, forest, etc.) \n" + " use predetermined heights to simulate having height data. \n" - + " Multithreaded - Fastest (2-5 ms) \n" + + " " + multiOrSingleThreadText(versionConstants, DistanceGenerationMode.BIOME_ONLY_SIMULATE_HEIGHT) + " - Fastest (2-5 ms) \n" + "\n" + " " + DistanceGenerationMode.SURFACE + " \n" + " Generate the world surface, \n" + " this does NOT include trees, \n" + " or structures. \n" - + " Multithreaded - Faster (10-20 ms) \n" + + " " + multiOrSingleThreadText(versionConstants, DistanceGenerationMode.SURFACE) + " - Faster (10-20 ms) \n" + "\n" + " " + DistanceGenerationMode.FEATURES + " \n" + " Generate everything except structures. \n" + " WARNING: This may cause world generation bugs or instability! \n" - + " Multithreaded - Fast (15-20 ms) \n" + + " " + multiOrSingleThreadText(versionConstants, DistanceGenerationMode.FEATURES) + " - Fast (15-20 ms) \n" + "\n" + " " + DistanceGenerationMode.FULL + " \n" + " Ask the local server to generate/load each chunk. \n" + " This will show player made structures, which can \n" + " be useful if you are adding the mod to a pre-existing world. \n" + " This is the most compatible, but causes server/simulation lag. \n" - + " SingleThreaded - Slow (15-50 ms, with spikes up to 200 ms) \n" + + " " + multiOrSingleThreadText(versionConstants, DistanceGenerationMode.FULL) + " - Slow (15-50 ms, with spikes up to 200 ms) \n" + "\n" + " The multithreaded options may increase CPU load significantly (while generating) \n" + " depending on how many world generation threads you have allocated. \n"; + } DistanceGenerationMode getDistanceGenerationMode(); void setDistanceGenerationMode(DistanceGenerationMode newDistanceGenerationMode); @@ -347,6 +356,13 @@ public interface ILodConfigWrapperSingleton + " This wont't affect performance."; BlocksToAvoid getBlocksToAvoid(); void setBlockToAvoid(BlocksToAvoid newBlockToAvoid); + + + /** description helper method */ + static String multiOrSingleThreadText(IVersionConstants versionConstants, DistanceGenerationMode distanceGenerationMode) + { + return versionConstants.isWorldGeneratorSingleThreaded(distanceGenerationMode) ? "Singlethreaded" : "Multithreaded"; + }; }