From d6397d6444eda62271d65ea1767d6d8a8534c547 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Thu, 16 Feb 2023 11:30:11 -0600 Subject: [PATCH] Improve the casting around SharedApi.currentWorld --- .../methods/data/DhApiTerrainDataRepo.java | 13 +- .../lod/core/api/internal/ClientApi.java | 27 +-- .../lod/core/api/internal/ServerApi.java | 47 +++--- .../lod/core/api/internal/SharedApi.java | 19 ++- .../lod/core/level/DhClientServerLevel.java | 2 +- .../lod/core/render/DhApiRenderProxy.java | 6 +- .../seibel/lod/core/render/LodQuadTree.java | 4 +- .../com/seibel/lod/core/util/RenderUtil.java | 33 ++-- .../lod/core/world/AbstractDhWorld.java | 27 ++- .../lod/core/world/DhApiWorldProxy.java | 22 +-- .../lod/core/world/DhClientServerWorld.java | 84 ++++++---- .../seibel/lod/core/world/DhClientWorld.java | 137 ++++++++++------ .../seibel/lod/core/world/DhServerWorld.java | 155 ++++++++++-------- .../lod/core/world/EWorldEnvironment.java | 5 + .../seibel/lod/core/world/IDhClientWorld.java | 9 +- .../seibel/lod/core/world/IDhServerWorld.java | 10 +- .../com/seibel/lod/core/world/IDhWorld.java | 19 +++ 17 files changed, 374 insertions(+), 245 deletions(-) create mode 100644 core/src/main/java/com/seibel/lod/core/world/IDhWorld.java diff --git a/core/src/main/java/com/seibel/lod/core/api/external/methods/data/DhApiTerrainDataRepo.java b/core/src/main/java/com/seibel/lod/core/api/external/methods/data/DhApiTerrainDataRepo.java index 270450d8d..ba709583c 100644 --- a/core/src/main/java/com/seibel/lod/core/api/external/methods/data/DhApiTerrainDataRepo.java +++ b/core/src/main/java/com/seibel/lod/core/api/external/methods/data/DhApiTerrainDataRepo.java @@ -18,6 +18,7 @@ import com.seibel.lod.core.util.*; import com.seibel.lod.core.util.math.Vec3d; import com.seibel.lod.core.util.math.Vec3f; import com.seibel.lod.core.util.math.Vec3i; +import com.seibel.lod.core.world.AbstractDhWorld; import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; @@ -166,18 +167,22 @@ public class DhApiTerrainDataRepo implements IDhApiTerrainDataRepo */ private static DhApiResult getTerrainDataColumnArray(IDhApiLevelWrapper levelWrapper, DhLodPos requestedColumnPos, Integer nullableBlockYPos) { - if (SharedApi.currentWorld == null) + AbstractDhWorld currentWorld = SharedApi.getAbstractDhWorld(); + if (currentWorld == null) { return DhApiResult.createFail("Unable to get terrain data before the world has loaded."); } - if (!(levelWrapper instanceof ILevelWrapper coreLevelWrapper)) + + if (!ILevelWrapper.class.isInstance(levelWrapper)) { // custom level wrappers aren't supported, // the API user must get a level wrapper from our code somewhere - return DhApiResult.createFail("Unsupported [" + IDhApiLevelWrapper.class.getSimpleName() + "] implementation, only the core class [" + IDhLevel.class.getSimpleName() + "] is a valid parameter."); + return DhApiResult.createFail("Unsupported ["+IDhApiLevelWrapper.class.getSimpleName()+"] implementation, only the core class ["+IDhLevel.class.getSimpleName()+"] is a valid parameter."); } + ILevelWrapper coreLevelWrapper = (ILevelWrapper) levelWrapper; - IDhLevel level = SharedApi.currentWorld.getLevel(coreLevelWrapper); + + IDhLevel level = currentWorld.getLevel(coreLevelWrapper); if (level == null) { return DhApiResult.createFail("Unable to get terrain data before the world has loaded."); diff --git a/core/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java b/core/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java index ce1d6c7df..17942b9cc 100644 --- a/core/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java +++ b/core/src/main/java/com/seibel/lod/core/api/internal/ClientApi.java @@ -101,7 +101,7 @@ public class ClientApi LOGGER.info("Client on ClientOnly mode connecting."); } - SharedApi.currentWorld = new DhClientWorld(); + SharedApi.setDhWorld(new DhClientWorld()); } public void onClientOnlyDisconnected() @@ -111,15 +111,15 @@ public class ClientApi LOGGER.info("Client on ClientOnly mode disconnecting."); } - SharedApi.currentWorld.close(); - SharedApi.currentWorld = null; + SharedApi.getAbstractDhWorld().close(); + SharedApi.setDhWorld(null); } public void clientChunkLoadEvent(IChunkWrapper chunk, IClientLevelWrapper level) { if (SharedApi.getEnvironment() == EWorldEnvironment.Client_Only) { - IDhLevel dhLevel = SharedApi.currentWorld.getLevel(level); + IDhLevel dhLevel = SharedApi.getAbstractDhWorld().getLevel(level); if (dhLevel != null) { dhLevel.updateChunk(chunk); @@ -145,9 +145,10 @@ public class ClientApi LOGGER.info("Client level "+level+" unloading."); } - if (SharedApi.currentWorld != null) + AbstractDhWorld world = SharedApi.getAbstractDhWorld(); + if (world != null) { - SharedApi.currentWorld.unloadLevel(level); + world.unloadLevel(level); ApiEventInjector.INSTANCE.fireAllEvents(DhApiLevelUnloadEvent.class, new DhApiLevelUnloadEvent.EventParam(level)); } } @@ -159,9 +160,10 @@ public class ClientApi LOGGER.info("Client level "+level+" loading."); } - if (SharedApi.currentWorld != null) + AbstractDhWorld world = SharedApi.getAbstractDhWorld(); + if (world != null) { - SharedApi.currentWorld.getOrLoadLevel(level); + world.getOrLoadLevel(level); ApiEventInjector.INSTANCE.fireAllEvents(DhApiLevelLoadEvent.class, new DhApiLevelLoadEvent.EventParam(level)); } } @@ -208,9 +210,10 @@ public class ClientApi ConfigBasedLogger.updateAll(); ConfigBasedSpamLogger.updateAll(doFlush); - if (SharedApi.currentWorld instanceof IDhClientWorld) + IDhClientWorld clientWorld = SharedApi.getIDhClientWorld(); + if (clientWorld != null) { - ((IDhClientWorld) SharedApi.currentWorld).clientTick(); + clientWorld.clientTick(); } profiler.pop(); } @@ -246,8 +249,8 @@ public class ClientApi //FIXME: Improve class hierarchy of DhWorld, IClientWorld, IServerWorld to fix all this hard casting // (also in RenderUtil) - AbstractDhWorld dhWorld = SharedApi.currentWorld; - IDhClientLevel level = (IDhClientLevel) dhWorld.getOrLoadLevel(levelWrapper); + IDhClientWorld dhClientWorld = SharedApi.getIDhClientWorld(); + IDhClientLevel level = dhClientWorld.getOrLoadClientLevel(levelWrapper); if (prefLoggerEnabled) { diff --git a/core/src/main/java/com/seibel/lod/core/api/internal/ServerApi.java b/core/src/main/java/com/seibel/lod/core/api/internal/ServerApi.java index 1b8624922..8986a9d52 100644 --- a/core/src/main/java/com/seibel/lod/core/api/internal/ServerApi.java +++ b/core/src/main/java/com/seibel/lod/core/api/internal/ServerApi.java @@ -24,19 +24,16 @@ import com.seibel.lod.api.methods.events.abstractEvents.DhApiLevelSaveEvent; import com.seibel.lod.api.methods.events.abstractEvents.DhApiLevelUnloadEvent; import com.seibel.lod.core.DependencyInjection.ApiEventInjector; import com.seibel.lod.core.level.IDhLevel; +import com.seibel.lod.core.world.AbstractDhWorld; import com.seibel.lod.core.world.DhClientServerWorld; import com.seibel.lod.core.world.DhServerWorld; import com.seibel.lod.core.world.IDhServerWorld; -import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.logging.DhLoggerBuilder; -import com.seibel.lod.core.wrapperInterfaces.IVersionConstants; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IServerLevelWrapper; 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 events. @@ -65,9 +62,9 @@ public class ServerApi public void serverTickEvent() { - if (SharedApi.currentWorld instanceof IDhServerWorld) + IDhServerWorld serverWorld = SharedApi.getIDhServerWorld(); + if (serverWorld != null) { - IDhServerWorld serverWorld = (IDhServerWorld) SharedApi.currentWorld; serverWorld.serverTick(); this.lastWorldGenTickDelta--; if (this.lastWorldGenTickDelta <= 0) @@ -89,25 +86,18 @@ public class ServerApi LOGGER.info("Server World loading with (dedicated?:{})", isDedicatedEnvironment); } - if (isDedicatedEnvironment) - { - SharedApi.currentWorld = new DhServerWorld(); - } - else - { - SharedApi.currentWorld = new DhClientServerWorld(); - } + SharedApi.setDhWorld(isDedicatedEnvironment ? new DhServerWorld() : new DhClientServerWorld()); } public void serverUnloadEvent() { if (ENABLE_EVENT_LOGGING) { - LOGGER.info("Server World "+SharedApi.currentWorld+" unloading"); + LOGGER.info("Server World "+SharedApi.getAbstractDhWorld()+" unloading"); } - SharedApi.currentWorld.close(); - SharedApi.currentWorld = null; + SharedApi.getAbstractDhWorld().close(); + SharedApi.setDhWorld(null); } public void serverLevelLoadEvent(IServerLevelWrapper level) @@ -117,9 +107,10 @@ public class ServerApi LOGGER.info("Server Level {} loading", level); } - if (SharedApi.currentWorld != null) + AbstractDhWorld serverWorld = SharedApi.getAbstractDhWorld(); + if (serverWorld != null) { - SharedApi.currentWorld.getOrLoadLevel(level); + serverWorld.getOrLoadLevel(level); ApiEventInjector.INSTANCE.fireAllEvents(DhApiLevelLoadEvent.class, new DhApiLevelLoadEvent.EventParam(level)); } } @@ -130,9 +121,10 @@ public class ServerApi LOGGER.info("Server Level {} unloading", level); } - if (SharedApi.currentWorld != null) + AbstractDhWorld serverWorld = SharedApi.getAbstractDhWorld(); + if (serverWorld != null) { - SharedApi.currentWorld.unloadLevel(level); + serverWorld.unloadLevel(level); ApiEventInjector.INSTANCE.fireAllEvents(DhApiLevelUnloadEvent.class, new DhApiLevelUnloadEvent.EventParam(level)); } } @@ -142,14 +134,15 @@ public class ServerApi { if (ENABLE_EVENT_LOGGING) { - LOGGER.info("Server world {} saving", SharedApi.currentWorld); + LOGGER.info("Server world "+SharedApi.getAbstractDhWorld()+" saving"); } - if (SharedApi.currentWorld instanceof IDhServerWorld) + AbstractDhWorld serverWorld = SharedApi.getAbstractDhWorld(); + if (serverWorld != null) { - SharedApi.currentWorld.saveAndFlush(); + serverWorld.saveAndFlush(); - for (IDhLevel level : SharedApi.currentWorld.getAllLoadedLevels()) + for (IDhLevel level : serverWorld.getAllLoadedLevels()) { ApiEventInjector.INSTANCE.fireAllEvents(DhApiLevelSaveEvent.class, new DhApiLevelSaveEvent.EventParam(level.getLevelWrapper())); } @@ -158,7 +151,7 @@ public class ServerApi public void serverChunkLoadEvent(IChunkWrapper chunk, ILevelWrapper level) { - IDhLevel dhLevel = SharedApi.currentWorld.getLevel(level); + IDhLevel dhLevel = SharedApi.getAbstractDhWorld().getLevel(level); if (dhLevel != null) { dhLevel.updateChunk(chunk); @@ -166,7 +159,7 @@ public class ServerApi } public void serverChunkSaveEvent(IChunkWrapper chunk, ILevelWrapper level) { - IDhLevel dhLevel = SharedApi.currentWorld.getLevel(level); + IDhLevel dhLevel = SharedApi.getAbstractDhWorld().getLevel(level); if (dhLevel != null) { dhLevel.updateChunk(chunk); diff --git a/core/src/main/java/com/seibel/lod/core/api/internal/SharedApi.java b/core/src/main/java/com/seibel/lod/core/api/internal/SharedApi.java index 9f00707f2..2967e07eb 100644 --- a/core/src/main/java/com/seibel/lod/core/api/internal/SharedApi.java +++ b/core/src/main/java/com/seibel/lod/core/api/internal/SharedApi.java @@ -1,14 +1,14 @@ package com.seibel.lod.core.api.internal; import com.seibel.lod.core.Initializer; -import com.seibel.lod.core.world.EWorldEnvironment; -import com.seibel.lod.core.world.AbstractDhWorld; +import com.seibel.lod.core.world.*; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper; public class SharedApi { public static IMinecraftSharedWrapper MC; - public static AbstractDhWorld currentWorld; + + private static AbstractDhWorld currentWorld; @@ -18,4 +18,17 @@ public class SharedApi public static EWorldEnvironment getEnvironment() { return (currentWorld == null) ? null : currentWorld.environment; } + + public static void setDhWorld(AbstractDhWorld newWorld) { currentWorld = newWorld; } + + public static AbstractDhWorld getAbstractDhWorld() { return currentWorld; } + + /** returns null if the {@link SharedApi#currentWorld} isn't a {@link DhClientServerWorld} */ + public static DhClientServerWorld getDhClientServerWorld() { return (currentWorld != null && DhClientServerWorld.class.isInstance(currentWorld)) ? (DhClientServerWorld) currentWorld : null; } + + /** returns null if the {@link SharedApi#currentWorld} isn't a {@link DhClientWorld} or {@link DhClientServerWorld} */ + public static IDhClientWorld getIDhClientWorld() { return (currentWorld != null && IDhClientWorld.class.isInstance(currentWorld)) ? (IDhClientWorld) currentWorld : null; } + /** returns null if the {@link SharedApi#currentWorld} isn't a {@link DhServerWorld} or {@link DhClientServerWorld} */ + public static IDhServerWorld getIDhServerWorld() { return (currentWorld != null && IDhServerWorld.class.isInstance(currentWorld)) ? (IDhServerWorld) currentWorld : null; } + } diff --git a/core/src/main/java/com/seibel/lod/core/level/DhClientServerLevel.java b/core/src/main/java/com/seibel/lod/core/level/DhClientServerLevel.java index 76f4f2e3d..44eb2b084 100644 --- a/core/src/main/java/com/seibel/lod/core/level/DhClientServerLevel.java +++ b/core/src/main/java/com/seibel/lod/core/level/DhClientServerLevel.java @@ -101,7 +101,7 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel return; } - if (renderState.quadtree.blockViewDistance != Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH) + if (renderState.quadtree.blockRenderDistance != Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH) { if (!this.renderStateRef.compareAndSet(renderState, null)) { diff --git a/core/src/main/java/com/seibel/lod/core/render/DhApiRenderProxy.java b/core/src/main/java/com/seibel/lod/core/render/DhApiRenderProxy.java index dbc3318dc..511695722 100644 --- a/core/src/main/java/com/seibel/lod/core/render/DhApiRenderProxy.java +++ b/core/src/main/java/com/seibel/lod/core/render/DhApiRenderProxy.java @@ -4,6 +4,7 @@ import com.seibel.lod.api.interfaces.render.IDhApiRenderProxy; import com.seibel.lod.api.objects.DhApiResult; import com.seibel.lod.core.api.internal.SharedApi; import com.seibel.lod.core.level.IDhLevel; +import com.seibel.lod.core.world.AbstractDhWorld; /** * Used to interact with Distant Horizons' rendering systems. @@ -24,14 +25,15 @@ public class DhApiRenderProxy implements IDhApiRenderProxy public DhApiResult clearRenderDataCache() { // make sure this is a valid time to run the method - if (SharedApi.currentWorld == null) + AbstractDhWorld world = SharedApi.getAbstractDhWorld(); + if (world == null) { return DhApiResult.createFail("No world loaded"); } // clear the render caches for each level - Iterable loadedLevels = SharedApi.currentWorld.getAllLoadedLevels(); + Iterable loadedLevels = world.getAllLoadedLevels(); for (IDhLevel level : loadedLevels) { if (level != null) diff --git a/core/src/main/java/com/seibel/lod/core/render/LodQuadTree.java b/core/src/main/java/com/seibel/lod/core/render/LodQuadTree.java index a8e835c44..d58acfb45 100644 --- a/core/src/main/java/com/seibel/lod/core/render/LodQuadTree.java +++ b/core/src/main/java/com/seibel/lod/core/render/LodQuadTree.java @@ -50,7 +50,7 @@ public class LodQuadTree implements AutoCloseable private final MovableGridRingList[] renderSectionRingLists; - public final int blockViewDistance; + public final int blockRenderDistance; private final ILodRenderSourceProvider renderSourceProvider; private final IDhClientLevel level; //FIXME: Proper hierarchy to remove this reference! @@ -72,7 +72,7 @@ public class LodQuadTree implements AutoCloseable DetailDistanceUtil.updateSettings(); //TODO: Move this to somewhere else this.level = level; this.renderSourceProvider = provider; - this.blockViewDistance = viewDistance; + this.blockRenderDistance = viewDistance; diff --git a/core/src/main/java/com/seibel/lod/core/util/RenderUtil.java b/core/src/main/java/com/seibel/lod/core/util/RenderUtil.java index 79420e6d3..357617a85 100644 --- a/core/src/main/java/com/seibel/lod/core/util/RenderUtil.java +++ b/core/src/main/java/com/seibel/lod/core/util/RenderUtil.java @@ -179,17 +179,23 @@ public class RenderUtil int vanillaBlockRenderedDistance = MC_RENDER.getRenderDistance() * LodUtil.CHUNK_WIDTH; float nearClipPlane; - if (Config.Client.Advanced.lodOnlyMode.get()) { + if (Config.Client.Advanced.lodOnlyMode.get()) + { nearClipPlane = 0.1f; - } else if (Config.Client.Graphics.AdvancedGraphics.useExtendedNearClipPlane.get()) { + } + else if (Config.Client.Graphics.AdvancedGraphics.useExtendedNearClipPlane.get()) + { nearClipPlane = Math.min(vanillaBlockRenderedDistance - LodUtil.CHUNK_WIDTH, (float) 8 * LodUtil.CHUNK_WIDTH); // allow a max near clip plane of 8 chunks - } else { + } + else + { nearClipPlane = 16f; } // modify the based on the player's FOV double fov = MC_RENDER.getFov(partialTicks); double aspectRatio = (double) MC_RENDER.getScreenWidth() / MC_RENDER.getScreenHeight(); + return (float) (nearClipPlane / Math.sqrt(1d + MathUtil.pow2(Math.tan(fov / 180d * Math.PI / 2d)) * (MathUtil.pow2(aspectRatio) + 1d))); @@ -204,23 +210,26 @@ public class RenderUtil public static boolean shouldLodsRender(ILevelWrapper levelWrapper) { if (!MC.playerExists()) + { return false; + } if (levelWrapper == null) + { return false; + } - AbstractDhWorld dhWorld = SharedApi.currentWorld; - if (dhWorld == null) + IDhClientWorld clientWorld = SharedApi.getIDhClientWorld(); + if (clientWorld == null) + { return false; + } - if (!(SharedApi.currentWorld instanceof IDhClientWorld)) - return false; // don't attempt to render server worlds - - //FIXME: Improve class hierarchy of DhWorld, IClientWorld, IServerWorld to fix all this hard casting - // (also in ClientApi) - IDhClientLevel level = (IDhClientLevel) dhWorld.getOrLoadLevel(levelWrapper); + IDhClientLevel level = clientWorld.getOrLoadClientLevel(levelWrapper); if (level == null) + { return false; //Level is not ready yet. + } if (MC_RENDER.playerHasBlindnessEffect()) { @@ -231,7 +240,9 @@ public class RenderUtil } if (MC_RENDER.getLightmapWrapper() == null) + { return false; + } return true; } diff --git a/core/src/main/java/com/seibel/lod/core/world/AbstractDhWorld.java b/core/src/main/java/com/seibel/lod/core/world/AbstractDhWorld.java index e5667a92c..d9e9227fd 100644 --- a/core/src/main/java/com/seibel/lod/core/world/AbstractDhWorld.java +++ b/core/src/main/java/com/seibel/lod/core/world/AbstractDhWorld.java @@ -16,24 +16,19 @@ import java.util.concurrent.CompletableFuture; * Represents an entire world (aka server) and * contains every level in that world. */ -public abstract class AbstractDhWorld implements Closeable +public abstract class AbstractDhWorld implements IDhWorld, Closeable { protected static final Logger LOGGER = DhLoggerBuilder.getLogger(); - + public final EWorldEnvironment environment; - - protected AbstractDhWorld(EWorldEnvironment environment) { - this.environment = environment; - } - public abstract IDhLevel getOrLoadLevel(ILevelWrapper wrapper); - - public abstract IDhLevel getLevel(ILevelWrapper wrapper); - public abstract Iterable getAllLoadedLevels(); - - public abstract void unloadLevel(ILevelWrapper wrapper); - public abstract CompletableFuture saveAndFlush(); - - @Override - public abstract void close(); + + + + protected AbstractDhWorld(EWorldEnvironment environment) { this.environment = environment; } + + + // remove the "throws IOException" + @Override + public abstract void close(); } diff --git a/core/src/main/java/com/seibel/lod/core/world/DhApiWorldProxy.java b/core/src/main/java/com/seibel/lod/core/world/DhApiWorldProxy.java index cf3526303..b47fe5c22 100644 --- a/core/src/main/java/com/seibel/lod/core/world/DhApiWorldProxy.java +++ b/core/src/main/java/com/seibel/lod/core/world/DhApiWorldProxy.java @@ -38,12 +38,12 @@ public class DhApiWorldProxy implements IDhApiWorldProxy @Override - public boolean worldLoaded() { return SharedApi.currentWorld != null; } + public boolean worldLoaded() { return SharedApi.getAbstractDhWorld() != null; } @Override public IDhApiLevelWrapper getSinglePlayerLevel() { - if (SharedApi.currentWorld == null) + if (SharedApi.getAbstractDhWorld() == null) { throw new IllegalStateException(NO_WORLD_EXCEPTION_STRING); } @@ -63,14 +63,14 @@ public class DhApiWorldProxy implements IDhApiWorldProxy @Override public Iterable getAllLoadedLevelWrappers() { - if (SharedApi.currentWorld == null) + AbstractDhWorld world = SharedApi.getAbstractDhWorld(); + if (world == null) { throw new IllegalStateException(NO_WORLD_EXCEPTION_STRING); } - ArrayList returnList = new ArrayList<>(); - for (IDhLevel dhLevel : SharedApi.currentWorld.getAllLoadedLevels()) + for (IDhLevel dhLevel : world.getAllLoadedLevels()) { returnList.add(dhLevel.getLevelWrapper()); } @@ -80,14 +80,14 @@ public class DhApiWorldProxy implements IDhApiWorldProxy @Override public Iterable getAllLoadedLevelsForDimensionType(IDhApiDimensionTypeWrapper dimensionTypeWrapper) { - if (SharedApi.currentWorld == null) + AbstractDhWorld world = SharedApi.getAbstractDhWorld(); + if (world == null) { throw new IllegalStateException(NO_WORLD_EXCEPTION_STRING); } - ArrayList returnList = new ArrayList<>(); - for (IDhLevel dhLevel : SharedApi.currentWorld.getAllLoadedLevels()) + for (IDhLevel dhLevel : world.getAllLoadedLevels()) { ILevelWrapper levelWrapper = dhLevel.getLevelWrapper(); if (levelWrapper.getDimensionType().equals(dimensionTypeWrapper)) @@ -101,16 +101,16 @@ public class DhApiWorldProxy implements IDhApiWorldProxy @Override public Iterable getAllLoadedLevelsWithDimensionNameLike(String dimensionName) { - if (SharedApi.currentWorld == null) + AbstractDhWorld world = SharedApi.getAbstractDhWorld(); + if (world == null) { throw new IllegalStateException(NO_WORLD_EXCEPTION_STRING); } - String soughtDimName = dimensionName.toLowerCase(); ArrayList returnList = new ArrayList<>(); - for (IDhLevel dhLevel : SharedApi.currentWorld.getAllLoadedLevels()) + for (IDhLevel dhLevel : world.getAllLoadedLevels()) { ILevelWrapper levelWrapper = dhLevel.getLevelWrapper(); String levelDimName = levelWrapper.getDimensionType().getDimensionName().toLowerCase(); diff --git a/core/src/main/java/com/seibel/lod/core/world/DhClientServerWorld.java b/core/src/main/java/com/seibel/lod/core/world/DhClientServerWorld.java index 9355ea1c4..33c90e020 100644 --- a/core/src/main/java/com/seibel/lod/core/world/DhClientServerWorld.java +++ b/core/src/main/java/com/seibel/lod/core/world/DhClientServerWorld.java @@ -21,20 +21,28 @@ public class DhClientServerWorld extends AbstractDhWorld implements IDhClientWor private final HashMap levelObjMap; private final HashSet dhLevels; public final LocalSaveStructure saveStructure; + public ExecutorService dhTickerThread = LodUtil.makeSingleThreadPool("DHTickerThread", 2); - public EventLoop eventLoop = new EventLoop(dhTickerThread, this::_clientTick); //TODO: Rate-limit the loop - public F3Screen.DynamicMessage f3Msg; - - public DhClientServerWorld() { + public EventLoop eventLoop = new EventLoop(this.dhTickerThread, this::_clientTick); //TODO: Rate-limit the loop + + public F3Screen.DynamicMessage f3Message; + + + + public DhClientServerWorld() + { super(EWorldEnvironment.Client_Server); - saveStructure = new LocalSaveStructure(); - levelObjMap = new HashMap<>(); - dhLevels = new HashSet<>(); - LOGGER.info("Started DhWorld of type {}", environment); - f3Msg = new F3Screen.DynamicMessage(() -> - LodUtil.formatLog("{} World with {} levels", environment, dhLevels.size())); + this.saveStructure = new LocalSaveStructure(); + this.levelObjMap = new HashMap<>(); + this.dhLevels = new HashSet<>(); + + LOGGER.info("Started DhWorld of type "+this.environment); + + this.f3Message = new F3Screen.DynamicMessage(() -> LodUtil.formatLog(this.environment+" World with "+this.dhLevels.size()+" levels")); } - + + + @Override public DhClientServerLevel getOrLoadLevel(ILevelWrapper wrapper) { @@ -56,9 +64,13 @@ public class DhClientServerWorld extends AbstractDhWorld implements IDhClientWor IClientLevelWrapper clientSide = (IClientLevelWrapper) levelWrapper; IServerLevelWrapper serverSide = clientSide.tryGetServerSideWrapper(); LodUtil.assertTrue(serverSide != null); + DhClientServerLevel level = this.levelObjMap.get(serverSide); if (level == null) + { return null; + } + level.startRenderer(clientSide); return level; }); @@ -90,38 +102,42 @@ public class DhClientServerWorld extends AbstractDhWorld implements IDhClientWor } } - private void _clientTick() { + private void _clientTick() + { //LOGGER.info("Client world tick with {} levels", levels.size()); - dhLevels.forEach(DhClientServerLevel::clientTick); + this.dhLevels.forEach(DhClientServerLevel::clientTick); } - public void clientTick() { + public void clientTick() + { //LOGGER.info("Client world tick"); - eventLoop.tick(); + this.eventLoop.tick(); } - public void serverTick() { - dhLevels.forEach(DhClientServerLevel::serverTick); - } + public void serverTick() { this.dhLevels.forEach(DhClientServerLevel::serverTick); } - public void doWorldGen() { - dhLevels.forEach(DhClientServerLevel::doWorldGen); - } + public void doWorldGen() { this.dhLevels.forEach(DhClientServerLevel::doWorldGen); } @Override - public CompletableFuture saveAndFlush() { - return CompletableFuture.allOf(dhLevels.stream().map(DhClientServerLevel::save).toArray(CompletableFuture[]::new)); - } + public CompletableFuture saveAndFlush() + { + return CompletableFuture.allOf(this.dhLevels.stream().map(DhClientServerLevel::save).toArray(CompletableFuture[]::new)); + } @Override - public void close() { - saveAndFlush().join(); - for (DhClientServerLevel level : dhLevels) { - LOGGER.info("Unloading level " + level.serverLevel.getDimensionType().getDimensionName()); - level.close(); - } - levelObjMap.clear(); - eventLoop.close(); - LOGGER.info("Closed DhWorld of type {}", environment); - } + public void close() + { + this.saveAndFlush().join(); + + for (DhClientServerLevel level : this.dhLevels) + { + LOGGER.info("Unloading level " + level.serverLevel.getDimensionType().getDimensionName()); + level.close(); + } + + this.levelObjMap.clear(); + this.eventLoop.close(); + LOGGER.info("Closed DhWorld of type "+this.environment); + } + } diff --git a/core/src/main/java/com/seibel/lod/core/world/DhClientWorld.java b/core/src/main/java/com/seibel/lod/core/world/DhClientWorld.java index 624c13560..c36486da4 100644 --- a/core/src/main/java/com/seibel/lod/core/world/DhClientWorld.java +++ b/core/src/main/java/com/seibel/lod/core/world/DhClientWorld.java @@ -20,80 +20,111 @@ public class DhClientWorld extends AbstractDhWorld implements IDhClientWorld { private final HashMap levels; public final ClientOnlySaveStructure saveStructure; + public ExecutorService dhTickerThread = LodUtil.makeSingleThreadPool("DHTickerThread", 2); - public EventLoop eventLoop = new EventLoop(dhTickerThread, this::_clientTick); - - public DhClientWorld() { - super(EWorldEnvironment.Client_Only); - saveStructure = new ClientOnlySaveStructure(); - levels = new HashMap<>(); - LOGGER.info("Started DhWorld of type {}", environment); - } - + public EventLoop eventLoop = new EventLoop(this.dhTickerThread, this::_clientTick); + + + + public DhClientWorld() + { + super(EWorldEnvironment.Client_Only); + this.saveStructure = new ClientOnlySaveStructure(); + this.levels = new HashMap<>(); + LOGGER.info("Started DhWorld of type "+this.environment); + } + + + @Override - public DhClientLevel getOrLoadLevel(ILevelWrapper wrapper) { - if (!(wrapper instanceof IClientLevelWrapper)) return null; + public DhClientLevel getOrLoadLevel(ILevelWrapper wrapper) + { + if (!(wrapper instanceof IClientLevelWrapper)) + { + return null; + } - return levels.computeIfAbsent((IClientLevelWrapper) wrapper, (w) -> { - File level = saveStructure.tryGetOrCreateLevelFolder(wrapper); - if (level == null) return null; - return new DhClientLevel(saveStructure, w); + return this.levels.computeIfAbsent((IClientLevelWrapper) wrapper, (clientLevelWrapper) -> + { + File level = this.saveStructure.tryGetOrCreateLevelFolder(wrapper); + if (level == null) + { + return null; + } + + return new DhClientLevel(this.saveStructure, clientLevelWrapper); }); } @Override - public DhClientLevel getLevel(ILevelWrapper wrapper) { - if (!(wrapper instanceof IClientLevelWrapper)) return null; - return levels.get(wrapper); + public DhClientLevel getLevel(ILevelWrapper wrapper) + { + if (!(wrapper instanceof IClientLevelWrapper)) + { + return null; + } + + return this.levels.get(wrapper); } @Override - public Iterable getAllLoadedLevels() - { - return levels.values(); - } + public Iterable getAllLoadedLevels() { return this.levels.values(); } @Override - public void unloadLevel(ILevelWrapper wrapper) { - if (!(wrapper instanceof IClientLevelWrapper)) return; - if (levels.containsKey(wrapper)) { - LOGGER.info("Unloading level {} ", levels.get(wrapper)); - levels.remove(wrapper).close(); + public void unloadLevel(ILevelWrapper wrapper) + { + if (!(wrapper instanceof IClientLevelWrapper)) + { + return; + } + + if (this.levels.containsKey(wrapper)) + { + LOGGER.info("Unloading level "+this.levels.get(wrapper)); + this.levels.remove(wrapper).close(); } } - private void _clientTick() { - int newViewDistance = Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH; - Iterator iterator = levels.values().iterator(); - while (iterator.hasNext()) { - DhClientLevel level = iterator.next(); - if (level.tree.blockViewDistance != newViewDistance) { - level.close(); - iterator.remove(); - } - } - DetailDistanceUtil.updateSettings(); - levels.values().forEach(DhClientLevel::clientTick); - } + private void _clientTick() + { + int newBlockRenderDistance = Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH; + + Iterator iterator = this.levels.values().iterator(); + while (iterator.hasNext()) + { + DhClientLevel level = iterator.next(); + if (level.tree.blockRenderDistance != newBlockRenderDistance) + { + level.close(); + iterator.remove(); + } + } + + DetailDistanceUtil.updateSettings(); + this.levels.values().forEach(DhClientLevel::clientTick); + } - public void clientTick() { - eventLoop.tick(); + public void clientTick() { this.eventLoop.tick(); } + + @Override + public CompletableFuture saveAndFlush() + { + return CompletableFuture.allOf(this.levels.values().stream().map(DhClientLevel::save).toArray(CompletableFuture[]::new)); } @Override - public CompletableFuture saveAndFlush() { - return CompletableFuture.allOf(levels.values().stream().map(DhClientLevel::save).toArray(CompletableFuture[]::new)); - } - - @Override - public void close() { - saveAndFlush().join(); - for (DhClientLevel level : levels.values()) { + public void close() + { + this.saveAndFlush().join(); + for (DhClientLevel level : this.levels.values()) + { LOGGER.info("Unloading level " + level.level.getDimensionType().getDimensionName()); level.close(); } - levels.clear(); - eventLoop.close(); - LOGGER.info("Closed DhWorld of type {}", environment); + + this.levels.clear(); + this.eventLoop.close(); + LOGGER.info("Closed DhWorld of type "+this.environment); } + } diff --git a/core/src/main/java/com/seibel/lod/core/world/DhServerWorld.java b/core/src/main/java/com/seibel/lod/core/world/DhServerWorld.java index 60eeba014..c7f35d976 100644 --- a/core/src/main/java/com/seibel/lod/core/world/DhServerWorld.java +++ b/core/src/main/java/com/seibel/lod/core/world/DhServerWorld.java @@ -3,6 +3,7 @@ package com.seibel.lod.core.world; import com.seibel.lod.core.level.DhServerLevel; import com.seibel.lod.core.level.IDhLevel; import com.seibel.lod.core.file.structure.LocalSaveStructure; +import com.seibel.lod.core.level.IDhServerLevel; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IServerLevelWrapper; @@ -13,71 +14,91 @@ import java.util.concurrent.CompletableFuture; public class DhServerWorld extends AbstractDhWorld implements IDhServerWorld { - private final HashMap levels; - public final LocalSaveStructure saveStructure; - - public DhServerWorld() { - super(EWorldEnvironment.Server_Only); - saveStructure = new LocalSaveStructure(); - levels = new HashMap<>(); - LOGGER.info("Started DhWorld of type {}", environment); - } - - @Override - public DhServerLevel getOrLoadLevel(ILevelWrapper wrapper) { - if (!(wrapper instanceof IServerLevelWrapper)) return null; - return levels.computeIfAbsent((IServerLevelWrapper) wrapper, (w) -> { - File levelFile = saveStructure.tryGetOrCreateLevelFolder(wrapper); - LodUtil.assertTrue(levelFile != null); - return new DhServerLevel(saveStructure, w); - }); - } - - @Override - public DhServerLevel getLevel(ILevelWrapper wrapper) { - if (!(wrapper instanceof IServerLevelWrapper)) return null; - return levels.get(wrapper); - } - - @Override - public Iterable getAllLoadedLevels() - { - return levels.values(); - } - - @Override - public void unloadLevel(ILevelWrapper wrapper) { - if (!(wrapper instanceof IServerLevelWrapper)) return; - if (levels.containsKey(wrapper)) { - LOGGER.info("Unloading level {} ", levels.get(wrapper)); - levels.remove(wrapper).close(); - } - } - - public void serverTick() { - levels.values().forEach(DhServerLevel::serverTick); - } - - public void doWorldGen() { - levels.values().forEach(DhServerLevel::doWorldGen); - - } - - @Override - public CompletableFuture saveAndFlush() { - return CompletableFuture.allOf(levels.values().stream().map(DhServerLevel::save).toArray(CompletableFuture[]::new)); - } - - @Override - public void close() { - for (DhServerLevel level : levels.values()) { - LOGGER.info("Unloading level " + level.level.getDimensionType().getDimensionName()); - level.close(); - } - levels.clear(); - LOGGER.info("Closed DhWorld of type {}", environment); - } - - - + private final HashMap levels; + public final LocalSaveStructure saveStructure; + + + + public DhServerWorld() + { + super(EWorldEnvironment.Server_Only); + + this.saveStructure = new LocalSaveStructure(); + this.levels = new HashMap<>(); + + LOGGER.info("Started "+DhServerWorld.class.getSimpleName()+" of type "+this.environment); + } + + + + @Override + public DhServerLevel getOrLoadLevel(ILevelWrapper wrapper) + { + if (!(wrapper instanceof IServerLevelWrapper)) + { + return null; + } + + return this.levels.computeIfAbsent((IServerLevelWrapper) wrapper, (w) -> + { + File levelFile = this.saveStructure.tryGetOrCreateLevelFolder(wrapper); + LodUtil.assertTrue(levelFile != null); + return new DhServerLevel(this.saveStructure, w); + }); + } + + @Override + public DhServerLevel getLevel(ILevelWrapper wrapper) + { + if (!(wrapper instanceof IServerLevelWrapper)) + { + return null; + } + + return this.levels.get(wrapper); + } + + @Override + public Iterable getAllLoadedLevels() { return this.levels.values(); } + + @Override + public void unloadLevel(ILevelWrapper wrapper) + { + if (!(wrapper instanceof IServerLevelWrapper)) + { + return; + } + + if (this.levels.containsKey(wrapper)) + { + LOGGER.info("Unloading level {} ", this.levels.get(wrapper)); + this.levels.remove(wrapper).close(); + } + } + + public void serverTick() { this.levels.values().forEach(DhServerLevel::serverTick); } + + public void doWorldGen() { this.levels.values().forEach(DhServerLevel::doWorldGen); } + + @Override + public CompletableFuture saveAndFlush() + { + return CompletableFuture.allOf(this.levels.values().stream().map(DhServerLevel::save).toArray(CompletableFuture[]::new)); + } + + @Override + public void close() + { + for (DhServerLevel level : this.levels.values()) + { + LOGGER.info("Unloading level " + level.level.getDimensionType().getDimensionName()); + level.close(); + } + + this.levels.clear(); + LOGGER.info("Closed DhWorld of type "+this.environment); + } + + + } diff --git a/core/src/main/java/com/seibel/lod/core/world/EWorldEnvironment.java b/core/src/main/java/com/seibel/lod/core/world/EWorldEnvironment.java index ebb7dc2ca..b4e3d653b 100644 --- a/core/src/main/java/com/seibel/lod/core/world/EWorldEnvironment.java +++ b/core/src/main/java/com/seibel/lod/core/world/EWorldEnvironment.java @@ -1,5 +1,10 @@ package com.seibel.lod.core.world; +/** + * Client_Only, + * Client_Server, + * Server_Only + */ public enum EWorldEnvironment { Client_Only, diff --git a/core/src/main/java/com/seibel/lod/core/world/IDhClientWorld.java b/core/src/main/java/com/seibel/lod/core/world/IDhClientWorld.java index 9d64552ac..6cdc1435b 100644 --- a/core/src/main/java/com/seibel/lod/core/world/IDhClientWorld.java +++ b/core/src/main/java/com/seibel/lod/core/world/IDhClientWorld.java @@ -1,6 +1,13 @@ package com.seibel.lod.core.world; -public interface IDhClientWorld +import com.seibel.lod.core.level.IDhClientLevel; +import com.seibel.lod.core.wrapperInterfaces.world.IClientLevelWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; + +public interface IDhClientWorld extends IDhWorld { void clientTick(); + + default IDhClientLevel getOrLoadClientLevel(ILevelWrapper levelWrapper) { return (IDhClientLevel) this.getOrLoadLevel(levelWrapper); } + } diff --git a/core/src/main/java/com/seibel/lod/core/world/IDhServerWorld.java b/core/src/main/java/com/seibel/lod/core/world/IDhServerWorld.java index 995018ebc..6b523c029 100644 --- a/core/src/main/java/com/seibel/lod/core/world/IDhServerWorld.java +++ b/core/src/main/java/com/seibel/lod/core/world/IDhServerWorld.java @@ -1,7 +1,15 @@ package com.seibel.lod.core.world; -public interface IDhServerWorld +import com.seibel.lod.core.level.IDhServerLevel; +import com.seibel.lod.core.wrapperInterfaces.world.IClientLevelWrapper; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; + +/** Used both for dedicated server and singleplayer worlds */ +public interface IDhServerWorld extends IDhWorld { void serverTick(); void doWorldGen(); + + default IDhServerLevel getOrLoadServerLevel(ILevelWrapper levelWrapper) { return (IDhServerLevel) this.getOrLoadLevel(levelWrapper); } + } diff --git a/core/src/main/java/com/seibel/lod/core/world/IDhWorld.java b/core/src/main/java/com/seibel/lod/core/world/IDhWorld.java new file mode 100644 index 000000000..e3377a159 --- /dev/null +++ b/core/src/main/java/com/seibel/lod/core/world/IDhWorld.java @@ -0,0 +1,19 @@ +package com.seibel.lod.core.world; + +import com.seibel.lod.core.level.IDhLevel; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; + +import java.util.concurrent.CompletableFuture; + +public interface IDhWorld +{ + + IDhLevel getOrLoadLevel(ILevelWrapper levelWrapper); + IDhLevel getLevel(ILevelWrapper wrapper); + Iterable getAllLoadedLevels(); + + void unloadLevel(ILevelWrapper levelWrapper); + + CompletableFuture saveAndFlush(); + +}