diff --git a/src/main/java/com/seibel/lod/core/a7/level/DhClientServerLevel.java b/src/main/java/com/seibel/lod/core/a7/level/DhClientServerLevel.java index b92d99d73..f4cbd3317 100644 --- a/src/main/java/com/seibel/lod/core/a7/level/DhClientServerLevel.java +++ b/src/main/java/com/seibel/lod/core/a7/level/DhClientServerLevel.java @@ -9,28 +9,46 @@ import com.seibel.lod.core.a7.render.RenderBufferHandler; import com.seibel.lod.core.a7.save.structure.LocalSaveStructure; import com.seibel.lod.core.config.Config; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; +import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.objects.math.Mat4f; import com.seibel.lod.core.render.a7LodRenderer; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; +import org.apache.logging.log4j.Logger; import java.util.concurrent.CompletableFuture; public class DhClientServerLevel implements IClientLevel, IServerLevel { + private static final Logger LOGGER = DhLoggerBuilder.getLogger(); private static final IMinecraftClientWrapper MC_CLIENT = SingletonHandler.get(IMinecraftClientWrapper.class); public final LocalSaveStructure save; public final LocalDataFileHandler dataFileHandler; - public final RenderFileHandler renderFileHandler; - public final RenderBufferHandler renderBufferHandler; //TODO: Should this be owned by renderer? + public RenderFileHandler renderFileHandler = null; + public RenderBufferHandler renderBufferHandler = null; //TODO: Should this be owned by renderer? public final ILevelWrapper level; public a7LodRenderer renderer = null; - public LodQuadTree tree; + public LodQuadTree tree = null; public DhClientServerLevel(LocalSaveStructure save, ILevelWrapper level) { this.level = level; this.save = save; dataFileHandler = new LocalDataFileHandler(this, save.getDataFolder(level)); + } + + public void clientTick() { + if (tree != null) tree.tick(new DhBlockPos2D(MC_CLIENT.getPlayerBlockPos())); + if (renderBufferHandler != null) renderBufferHandler.update(); + } + + public void serverTick() { + //TODO Update network packet and stuff or state or etc.. + } + public void startRenderer() { + if (renderBufferHandler != null) { + LOGGER.warn("Tried to call startRenderer() on the clientServerLevel {} when renderer is already setup!", level); + return; + } renderFileHandler = new RenderFileHandler(dataFileHandler, this, save.getRenderCacheFolder(level)); tree = new LodQuadTree(Config.Client.Graphics.Quality.lodChunkRenderDistance.get()*16, MC_CLIENT.getPlayerBlockPos().x, MC_CLIENT.getPlayerBlockPos().z, renderFileHandler); @@ -38,20 +56,12 @@ public class DhClientServerLevel implements IClientLevel, IServerLevel { FileScanner.scanFile(save, level, dataFileHandler, renderFileHandler); } - public void clientTick() { - tree.tick(new DhBlockPos2D(MC_CLIENT.getPlayerBlockPos())); - renderBufferHandler.update(); - } - - public void serverTick() { - //TODO Update network packet and stuff or state or etc.. - } - public void startRenderer() { - //TODO - } - @Override public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler) { + if (renderBufferHandler == null) { + LOGGER.error("Tried to call render() on the clientServerLevel {} when renderer has not been started!", level); + return; + } if (renderer == null) { renderer = new a7LodRenderer(this); } @@ -59,8 +69,16 @@ public class DhClientServerLevel implements IClientLevel, IServerLevel { } public void stopRenderer() { + if (renderBufferHandler == null) { + LOGGER.warn("Tried to call stopRenderer() on the clientServerLevel {} when renderer is already closed!", level); + return; + } + renderBufferHandler.close(); + renderBufferHandler = null; + tree = null; //TODO Close the tree renderFileHandler.flushAndSave(); //Ignore the completion feature so that this action is async - //TODO + renderFileHandler.close(); + renderFileHandler = null; } @Override @@ -80,14 +98,13 @@ public class DhClientServerLevel implements IClientLevel, IServerLevel { @Override public CompletableFuture save() { - return renderFileHandler.flushAndSave(); + return renderFileHandler == null ? dataFileHandler.flushAndSave() : renderFileHandler.flushAndSave(); //Note: saving renderFileHandler will also save the dataFileHandler. } @Override public void close() { - renderFileHandler.close(); - //Note: Closing renderFileHandler will also close the dataFileHandler. + dataFileHandler.close(); } @Override diff --git a/src/main/java/com/seibel/lod/core/api/internal/EventApi.java b/src/main/java/com/seibel/lod/core/api/internal/EventApi.java index c13a2cf01..475f98fe2 100644 --- a/src/main/java/com/seibel/lod/core/api/internal/EventApi.java +++ b/src/main/java/com/seibel/lod/core/api/internal/EventApi.java @@ -22,7 +22,7 @@ package com.seibel.lod.core.api.internal; import com.seibel.lod.core.builders.lodBuilding.LodBuilder; import com.seibel.lod.core.builders.worldGeneration.BatchGenerator; import com.seibel.lod.core.config.Config; -import com.seibel.lod.core.enums.EWorldType; +import com.seibel.lod.core.enums.ELevelType; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.objects.DHChunkPos; @@ -129,14 +129,14 @@ public class EventApi if (ENABLE_STACK_DUMP_LOGGING) LOGGER.info( "WorldLoadEvent called here for " - + (world.getWorldType() == EWorldType.ClientWorld ? "clientLevel" : "serverLevel"), + + (world.getLevelType() == ELevelType.ClientLevel ? "clientLevel" : "serverLevel"), new RuntimeException()); // Always ignore ServerWorld event - if (world.getWorldType() == EWorldType.ServerWorld) + if (world.getLevelType() == ELevelType.ServerLevel) return; isCurrentlyOnSinglePlayerServer = MC.hasSinglePlayerServer(); if (!InternalApiShared.isShuttingDown) LOGGER.warn("WorldLoadEvent called on {} while another world is loaded!", - (world.getWorldType() == EWorldType.ClientWorld ? "clientLevel" : "serverLevel")); + (world.getLevelType() == ELevelType.ClientLevel ? "clientLevel" : "serverLevel")); InternalApiShared.isShuttingDown = false; //DataPointUtil.WORLD_HEIGHT = world.getHeight(); LodBuilder.MIN_WORLD_HEIGHT = world.getMinHeight(); // This updates the World height @@ -162,13 +162,13 @@ public class EventApi if (ENABLE_STACK_DUMP_LOGGING) LOGGER.info( "WorldUnloadEvent called here for " - + (world.getWorldType() == EWorldType.ClientWorld ? "clientLevel" : "serverLevel"), + + (world.getLevelType() == ELevelType.ClientLevel ? "clientLevel" : "serverLevel"), new RuntimeException()); // If it's single player, ignore the client side world unload event // Note: using isCurrentlyOnSinglePlayerServer as often API call unload event // AFTER setting MC to not be in a singlePlayerServer - if (isCurrentlyOnSinglePlayerServer && world.getWorldType() == EWorldType.ClientWorld) + if (isCurrentlyOnSinglePlayerServer && world.getLevelType() == ELevelType.ClientLevel) return; // if this isn't done unfinished tasks may be left in the queue diff --git a/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java b/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java index da3defa06..3e2ed43aa 100644 --- a/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java +++ b/src/main/java/com/seibel/lod/core/api/internal/a7/ClientApi.java @@ -179,18 +179,20 @@ public class ClientApi profiler.pop(); } - public void renderLods(ILevelWrapper world, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks) + public void renderLods(ILevelWrapper levelWrapper, Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks) { IProfilerWrapper profiler = MC.getProfiler(); profiler.pop(); // get out of "terrain" profiler.push("DH-RenderLevel"); try { if (!MC.playerExists()) return; - if (world == null) return; - DhWorld DhWorld = SharedApi.currentWorld; - if (DhWorld == null) return; + if (levelWrapper == null) return; + DhWorld dhWorld = SharedApi.currentWorld; + if (dhWorld == null) return; if (!(SharedApi.currentWorld instanceof IClientWorld)) return; - IClientLevel level = (IClientLevel)SharedApi.currentWorld; + //FIXME: Improve class hierarchy of DhWorld, IClientWorld, IServerWorld to fix all this hard casting + IClientLevel level = (IClientLevel) dhWorld.getOrLoadLevel(levelWrapper); + if (level == null) return; //Level is not ready yet. if (prefLoggerEnabled) { level.dumpRamUsage(); diff --git a/src/main/java/com/seibel/lod/core/api/internal/a7/SharedApi.java b/src/main/java/com/seibel/lod/core/api/internal/a7/SharedApi.java index 780aaf67b..ae597bb46 100644 --- a/src/main/java/com/seibel/lod/core/api/internal/a7/SharedApi.java +++ b/src/main/java/com/seibel/lod/core/api/internal/a7/SharedApi.java @@ -1,5 +1,6 @@ package com.seibel.lod.core.api.internal.a7; +import com.seibel.lod.core.a7.Initializer; import com.seibel.lod.core.a7.world.WorldEnvironment; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.a7.world.DhWorld; @@ -10,12 +11,11 @@ public class SharedApi { public static final Logger LOGGER = DhLoggerBuilder.getLogger("DH Events"); public static IMinecraftSharedWrapper MC; public static DhWorld currentWorld; - - //TODO: Should this be in core and able to be accessed by core, or should this be in common, and only effect - // how common calls back into the internal APIs? - public static boolean inDedicatedEnvironment; - public static WorldEnvironment getEnvironment() { return currentWorld==null ? null : currentWorld.environment; } + + public static void init() { + Initializer.init(); + } } diff --git a/src/main/java/com/seibel/lod/core/enums/EWorldType.java b/src/main/java/com/seibel/lod/core/enums/ELevelType.java similarity index 94% rename from src/main/java/com/seibel/lod/core/enums/EWorldType.java rename to src/main/java/com/seibel/lod/core/enums/ELevelType.java index 7b4b954fc..5acdb4a51 100644 --- a/src/main/java/com/seibel/lod/core/enums/EWorldType.java +++ b/src/main/java/com/seibel/lod/core/enums/ELevelType.java @@ -25,9 +25,9 @@ package com.seibel.lod.core.enums; * @author James Seibel * @version 11-12-2021 */ -public enum EWorldType +public enum ELevelType { - ServerWorld, - ClientWorld, + ServerLevel, + ClientLevel, Unknown } diff --git a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/SingletonHandler.java b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/SingletonHandler.java index 3ef26b55b..1a12305d2 100644 --- a/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/SingletonHandler.java +++ b/src/main/java/com/seibel/lod/core/handlers/dependencyInjection/SingletonHandler.java @@ -70,8 +70,8 @@ public class SingletonHandler return foundObject; } - - + + /** * Should only be called after all Binds have been done. * Calls the delayedSetup method for each dependency.

diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java index 3e69e4711..e17eb437c 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/minecraft/IMinecraftSharedWrapper.java @@ -6,7 +6,8 @@ import java.io.File; //TODO: Maybe have IMCClientWrapper & IMCDedicatedWrapper extend this interface??? public interface IMinecraftSharedWrapper extends IBindable { - boolean isServerJar(); + boolean isDedicatedServer(); + File getInstallationDirectory(); } diff --git a/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/ILevelWrapper.java b/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/ILevelWrapper.java index c5bb15896..754023868 100644 --- a/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/ILevelWrapper.java +++ b/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/ILevelWrapper.java @@ -21,7 +21,7 @@ package com.seibel.lod.core.wrapperInterfaces.world; import java.io.File; -import com.seibel.lod.core.enums.EWorldType; +import com.seibel.lod.core.enums.ELevelType; import com.seibel.lod.core.handlers.dependencyInjection.IBindable; import com.seibel.lod.core.objects.DHChunkPos; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; @@ -36,7 +36,7 @@ public interface ILevelWrapper extends IBindable { IDimensionTypeWrapper getDimensionType(); - EWorldType getWorldType(); + ELevelType getLevelType(); int getBlockLight(int x, int y, int z);