Prep for the external DH API

All files previously in the "api" package have been moved to "api.internal"
This commit is contained in:
James Seibel
2022-04-24 19:18:41 -05:00
parent ad0eb208ea
commit f5d48ebcd3
9 changed files with 100 additions and 64 deletions
@@ -0,0 +1,19 @@
package com.seibel.lod.core.api.external;
/**
* This stores objects and variables that
* are shared between the different Core external api classes. <br> <br>
*
* The external api package is designed to hold any code that
* interfaces between Distant Horizons and other mods or projects.
* For example: if a weather mod wanted to disable LOD rendering during a blizzard
* they would do that through a method in the external api.
*
*
* @author James Seibel
* @version 2022-4-24
*/
public class ExternalApiShared
{
}
@@ -17,8 +17,9 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.core.api;
package com.seibel.lod.core.api.internal;
import java.lang.invoke.MethodHandles;
import java.time.Duration;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
@@ -28,9 +29,10 @@ import com.seibel.lod.core.enums.rendering.RendererType;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import com.seibel.lod.core.logging.ConfigBasedSpamLogger;
import com.seibel.lod.core.render.RenderSystemTest;
import com.seibel.lod.core.wrapperInterfaces.chunk.AbstractChunkPosWrapper;
import org.apache.logging.log4j.Level;
import com.seibel.lod.core.handlers.LodDimensionFinder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.lwjgl.glfw.GLFW;
import com.seibel.lod.core.ModInfo;
@@ -60,7 +62,8 @@ import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
* @version 2022-3-26
*/
public class ClientApi
{
{
public static final Logger LOGGER = LogManager.getLogger(ClientApi.class.getSimpleName());
public static boolean prefLoggerEnabled = false;
public static final ClientApi INSTANCE = new ClientApi();
@@ -90,7 +93,7 @@ public class ClientApi
if (!ENABLE_LAG_SPIKE_LOGGING) return;
timer = System.nanoTime() - timer;
if (timer > LAG_SPIKE_THRESOLD_NS) {
ApiShared.LOGGER.info("LagSpikeCatcher: "+source+" took "+Duration.ofNanos(timer)+"!");
LOGGER.info("LagSpikeCatcher: "+source+" took "+Duration.ofNanos(timer)+"!");
}
}
}
@@ -167,8 +170,8 @@ public class ClientApi
ConfigBasedLogger.updateAll();
ConfigBasedSpamLogger.updateAll(doFlush);
if (ApiShared.previousVertQual != CONFIG.client().graphics().quality().getVerticalQuality()) {
ApiShared.previousVertQual = CONFIG.client().graphics().quality().getVerticalQuality();
if (InternalApiShared.previousVertQual != CONFIG.client().graphics().quality().getVerticalQuality()) {
InternalApiShared.previousVertQual = CONFIG.client().graphics().quality().getVerticalQuality();
EventApi.INSTANCE.worldUnloadEvent(MC.getWrappedServerWorld());
EventApi.INSTANCE.worldLoadEvent(MC.getWrappedClientWorld());
return;
@@ -178,13 +181,13 @@ public class ClientApi
if (!firstTimeSetupComplete)
firstFrameSetup();
if (!MC.playerExists() || ApiShared.lodWorld.getIsWorldNotLoaded())
if (!MC.playerExists() || InternalApiShared.lodWorld.getIsWorldNotLoaded())
return;
IWorldWrapper world = MC.getWrappedClientWorld();
if (world == null)
return;
LodDimension lodDim = ApiShared.lodWorld.getLodDimension(world.getDimensionType());
LodDimension lodDim = InternalApiShared.lodWorld.getLodDimension(world.getDimensionType());
// Make sure the player's data is up-to-date
DIMENSION_FINDER.updatePlayerData();
@@ -195,7 +198,7 @@ public class ClientApi
if (DIMENSION_FINDER.isDone())
{
lodDim = DIMENSION_FINDER.getAndClearFoundLodDimension();
ApiShared.lodWorld.addLodDimension(lodDim);
InternalApiShared.lodWorld.addLodDimension(lodDim);
}
else
{
@@ -226,7 +229,7 @@ public class ClientApi
toBeLoaded.remove(pos);
generating.add(pos);
//ApiShared.LOGGER.info("Lod Generation trying "+pos+". Remining: " +toBeLoaded.size());
ApiShared.lodBuilder.generateLodNodeAsync(chunk, ApiShared.lodWorld,
InternalApiShared.lodBuilder.generateLodNodeAsync(chunk, InternalApiShared.lodWorld,
world.getDimensionType(), DistanceGenerationMode.FULL, true, true, () -> {
generating.remove(pos);
LodBuilder.EVENT_LOGGER.debug("Manual Chunk: {} done. Remaining queue: {}", FACTORY.createChunkPos(pos), toBeLoaded.size());
@@ -272,7 +275,7 @@ public class ClientApi
ClientApi.renderer.drawLODs(lodDim, mcModelViewMatrix, mcProjectionMatrix, partialTicks, MC.getProfiler());
} catch (RuntimeException e) {
rendererDisabledBecauseOfExceptions = true;
ApiShared.LOGGER.error("Renderer thrown an uncaught exception: ",e);
LOGGER.error("Renderer thrown an uncaught exception: ",e);
try {
MC.sendChatMessage("\u00A74\u00A7l\u00A7uERROR: Distant Horizons"
+ " renderer has encountered an exception!");
@@ -294,12 +297,12 @@ public class ClientApi
// these can't be set until after the buffers are built (in renderer.drawLODs)
// otherwise the buffers may be set to the wrong size, or not changed at all
ApiShared.previousChunkRenderDistance = MC_RENDER.getRenderDistance();
ApiShared.previousLodRenderDistance = CONFIG.client().graphics().quality().getLodChunkRenderDistance();
InternalApiShared.previousChunkRenderDistance = MC_RENDER.getRenderDistance();
InternalApiShared.previousLodRenderDistance = CONFIG.client().graphics().quality().getLodChunkRenderDistance();
}
catch (Exception e)
{
ApiShared.LOGGER.error("client proxy uncaught exception: ", e);
LOGGER.error("client proxy uncaught exception: ", e);
}
}
@@ -335,24 +338,29 @@ public class ClientApi
//=================//
// DUBUG USE //
//=================//
// Trigger once on key press, with CLIENT PLAYER.
public void keyPressedEvent(int glfwKey) {
if (!CONFIG.client().advanced().debugging().getDebugKeybindingsEnabled()) return;
if (glfwKey == GLFW.GLFW_KEY_F8) {
CONFIG.client().advanced().debugging()
public void keyPressedEvent(int glfwKey)
{
if (!CONFIG.client().advanced().debugging().getDebugKeybindingsEnabled())
return;
if (glfwKey == GLFW.GLFW_KEY_F8)
{
CONFIG.client().advanced().debugging()
.setDebugMode(CONFIG.client().advanced().debugging().getDebugMode().getNext());
MC.sendChatMessage("F8: Set debug mode to " + CONFIG.client().advanced().debugging().getDebugMode());
}
if (glfwKey == GLFW.GLFW_KEY_F6) {
if (glfwKey == GLFW.GLFW_KEY_F6)
{
CONFIG.client().advanced().debugging()
.setRendererType(RendererType.next(CONFIG.client().advanced().debugging().getRendererType()));
MC.sendChatMessage("F6: Set rendering to " + CONFIG.client().advanced().debugging().getRendererType());
}
if (glfwKey == GLFW.GLFW_KEY_P) {
if (glfwKey == GLFW.GLFW_KEY_P)
{
prefLoggerEnabled = !prefLoggerEnabled;
MC.sendChatMessage("P: Debug Pref Logger is " + (prefLoggerEnabled ? "enabled" : "disabled"));
}
@@ -17,13 +17,13 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.core.api;
package com.seibel.lod.core.api.internal;
import com.seibel.lod.core.api.ClientApi.LagSpikeCatcher;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.worldGeneration.BatchGenerator;
import com.seibel.lod.core.enums.WorldType;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.logging.DhLoggerBuilder;
import com.seibel.lod.core.objects.lod.LodDimension;
import com.seibel.lod.core.objects.lod.RegionPos;
import com.seibel.lod.core.render.GLProxy;
@@ -36,18 +36,23 @@ import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IDimensionTypeWrapper;
import com.seibel.lod.core.wrapperInterfaces.world.IWorldWrapper;
import org.apache.logging.log4j.Logger;
import java.lang.invoke.MethodHandles;
/**
* This holds the methods that should be called by the host mod loader (Fabric,
* Forge, etc.). Specifically server and client events.
*
* @author James Seibel
* @version 11-12-2021
* @version 2021-11-12
*/
public class EventApi
{
public static final boolean ENABLE_STACK_DUMP_LOGGING = false;
public static final EventApi INSTANCE = new EventApi();
private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName());
private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class);
private static final ILodConfigWrapperSingleton CONFIG = SingletonHandler.get(ILodConfigWrapperSingleton.class);
private static final IVersionConstants VERSION_CONSTANTS = SingletonHandler.get(IVersionConstants.class);
@@ -75,13 +80,13 @@ public class EventApi
public void serverTickEvent()
{
lastWorldGenTickDelta--;
if (!MC.playerExists() || ApiShared.lodWorld.getIsWorldNotLoaded())
if (!MC.playerExists() || InternalApiShared.lodWorld.getIsWorldNotLoaded())
return;
LodDimension lodDim = ApiShared.lodWorld.getLodDimension(MC.getCurrentDimension());
LodDimension lodDim = InternalApiShared.lodWorld.getLodDimension(MC.getCurrentDimension());
if (lodDim == null)
return;
if (ApiShared.isShuttingDown)
if (InternalApiShared.isShuttingDown)
return;
if (CONFIG.client().worldGenerator().getEnableDistantGeneration())
@@ -90,8 +95,8 @@ public class EventApi
lastWorldGenTickDelta = 20; // 20 ticks is 1 second. We don't need to refresh world gen status every tick.
try {
if (batchGenerator == null)
batchGenerator = new BatchGenerator(ApiShared.lodBuilder, lodDim);
batchGenerator.queueGenerationRequests(lodDim, ApiShared.lodBuilder);
batchGenerator = new BatchGenerator(InternalApiShared.lodBuilder, lodDim);
batchGenerator.queueGenerationRequests(lodDim, InternalApiShared.lodBuilder);
} catch (Exception e) {
// Exception may happen if world got unloaded unorderly
e.printStackTrace();
@@ -114,14 +119,14 @@ public class EventApi
public void worldSaveEvent()
{
ApiShared.lodWorld.saveAllDimensions(false); // Do an async save.
InternalApiShared.lodWorld.saveAllDimensions(false); // Do an async save.
}
/** This is also called when a new dimension loads */
public void worldLoadEvent(IWorldWrapper world)
{
if (ENABLE_STACK_DUMP_LOGGING)
ApiShared.LOGGER.info(
LOGGER.info(
"WorldLoadEvent called here for "
+ (world.getWorldType() == WorldType.ClientWorld ? "clientLevel" : "serverLevel"),
new RuntimeException());
@@ -129,9 +134,9 @@ public class EventApi
if (world.getWorldType() == WorldType.ServerWorld)
return;
isCurrentlyOnSinglePlayerServer = MC.hasSinglePlayerServer();
if (!ApiShared.isShuttingDown) ApiShared.LOGGER.warn("WorldLoadEvent called on {} while another world is loaded!",
if (!InternalApiShared.isShuttingDown) LOGGER.warn("WorldLoadEvent called on {} while another world is loaded!",
(world.getWorldType() == WorldType.ClientWorld ? "clientLevel" : "serverLevel"));
ApiShared.isShuttingDown = false;
InternalApiShared.isShuttingDown = false;
//DataPointUtil.WORLD_HEIGHT = world.getHeight();
LodBuilder.MIN_WORLD_HEIGHT = world.getMinHeight(); // This updates the World height
@@ -140,21 +145,21 @@ public class EventApi
// the player just loaded a new world/dimension
String worldID = LodUtil.getWorldID(world);
ApiShared.LOGGER.info("Loading new world/dimension: {}",worldID);
ApiShared.lodWorld.selectWorld(worldID);
ApiShared.LOGGER.info("World/dimension loaded: {}",worldID);
LOGGER.info("Loading new world/dimension: {}",worldID);
InternalApiShared.lodWorld.selectWorld(worldID);
LOGGER.info("World/dimension loaded: {}",worldID);
// make sure the correct LODs are being rendered
// (if this isn't done the previous world's LODs may be drawn)
ClientApi.renderer.regenerateLODsNextFrame();
ApiShared.previousVertQual = CONFIG.client().graphics().quality().getVerticalQuality();
InternalApiShared.previousVertQual = CONFIG.client().graphics().quality().getVerticalQuality();
}
/** This is also called when the user disconnects from a server+ */
public void worldUnloadEvent(IWorldWrapper world)
{
if (ENABLE_STACK_DUMP_LOGGING)
ApiShared.LOGGER.info(
LOGGER.info(
"WorldUnloadEvent called here for "
+ (world.getWorldType() == WorldType.ClientWorld ? "clientLevel" : "serverLevel"),
new RuntimeException());
@@ -167,15 +172,15 @@ public class EventApi
// if this isn't done unfinished tasks may be left in the queue
// preventing new LodChunks form being generated
if (ApiShared.isShuttingDown) return; // Don't do this if we're already shutting down
ApiShared.isShuttingDown = true;
if (InternalApiShared.isShuttingDown) return; // Don't do this if we're already shutting down
InternalApiShared.isShuttingDown = true;
// TODO Better report on when world gen is stuck and timeout
if (batchGenerator != null)
batchGenerator.stop(true);
batchGenerator = null;
ApiShared.lodWorld.deselectWorld(); // This force a save and shutdown lodDim properly
InternalApiShared.lodWorld.deselectWorld(); // This force a save and shutdown lodDim properly
// prevent issues related to the buffer builder
// breaking or retaining previous data when changing worlds.
@@ -183,12 +188,12 @@ public class EventApi
ClientApi.renderer.requestCleanup();
GLProxy.ensureAllGLJobCompleted();
recalculateWidths = true;
ApiShared.previousVertQual = null;
InternalApiShared.previousVertQual = null;
// TODO: Check if after the refactoring, is this still needed
ClientApi.renderer = new LodRenderer(ClientApi.lodBufferBuilderFactory);
ClientApi.INSTANCE.rendererDisabledBecauseOfExceptions = false;
ApiShared.LOGGER.info("Distant Horizon unloaded");
LOGGER.info("Distant Horizon unloaded");
}
public void blockChangeEvent(IChunkWrapper chunk, IDimensionTypeWrapper dimType)
@@ -196,7 +201,7 @@ public class EventApi
if (dimType != MC.getCurrentDimension())
return;
// recreate the LOD where the blocks were changed
LagSpikeCatcher blockChangeUpdate = new LagSpikeCatcher();
ClientApi.LagSpikeCatcher blockChangeUpdate = new ClientApi.LagSpikeCatcher();
ClientApi.INSTANCE.toBeLoaded.add(chunk.getLongChunkPos());
blockChangeUpdate.end("clientChunkLoad");
}
@@ -238,11 +243,11 @@ public class EventApi
newWidth += (newWidth & 1) == 0 ? 1 : 0;
// do the dimensions need to change in size?
if (ApiShared.lodBuilder.defaultDimensionWidthInRegions != newWidth || recalculateWidths)
if (InternalApiShared.lodBuilder.defaultDimensionWidthInRegions != newWidth || recalculateWidths)
{
// update the dimensions to fit the new width
ApiShared.lodWorld.resizeDimensionRegionWidth(newWidth);
ApiShared.lodBuilder.defaultDimensionWidthInRegions = newWidth;
InternalApiShared.lodWorld.resizeDimensionRegionWidth(newWidth);
InternalApiShared.lodBuilder.defaultDimensionWidthInRegions = newWidth;
ClientApi.renderer.setupBuffers();
recalculateWidths = false;
@@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.lod.core.api;
package com.seibel.lod.core.api.internal;
import com.seibel.lod.core.ModInfo;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
@@ -28,15 +28,18 @@ import org.apache.logging.log4j.Logger;
/**
* This stores objects and variables that
* are shared between the different Core api classes.
*
* are shared between the different Core internal api classes. <br> <br>
*
* The internal api package is designed to hold any code that
* interfaces between Distant Horizons and the host mod loader
* (IE Fabric or Forge).
*
* @author James Seibel
* @version 11-12-2021
* @version 2022-4-24
*/
public class ApiShared
public class InternalApiShared
{
public static final Logger LOGGER = LogManager.getLogger(ModInfo.NAME);
public ApiShared INSTANCE = new ApiShared();
public InternalApiShared INSTANCE = new InternalApiShared();
public static final LodWorld lodWorld = new LodWorld();
public static final LodBuilder lodBuilder = new LodBuilder();
@@ -50,7 +53,9 @@ public class ApiShared
/** Signal whether a world is shutting down */
public static volatile boolean isShuttingDown = false;
private ApiShared()
private InternalApiShared()
{
}
@@ -36,7 +36,7 @@ import java.util.concurrent.locks.ReentrantLock;
import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import com.seibel.lod.core.wrapperInterfaces.config.ILodConfigWrapperSingleton;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.api.internal.ClientApi;
import org.apache.commons.compress.compressors.xz.XZCompressorInputStream;
import org.apache.commons.compress.compressors.xz.XZCompressorOutputStream;
@@ -19,7 +19,7 @@
package com.seibel.lod.core.logging;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.api.internal.ClientApi;
import com.seibel.lod.core.enums.config.LoggerMode;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
@@ -19,8 +19,7 @@
package com.seibel.lod.core.logging;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.api.internal.ClientApi;
import com.seibel.lod.core.enums.config.LoggerMode;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Logger;
@@ -26,7 +26,7 @@ import java.util.concurrent.Executor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import com.seibel.lod.core.api.ClientApi;
import com.seibel.lod.core.api.internal.ClientApi;
import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.CubicLodTemplate;
import com.seibel.lod.core.builders.lodBuilding.LodBuilder;
import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodQuadBuilder;
@@ -23,7 +23,7 @@ import java.awt.Color;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
import com.seibel.lod.core.api.ApiShared;
import com.seibel.lod.core.api.internal.InternalApiShared;
import com.seibel.lod.core.logging.ConfigBasedLogger;
import com.seibel.lod.core.logging.ConfigBasedSpamLogger;
import com.seibel.lod.core.objects.BoolType;
@@ -564,7 +564,7 @@ public class LodRenderer
boolean tryFullGen = false;
// check if the view distance or config changed
if (ApiShared.previousLodRenderDistance != CONFIG.client().graphics().quality().getLodChunkRenderDistance()
if (InternalApiShared.previousLodRenderDistance != CONFIG.client().graphics().quality().getLodChunkRenderDistance()
|| chunkRenderDistance != prevRenderDistance
|| prevFogDistance != CONFIG.client().graphics().fogQuality().getFogDistance())
{