From ea41fbc6642c52b1a0829e3476f0ed3614e1786c Mon Sep 17 00:00:00 2001 From: James Seibel Date: Sat, 25 Feb 2023 17:17:27 -0600 Subject: [PATCH] make DhClientServerLevel extends DhClientLevel --- .../lod/core/api/internal/ServerApi.java | 2 +- .../file/structure/AbstractSaveStructure.java | 4 +- .../structure/ClientOnlySaveStructure.java | 4 +- .../file/structure/LocalSaveStructure.java | 10 +- .../seibel/lod/core/level/DhClientLevel.java | 182 ++++++++----- .../lod/core/level/DhClientServerLevel.java | 247 +++--------------- .../seibel/lod/core/level/DhServerLevel.java | 4 +- .../seibel/lod/core/level/IDhClientLevel.java | 1 - .../core/level/states/ClientRenderState.java | 18 +- .../seibel/lod/core/util/FileScanUtil.java | 6 +- .../lod/core/world/DhClientServerWorld.java | 4 +- .../seibel/lod/core/world/DhClientWorld.java | 4 +- .../seibel/lod/core/world/DhServerWorld.java | 2 +- .../world/IServerLevelWrapper.java | 2 +- 14 files changed, 177 insertions(+), 313 deletions(-) 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 04b5580af..5d60db19a 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 @@ -104,7 +104,7 @@ public class ServerApi { if (ENABLE_EVENT_LOGGING) { - LOGGER.info("Server Level {} loading", level); + LOGGER.info("Server Level "+level+" loading"); } AbstractDhWorld serverWorld = SharedApi.getAbstractDhWorld(); diff --git a/core/src/main/java/com/seibel/lod/core/file/structure/AbstractSaveStructure.java b/core/src/main/java/com/seibel/lod/core/file/structure/AbstractSaveStructure.java index 8818db5b2..f06f0be4d 100644 --- a/core/src/main/java/com/seibel/lod/core/file/structure/AbstractSaveStructure.java +++ b/core/src/main/java/com/seibel/lod/core/file/structure/AbstractSaveStructure.java @@ -25,12 +25,12 @@ public abstract class AbstractSaveStructure implements AutoCloseable * This will always return a folder, however that folder may not be the best match * if multiverse support is enabled. * */ - public abstract File tryGetOrCreateLevelFolder(ILevelWrapper wrapper); + public abstract File getLevelFolder(ILevelWrapper wrapper); /** Will return null if no parent folder exists for the given {@link ILevelWrapper}.*/ public abstract File getRenderCacheFolder(ILevelWrapper world); /** Will return null if no parent folder exists for the given {@link ILevelWrapper}.*/ - public abstract File getDataFolder(ILevelWrapper world); + public abstract File getFullDataFolder(ILevelWrapper world); } diff --git a/core/src/main/java/com/seibel/lod/core/file/structure/ClientOnlySaveStructure.java b/core/src/main/java/com/seibel/lod/core/file/structure/ClientOnlySaveStructure.java index e855a6ba4..06be792bc 100644 --- a/core/src/main/java/com/seibel/lod/core/file/structure/ClientOnlySaveStructure.java +++ b/core/src/main/java/com/seibel/lod/core/file/structure/ClientOnlySaveStructure.java @@ -54,7 +54,7 @@ public class ClientOnlySaveStructure extends AbstractSaveStructure //================// @Override - public File tryGetOrCreateLevelFolder(ILevelWrapper level) + public File getLevelFolder(ILevelWrapper level) { return this.levelToFileMap.computeIfAbsent(level, (newLevel) -> { @@ -139,7 +139,7 @@ public class ClientOnlySaveStructure extends AbstractSaveStructure } @Override - public File getDataFolder(ILevelWrapper level) + public File getFullDataFolder(ILevelWrapper level) { File levelFolder = this.levelToFileMap.get(level); if (levelFolder == null) diff --git a/core/src/main/java/com/seibel/lod/core/file/structure/LocalSaveStructure.java b/core/src/main/java/com/seibel/lod/core/file/structure/LocalSaveStructure.java index 165c5b247..3510ba489 100644 --- a/core/src/main/java/com/seibel/lod/core/file/structure/LocalSaveStructure.java +++ b/core/src/main/java/com/seibel/lod/core/file/structure/LocalSaveStructure.java @@ -27,7 +27,7 @@ public class LocalSaveStructure extends AbstractSaveStructure //================// @Override - public File tryGetOrCreateLevelFolder(ILevelWrapper wrapper) + public File getLevelFolder(ILevelWrapper wrapper) { IServerLevelWrapper serverSide = (IServerLevelWrapper) wrapper; this.debugPath = new File(serverSide.getSaveFolder(), "Distant_Horizons"); @@ -43,11 +43,11 @@ public class LocalSaveStructure extends AbstractSaveStructure } @Override - public File getDataFolder(ILevelWrapper level) + public File getFullDataFolder(ILevelWrapper level) { - IServerLevelWrapper serverSide = (IServerLevelWrapper) level; - this.debugPath = new File(serverSide.getSaveFolder(), SERVER_FOLDER_NAME); - return new File(new File(serverSide.getSaveFolder(), SERVER_FOLDER_NAME), DATA_FOLDER); + IServerLevelWrapper serverLevelWrapper = (IServerLevelWrapper) level; + this.debugPath = new File(serverLevelWrapper.getSaveFolder(), SERVER_FOLDER_NAME); + return new File(new File(serverLevelWrapper.getSaveFolder(), SERVER_FOLDER_NAME), DATA_FOLDER); } diff --git a/core/src/main/java/com/seibel/lod/core/level/DhClientLevel.java b/core/src/main/java/com/seibel/lod/core/level/DhClientLevel.java index fa7b3e10c..9362a4712 100644 --- a/core/src/main/java/com/seibel/lod/core/level/DhClientLevel.java +++ b/core/src/main/java/com/seibel/lod/core/level/DhClientLevel.java @@ -3,7 +3,9 @@ package com.seibel.lod.core.level; import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource; import com.seibel.lod.core.dataObjects.transformers.ChunkToLodBuilder; +import com.seibel.lod.core.file.fullDatafile.FullDataFileHandler; import com.seibel.lod.core.file.fullDatafile.IFullDataSourceProvider; +import com.seibel.lod.core.file.structure.AbstractSaveStructure; import com.seibel.lod.core.level.states.ClientRenderState; import com.seibel.lod.core.logging.f3.F3Screen; import com.seibel.lod.core.pos.DhLodPos; @@ -11,7 +13,6 @@ import com.seibel.lod.core.pos.DhSectionPos; import com.seibel.lod.core.util.FileScanUtil; import com.seibel.lod.core.file.fullDatafile.RemoteFullDataFileHandler; import com.seibel.lod.core.pos.DhBlockPos2D; -import com.seibel.lod.core.file.structure.ClientOnlySaveStructure; import com.seibel.lod.core.config.Config; import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.logging.DhLoggerBuilder; @@ -35,60 +36,55 @@ public class DhClientLevel implements IDhClientLevel private static final Logger LOGGER = DhLoggerBuilder.getLogger(); private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - public final ClientOnlySaveStructure saveStructure; - public final RemoteFullDataFileHandler fullDataFileHandler; + public final IClientLevelWrapper clientLevelWrapper; + + public final AbstractSaveStructure saveStructure; public final ChunkToLodBuilder chunkToLodBuilder; - public final IClientLevelWrapper clientLevel; - public F3Screen.NestedMessage f3Message; + public final F3Screen.NestedMessage f3Message; + + public FullDataFileHandler fullDataFileHandler; public final AtomicReference ClientRenderStateRef = new AtomicReference<>(); - public DhClientLevel(ClientOnlySaveStructure saveStructure, IClientLevelWrapper clientLevel) + //=============// + // constructor // + //=============// + + public DhClientLevel(AbstractSaveStructure saveStructure, IClientLevelWrapper clientLevelWrapper) { - this.clientLevel = clientLevel; + this(saveStructure, clientLevelWrapper, null); + + this.fullDataFileHandler = new RemoteFullDataFileHandler(this, this.saveStructure.getFullDataFolder(this.clientLevelWrapper)); + FileScanUtil.scanFiles(saveStructure, this.clientLevelWrapper, this.fullDataFileHandler, null); + } + public DhClientLevel(AbstractSaveStructure saveStructure, IClientLevelWrapper clientLevelWrapper, FullDataFileHandler fullDataFileHandler) + { + this.clientLevelWrapper = clientLevelWrapper; this.saveStructure = saveStructure; - saveStructure.getDataFolder(clientLevel).mkdirs(); - saveStructure.getRenderCacheFolder(clientLevel).mkdirs(); + if (this.saveStructure.getFullDataFolder(this.clientLevelWrapper).mkdirs()) + { + LOGGER.warn("unable to create full data folder."); + } + if (this.saveStructure.getRenderCacheFolder(this.clientLevelWrapper).mkdirs()) + { + LOGGER.warn("unable to create cache folder."); + } - this.fullDataFileHandler = new RemoteFullDataFileHandler(this, saveStructure.getDataFolder(clientLevel)); - FileScanUtil.scanFiles(saveStructure, clientLevel, this.fullDataFileHandler, null); + // TODO not a great way of handling this, but it works for now + if (fullDataFileHandler != null) + { + this.fullDataFileHandler = fullDataFileHandler; + FileScanUtil.scanFiles(saveStructure, this.clientLevelWrapper, this.fullDataFileHandler, null); + } this.f3Message = new F3Screen.NestedMessage(this::f3Log); this.chunkToLodBuilder = new ChunkToLodBuilder(); - LOGGER.info("Started DHLevel for "+clientLevel+" with saves at "+saveStructure); - } - - - - //=======================// - // misc helper functions // - //=======================// - - /** Returns what should be displayed in Minecraft's F3 debug menu */ - private String[] f3Log() - { - ClientRenderState rs = this.ClientRenderStateRef.get(); - if (rs == null) - { - return new String[] { LodUtil.formatLog("level @ {}: Inactive", this.clientLevel.getDimensionType().getDimensionName()) }; - } - else - { - return new String[] { - LodUtil.formatLog("level @ {}: Active", this.clientLevel.getDimensionType().getDimensionName()) - }; - } - } - - @Override - public void dumpRamUsage() - { - //TODO + LOGGER.info("Started DHLevel for "+this.clientLevelWrapper+" with saves at "+this.saveStructure); } @@ -99,18 +95,31 @@ public class DhClientLevel implements IDhClientLevel @Override public void clientTick() + { + if (!this.baseClientTick()) + { + return; + } + + this.chunkToLodBuilder.tick(); + } + /** + * Includes logic used by both {@link DhClientServerLevel} and {@link DhClientServerLevel} + * @return whether the tick method completed + */ + protected boolean baseClientTick() { ClientRenderState clientRenderState = this.ClientRenderStateRef.get(); if (clientRenderState == null) { - return; + return false; } if (clientRenderState.quadtree.blockRenderDistance != Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH) { if (!this.ClientRenderStateRef.compareAndSet(clientRenderState, null)) { - return; //If we fail, we'll just wait for the next tick + return false; //If we fail, we'll just wait for the next tick } IClientLevelWrapper levelWrapper = clientRenderState.clientLevel; @@ -121,14 +130,14 @@ public class DhClientLevel implements IDhClientLevel //FIXME: How to handle this? LOGGER.warn("Failed to set render state due to concurrency after changing view distance"); clientRenderState.closeAsync(); - return; + return false; } } clientRenderState.quadtree.tick(new DhBlockPos2D(MC_CLIENT.getPlayerBlockPos())); clientRenderState.renderer.bufferHandler.update(); - this.chunkToLodBuilder.tick(); + return true; } @@ -140,11 +149,21 @@ public class DhClientLevel implements IDhClientLevel public void startRenderer(IClientLevelWrapper clientLevel) { LOGGER.info("Starting renderer for "+this); - ClientRenderState ClientRenderState = new ClientRenderState(this, clientLevel); + this.setAndStartRenderer(); + } + /** @return if the {@link ClientRenderState} was successfully swapped */ + protected boolean setAndStartRenderer() + { + ClientRenderState ClientRenderState = new ClientRenderState(this, this.clientLevelWrapper); if (!this.ClientRenderStateRef.compareAndSet(null, ClientRenderState)) { LOGGER.warn("Failed to start renderer due to concurrency"); ClientRenderState.closeAsync(); + return false; + } + else + { + return true; } } @@ -180,7 +199,6 @@ public class DhClientLevel implements IDhClientLevel } } ClientRenderState.closeAsync().join(); //TODO: Make it async. - } @@ -190,31 +208,15 @@ public class DhClientLevel implements IDhClientLevel //================// @Override - public int computeBaseColor(DhBlockPos pos, IBiomeWrapper biome, IBlockStateWrapper block) - { - IClientLevelWrapper clientLevel = this.getClientLevelWrapper(); - if (clientLevel == null) - { - return 0; - } - else - { - return clientLevel.computeBaseColor(pos, biome, block); - } - } + public int computeBaseColor(DhBlockPos pos, IBiomeWrapper biome, IBlockStateWrapper block) { return this.clientLevelWrapper.computeBaseColor(pos, biome, block); } @Override - public IClientLevelWrapper getClientLevelWrapper() - { - ClientRenderState ClientRenderState = this.ClientRenderStateRef.get(); - return ClientRenderState == null ? null : ClientRenderState.clientLevel; - } + public IClientLevelWrapper getClientLevelWrapper() { return this.clientLevelWrapper; } + @Override + public ILevelWrapper getLevelWrapper() { return this.clientLevelWrapper; } @Override - public ILevelWrapper getLevelWrapper() { return this.clientLevel; } - - @Override - public int getMinY() { return this.clientLevel.getMinHeight(); } + public int getMinY() { return this.clientLevelWrapper.getMinHeight(); } @@ -263,25 +265,62 @@ public class DhClientLevel implements IDhClientLevel @Override public void close() + { + this.baseClose(); + LOGGER.info("Closed "+DhClientLevel.class.getSimpleName()+" for "+this.clientLevelWrapper); + } + /** Includes logic used by both {@link DhClientServerLevel} and {@link DhClientServerLevel} */ + protected void baseClose() { ClientRenderState ClientRenderState = this.ClientRenderStateRef.get(); if (ClientRenderState != null) { + // TODO does this have to be in a while loop, if so why? while (!this.ClientRenderStateRef.compareAndSet(ClientRenderState, null)) { ClientRenderState = this.ClientRenderStateRef.get(); if (ClientRenderState == null) { - return; + break; } } - ClientRenderState.closeAsync().join(); //TODO: Make this async. + + if (ClientRenderState != null) + { + ClientRenderState.closeAsync().join(); //TODO: Make this async. + } } - - LOGGER.info("Closed DHLevel for "+this.clientLevel); } + + + //=======================// + // misc helper functions // + //=======================// + + /** Returns what should be displayed in Minecraft's F3 debug menu */ + protected String[] f3Log() + { + ClientRenderState renderState = this.ClientRenderStateRef.get(); + if (renderState == null) + { + return new String[] { LodUtil.formatLog("level @ {}: Inactive", this.clientLevelWrapper.getDimensionType().getDimensionName()) }; + } + else + { + return new String[] { + LodUtil.formatLog("level @ {}: Active", this.clientLevelWrapper.getDimensionType().getDimensionName()) + }; + } + } + + @Override + public void dumpRamUsage() + { + //TODO + } + @Override public IFullDataSourceProvider getFileHandler() { return this.fullDataFileHandler; } @@ -296,4 +335,5 @@ public class DhClientLevel implements IDhClientLevel } + } 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 53ee8ff90..1551b2ae6 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 @@ -3,30 +3,19 @@ package com.seibel.lod.core.level; import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGenerator; import com.seibel.lod.core.DependencyInjection.WorldGeneratorInjector; import com.seibel.lod.core.config.AppliedConfigState; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource; -import com.seibel.lod.core.dataObjects.transformers.ChunkToLodBuilder; -import com.seibel.lod.core.file.fullDatafile.IFullDataSourceProvider; +import com.seibel.lod.core.dependencyInjection.SingletonInjector; +import com.seibel.lod.core.file.fullDatafile.FullDataFileHandler; +import com.seibel.lod.core.file.structure.AbstractSaveStructure; import com.seibel.lod.core.generation.BatchGenerator; import com.seibel.lod.core.generation.WorldGenerationQueue; -import com.seibel.lod.core.level.states.ClientRenderState; -import com.seibel.lod.core.pos.DhLodPos; -import com.seibel.lod.core.pos.DhSectionPos; import com.seibel.lod.core.file.fullDatafile.GeneratedFullDataFileHandler; import com.seibel.lod.core.util.FileScanUtil; import com.seibel.lod.core.pos.DhBlockPos2D; -import com.seibel.lod.core.file.structure.LocalSaveStructure; import com.seibel.lod.core.config.Config; -import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.logging.DhLoggerBuilder; -import com.seibel.lod.core.logging.f3.F3Screen; import com.seibel.lod.core.pos.DhBlockPos; -import com.seibel.lod.core.util.math.Mat4f; -import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper; -import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; @@ -37,69 +26,38 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; /** The level used on a singleplayer world */ -public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel +public class DhClientServerLevel extends DhClientLevel implements IDhClientLevel, IDhServerLevel { private static final Logger LOGGER = DhLoggerBuilder.getLogger(); private static final IMinecraftClientWrapper MC_CLIENT = SingletonInjector.INSTANCE.get(IMinecraftClientWrapper.class); - public final LocalSaveStructure saveStructure; - public final GeneratedFullDataFileHandler fullDataFileHandler; - public final ChunkToLodBuilder chunkToLodBuilder; - public final IServerLevelWrapper serverLevel; - private final AppliedConfigState worldGeneratorEnabledConfig; - public F3Screen.NestedMessage f3Message; + public final IServerLevelWrapper serverLevelWrapper; - private final AtomicReference ClientRenderStateRef = new AtomicReference<>(); + /** + * This is separate from {@link DhClientLevel#fullDataFileHandler} and included + * since the base {@link FullDataFileHandler} doesn't support world generation + */ + public final GeneratedFullDataFileHandler generatedFullDataFileHandler; + + private final AppliedConfigState worldGeneratorEnabledConfig; private final AtomicReference worldGenStateRef = new AtomicReference<>(); - public DhClientServerLevel(LocalSaveStructure saveStructure, IServerLevelWrapper serverLevel) + public DhClientServerLevel(AbstractSaveStructure saveStructure, IServerLevelWrapper serverLevelWrapper) { - this.serverLevel = serverLevel; + super(saveStructure, serverLevelWrapper.tryGetClientLevelWrapper(), null); - this.saveStructure = saveStructure; - saveStructure.getDataFolder(serverLevel).mkdirs(); - saveStructure.getRenderCacheFolder(serverLevel).mkdirs(); + this.serverLevelWrapper = serverLevelWrapper; - this.fullDataFileHandler = new GeneratedFullDataFileHandler(this, saveStructure.getDataFolder(serverLevel)); - FileScanUtil.scanFiles(saveStructure, this.serverLevel, this.fullDataFileHandler, null); - - this.f3Message = new F3Screen.NestedMessage(this::f3Log); - this.chunkToLodBuilder = new ChunkToLodBuilder(); + this.generatedFullDataFileHandler = new GeneratedFullDataFileHandler(this, saveStructure.getFullDataFolder(serverLevelWrapper)); + this.fullDataFileHandler = this.generatedFullDataFileHandler; + FileScanUtil.scanFiles(saveStructure, this.serverLevelWrapper, this.fullDataFileHandler, null); this.worldGeneratorEnabledConfig = new AppliedConfigState<>(Config.Client.WorldGenerator.enableDistantGeneration); - LOGGER.info("Started DHLevel for "+serverLevel+" with saves at "+saveStructure); - } - - - - //=======================// - // misc helper functions // - //=======================// - - /** Returns what should be displayed in Minecraft's F3 debug menu */ - private String[] f3Log() - { - ClientRenderState rs = this.ClientRenderStateRef.get(); - if (rs == null) - { - return new String[] { LodUtil.formatLog("level @ {}: Inactive", this.serverLevel.getDimensionType().getDimensionName()) }; - } - else - { - return new String[] { - LodUtil.formatLog("level @ {}: Active", this.serverLevel.getDimensionType().getDimensionName()) - }; - } - } - - @Override - public void dumpRamUsage() - { - //TODO + LOGGER.info("Started "+DhClientServerLevel.class.getSimpleName()+" for "+ serverLevelWrapper +" with saves at "+saveStructure); } @@ -111,33 +69,12 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel @Override public void clientTick() { - ClientRenderState clientRenderState = this.ClientRenderStateRef.get(); - if (clientRenderState == null) + if (!super.baseClientTick()) { return; } - if (clientRenderState.quadtree.blockRenderDistance != Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH) - { - if (!this.ClientRenderStateRef.compareAndSet(clientRenderState, null)) - { - return; //If we fail, we'll just wait for the next tick - } - - IClientLevelWrapper levelWrapper = clientRenderState.clientLevel; - clientRenderState.closeAsync().join(); //TODO: Make it async. - clientRenderState = new ClientRenderState(this, levelWrapper); - if (!this.ClientRenderStateRef.compareAndSet(null, clientRenderState)) - { - //FIXME: How to handle this? - LOGGER.warn("Failed to set render state due to concurrency after changing view distance"); - clientRenderState.closeAsync(); - return; - } - } - - clientRenderState.quadtree.tick(new DhBlockPos2D(MC_CLIENT.getPlayerBlockPos())); - clientRenderState.renderer.bufferHandler.update(); + // additional tick logic can be added if necessary } @Override @@ -195,13 +132,7 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel public void startRenderer(IClientLevelWrapper clientLevel) { LOGGER.info("Starting renderer for "+this); - ClientRenderState ClientRenderState = new ClientRenderState(this, clientLevel); - if (!this.ClientRenderStateRef.compareAndSet(null, ClientRenderState)) - { - LOGGER.warn("Failed to start renderer due to concurrency"); - ClientRenderState.closeAsync(); - } - else + if (super.setAndStartRenderer()) { this.worldGeneratorEnabledConfig.pollNewValue(); if (this.worldGeneratorEnabledConfig.get() && this.worldGenStateRef.get() == null) @@ -217,38 +148,9 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel } } - @Override - public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler) - { - ClientRenderState ClientRenderState = this.ClientRenderStateRef.get(); - if (ClientRenderState == null) - { - LOGGER.error("Tried to call render() on "+this+" when renderer has not been started!"); - return; - } - ClientRenderState.renderer.drawLODs(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler); - } - public void stopRenderer() { - LOGGER.info("Stopping renderer for "+this); - ClientRenderState ClientRenderState = this.ClientRenderStateRef.get(); - if (ClientRenderState == null) - { - LOGGER.warn("Tried to stop renderer for "+this+" when it was not started!"); - return; - } - - // stop the render state - while (!this.ClientRenderStateRef.compareAndSet(ClientRenderState, null)) // TODO why is there a while loop here? - { - ClientRenderState = this.ClientRenderStateRef.get(); - if (ClientRenderState == null) - { - return; - } - } - ClientRenderState.closeAsync().join(); //TODO: Make it async. + super.stopRenderer(); // stop the world generator WorldGenState worldGenState = this.worldGenStateRef.get(); @@ -272,7 +174,7 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel // level handling // //================// - @Override //FIXME // why is this labeled "fixme"? + @Override //FIXME this can fail if the clientLevel hasn't been created yet public int computeBaseColor(DhBlockPos pos, IBiomeWrapper biome, IBlockStateWrapper block) { IClientLevelWrapper clientLevel = this.getClientLevelWrapper(); @@ -287,19 +189,12 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel } @Override - public IClientLevelWrapper getClientLevelWrapper() - { - ClientRenderState ClientRenderState = this.ClientRenderStateRef.get(); - return ClientRenderState == null ? null : ClientRenderState.clientLevel; - } + public IServerLevelWrapper getServerLevelWrapper() { return this.serverLevelWrapper; } @Override - public IServerLevelWrapper getServerLevelWrapper() { return this.serverLevel; } + public ILevelWrapper getLevelWrapper() { return this.serverLevelWrapper; } @Override - public ILevelWrapper getLevelWrapper() { return this.serverLevel; } - - @Override - public int getMinY() { return this.serverLevel.getMinHeight(); } + public int getMinY() { return this.serverLevelWrapper.getMinHeight(); } @@ -307,89 +202,31 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel // data handling // //===============// - @Override - public void updateChunkAsync(IChunkWrapper chunk) - { - CompletableFuture future = this.chunkToLodBuilder.tryGenerateData(chunk); - if (future != null) - { - future.thenAccept(this::saveWrites); - } - } - private void saveWrites(ChunkSizedFullDataSource data) - { - ClientRenderState ClientRenderState = this.ClientRenderStateRef.get(); - DhLodPos pos = data.getBBoxLodPos().convertToDetailLevel(FullDataSource.SECTION_SIZE_OFFSET); - if (ClientRenderState != null) - { - ClientRenderState.renderSourceFileHandler.write(new DhSectionPos(pos.detailLevel, pos.x, pos.z), data); - } - else - { - this.fullDataFileHandler.write(new DhSectionPos(pos.detailLevel, pos.x, pos.z), data); - } - } - - @Override - public CompletableFuture saveAsync() - { - ClientRenderState ClientRenderState = this.ClientRenderStateRef.get(); - if (ClientRenderState != null) - { - return ClientRenderState.renderSourceFileHandler.flushAndSave().thenCombine(this.fullDataFileHandler.flushAndSave(), (voidA, voidB) -> null); - } - else - { - return this.fullDataFileHandler.flushAndSave(); - } - } - @Override public void close() { - ClientRenderState ClientRenderState = this.ClientRenderStateRef.get(); - if (ClientRenderState != null) + super.baseClose(); + + WorldGenState worldGenState = this.worldGenStateRef.get(); + if (worldGenState != null) { - while (!this.ClientRenderStateRef.compareAndSet(ClientRenderState, null)) + // TODO does this have to be in a while loop, if so why? + while (!this.worldGenStateRef.compareAndSet(worldGenState, null)) { - ClientRenderState = this.ClientRenderStateRef.get(); - if (ClientRenderState == null) + worldGenState = this.worldGenStateRef.get(); + if (worldGenState == null) { - return; + break; } } - ClientRenderState.closeAsync().join(); //TODO: Make this async. - } - - WorldGenState wgs = this.worldGenStateRef.get(); - if (wgs != null) - { - while (!this.worldGenStateRef.compareAndSet(wgs, null)) + + if (worldGenState != null) { - wgs = this.worldGenStateRef.get(); - if (wgs == null) - { - return; - } + worldGenState.closeAsync(true).join(); //TODO: Make it async. } - wgs.closeAsync(true).join(); //TODO: Make it async. } - LOGGER.info("Closed "+this); - } - - - @Override - public IFullDataSourceProvider getFileHandler() { return this.fullDataFileHandler; } - - @Override - public void clearRenderDataCache() - { - ClientRenderState ClientRenderState = this.ClientRenderStateRef.get(); - if (ClientRenderState != null && ClientRenderState.quadtree != null) - { - ClientRenderState.quadtree.clearRenderDataCache(); - } + LOGGER.info("Closed "+DhClientLevel.class.getSimpleName()+" for "+this.serverLevelWrapper); } @@ -420,14 +257,14 @@ public class DhClientServerLevel implements IDhClientLevel, IDhServerLevel this.chunkGenerator = worldGenerator; this.worldGenerationQueue = new WorldGenerationQueue(this.chunkGenerator); - DhClientServerLevel.this.fullDataFileHandler.setGenerationQueue(this.worldGenerationQueue); + DhClientServerLevel.this.generatedFullDataFileHandler.setGenerationQueue(this.worldGenerationQueue); } CompletableFuture closeAsync(boolean doInterrupt) { - DhClientServerLevel.this.fullDataFileHandler.clearGenerationQueue(); + DhClientServerLevel.this.generatedFullDataFileHandler.clearGenerationQueue(); return this.worldGenerationQueue.startClosing(true, doInterrupt) .exceptionally(ex -> { diff --git a/core/src/main/java/com/seibel/lod/core/level/DhServerLevel.java b/core/src/main/java/com/seibel/lod/core/level/DhServerLevel.java index 1173f06d8..6a49f6256 100644 --- a/core/src/main/java/com/seibel/lod/core/level/DhServerLevel.java +++ b/core/src/main/java/com/seibel/lod/core/level/DhServerLevel.java @@ -24,8 +24,8 @@ public class DhServerLevel implements IDhServerLevel { this.save = save; this.level = level; - save.getDataFolder(level).mkdirs(); - this.dataFileHandler = new FullDataFileHandler(this, save.getDataFolder(level)); //FIXME: GenerationQueue + save.getFullDataFolder(level).mkdirs(); + this.dataFileHandler = new FullDataFileHandler(this, save.getFullDataFolder(level)); //FIXME: GenerationQueue FileScanUtil.scanFiles(save, level, this.dataFileHandler, null); LOGGER.info("Started DHLevel for {} with saves at {}", level, save); } diff --git a/core/src/main/java/com/seibel/lod/core/level/IDhClientLevel.java b/core/src/main/java/com/seibel/lod/core/level/IDhClientLevel.java index 43672f116..a9a54a11e 100644 --- a/core/src/main/java/com/seibel/lod/core/level/IDhClientLevel.java +++ b/core/src/main/java/com/seibel/lod/core/level/IDhClientLevel.java @@ -9,7 +9,6 @@ import com.seibel.lod.core.wrapperInterfaces.world.IClientLevelWrapper; public interface IDhClientLevel extends IDhLevel { - /** Return whether the level needs to be reloaded */ void clientTick(); void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler); diff --git a/core/src/main/java/com/seibel/lod/core/level/states/ClientRenderState.java b/core/src/main/java/com/seibel/lod/core/level/states/ClientRenderState.java index 3a921fb82..9026dbe7c 100644 --- a/core/src/main/java/com/seibel/lod/core/level/states/ClientRenderState.java +++ b/core/src/main/java/com/seibel/lod/core/level/states/ClientRenderState.java @@ -28,29 +28,17 @@ public class ClientRenderState public final LodRenderer renderer; - // TODO combine - public ClientRenderState(DhClientServerLevel parent, IClientLevelWrapper clientLevel) - { - this.clientLevel = clientLevel; - this.renderSourceFileHandler = new RenderSourceFileHandler(parent.fullDataFileHandler, parent, parent.saveStructure.getRenderCacheFolder(parent.serverLevel)); - - this.quadtree = new LodQuadTree(parent, Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH, - MC_CLIENT.getPlayerBlockPos().x, MC_CLIENT.getPlayerBlockPos().z, this.renderSourceFileHandler); - - RenderBufferHandler renderBufferHandler = new RenderBufferHandler(this.quadtree); - FileScanUtil.scanFiles(parent.saveStructure, parent.serverLevel, null, this.renderSourceFileHandler); - this.renderer = new LodRenderer(renderBufferHandler); - } + public ClientRenderState(DhClientLevel parent, IClientLevelWrapper clientLevel) { this.clientLevel = clientLevel; - this.renderSourceFileHandler = new RenderSourceFileHandler(parent.fullDataFileHandler, parent, parent.saveStructure.getRenderCacheFolder(parent.clientLevel)); + this.renderSourceFileHandler = new RenderSourceFileHandler(parent.fullDataFileHandler, parent, parent.saveStructure.getRenderCacheFolder(parent.getLevelWrapper())); this.quadtree = new LodQuadTree(parent, Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * LodUtil.CHUNK_WIDTH, MC_CLIENT.getPlayerBlockPos().x, MC_CLIENT.getPlayerBlockPos().z, this.renderSourceFileHandler); RenderBufferHandler renderBufferHandler = new RenderBufferHandler(this.quadtree); - FileScanUtil.scanFiles(parent.saveStructure, parent.clientLevel, null, this.renderSourceFileHandler); + FileScanUtil.scanFiles(parent.saveStructure, parent.getLevelWrapper(), null, this.renderSourceFileHandler); this.renderer = new LodRenderer(renderBufferHandler); } diff --git a/core/src/main/java/com/seibel/lod/core/util/FileScanUtil.java b/core/src/main/java/com/seibel/lod/core/util/FileScanUtil.java index 94f7ba357..3dbe46909 100644 --- a/core/src/main/java/com/seibel/lod/core/util/FileScanUtil.java +++ b/core/src/main/java/com/seibel/lod/core/util/FileScanUtil.java @@ -26,7 +26,7 @@ public class FileScanUtil { if (dataSourceProvider != null) { - try (Stream pathStream = Files.walk(saveStructure.getDataFolder(levelWrapper).toPath(), MAX_SCAN_DEPTH)) + try (Stream pathStream = Files.walk(saveStructure.getFullDataFolder(levelWrapper).toPath(), MAX_SCAN_DEPTH)) { dataSourceProvider.addScannedFile(pathStream.filter( path -> path.toFile().getName().endsWith(LOD_FILE_POSTFIX) && path.toFile().isFile() @@ -35,7 +35,7 @@ public class FileScanUtil } catch (Exception e) { - LOGGER.error("Failed to scan and collect data files for {} in {}", levelWrapper, saveStructure, e); + LOGGER.error("Failed to scan and collect full data files for "+levelWrapper+" in "+saveStructure, e); } } @@ -50,7 +50,7 @@ public class FileScanUtil } catch (Exception e) { - LOGGER.error("Failed to scan and collect data files for {} in {}", levelWrapper, saveStructure, e); + LOGGER.error("Failed to scan and collect cache files for "+levelWrapper+" in "+saveStructure, e); } } } 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 b26da0712..a46d2fb7d 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 @@ -50,7 +50,7 @@ public class DhClientServerWorld extends AbstractDhWorld implements IDhClientWor { return this.levelObjMap.computeIfAbsent(wrapper, (levelWrapper) -> { - File levelFile = this.saveStructure.tryGetOrCreateLevelFolder(levelWrapper); + File levelFile = this.saveStructure.getLevelFolder(levelWrapper); LodUtil.assertTrue(levelFile != null); DhClientServerLevel level = new DhClientServerLevel(this.saveStructure, (IServerLevelWrapper) levelWrapper); this.dhLevels.add(level); @@ -132,7 +132,7 @@ public class DhClientServerWorld extends AbstractDhWorld implements IDhClientWor for (DhClientServerLevel level : this.dhLevels) { - LOGGER.info("Unloading level " + level.serverLevel.getDimensionType().getDimensionName()); + LOGGER.info("Unloading level " + level.serverLevelWrapper.getDimensionType().getDimensionName()); level.close(); } 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 1ed5a10df..ea9d21ee3 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 @@ -46,7 +46,7 @@ public class DhClientWorld extends AbstractDhWorld implements IDhClientWorld return this.levels.computeIfAbsent((IClientLevelWrapper) wrapper, (clientLevelWrapper) -> { - File file = this.saveStructure.tryGetOrCreateLevelFolder(wrapper); + File file = this.saveStructure.getLevelFolder(wrapper); if (file == null) { return null; @@ -121,7 +121,7 @@ public class DhClientWorld extends AbstractDhWorld implements IDhClientWorld this.saveAndFlush().join(); for (DhClientLevel level : this.levels.values()) { - LOGGER.info("Unloading level " + level.clientLevel.getDimensionType().getDimensionName()); + LOGGER.info("Unloading level " + level.clientLevelWrapper.getDimensionType().getDimensionName()); level.close(); } 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 64194a8f9..8aab67267 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 @@ -40,7 +40,7 @@ public class DhServerWorld extends AbstractDhWorld implements IDhServerWorld return this.levels.computeIfAbsent((IServerLevelWrapper) wrapper, (w) -> { - File levelFile = this.saveStructure.tryGetOrCreateLevelFolder(wrapper); + File levelFile = this.saveStructure.getLevelFolder(wrapper); LodUtil.assertTrue(levelFile != null); return new DhServerLevel(this.saveStructure, w); }); diff --git a/core/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/IServerLevelWrapper.java b/core/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/IServerLevelWrapper.java index 9c09d0290..5634624ff 100644 --- a/core/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/IServerLevelWrapper.java +++ b/core/src/main/java/com/seibel/lod/core/wrapperInterfaces/world/IServerLevelWrapper.java @@ -5,7 +5,7 @@ import java.io.File; public interface IServerLevelWrapper extends ILevelWrapper { @Nullable - IClientLevelWrapper tryGetClientSideWrapper(); + IClientLevelWrapper tryGetClientLevelWrapper(); File getSaveFolder(); }