From b780a975ee124fc366bd62ee6b2036c31705a48b Mon Sep 17 00:00:00 2001 From: TomTheFurry Date: Thu, 23 Jun 2022 13:22:16 +0800 Subject: [PATCH] Finish up the level split of 3 type of levels: ClientOnly, ClientServer, and ServerOnly --- .../com/seibel/lod/core/a7/Initializer.java | 13 + .../lod/core/a7/RenderDataProvider.java | 11 - .../java/com/seibel/lod/core/a7/Server.java | 2 +- .../lod/core/a7/data/LodDataSource.java | 10 - .../lod/core/a7/data/OldFileConverter.java | 10 - .../{data => datatype}/DataSourceLoader.java | 33 ++- .../core/a7/datatype/EmptyRenderSource.java | 46 ++++ .../lod/core/a7/datatype/LodDataSource.java | 25 ++ .../lod/core/a7/datatype/LodRenderSource.java | 46 ++++ .../core/a7/datatype/RenderSourceLoader.java | 60 +++++ .../a7/datatype/column/Alpha6DataLoader.java | 103 -------- .../a7/datatype/column/ColumnDataLoader.java | 65 ----- ...ColumnDataPoint.java => ColumnFormat.java} | 4 +- .../datatype/column/ColumnRenderLoader.java | 197 ++------------ ...nDatatype.java => ColumnRenderSource.java} | 70 +++-- .../a7/datatype/column/DataSourceSaver.java | 31 --- .../a7/datatype/column/OldColumnDatatype.java | 249 ------------------ .../datatype/column/OldDataSourceLoader.java | 14 - .../{ => accessor}/ColumnArrayView.java | 12 +- .../column/{ => accessor}/ColumnDataView.java | 2 +- .../column/{ => accessor}/ColumnQuadView.java | 2 +- .../{ => accessor}/IColumnDatatype.java | 7 +- .../column/{ => render}/ColumnBox.java | 3 +- .../{ => render}/ColumnRenderBuffer.java | 12 +- .../core/a7/{data => datatype/full}/Data.java | 2 +- .../core/a7/{ => datatype/full}/DhChunk.java | 2 +- .../core/a7/datatype/full/FullDatatype.java | 22 -- .../full/FullFormat.java} | 37 ++- .../a7/{ => datatype/full}/ProtoSection.java | 3 +- .../lod/core/a7/level/DhClientLevel.java | 17 +- .../core/a7/level/DhClientServerLevel.java | 11 +- .../lod/core/a7/level/DhServerLevel.java | 4 +- .../lod/core/a7/level/IClientLevel.java | 4 +- .../lod/core/a7/level/IServerLevel.java | 1 + .../core/a7/render/EmptyRenderContainer.java | 42 --- .../lod/core/a7/{ => render}/LodQuadTree.java | 37 ++- .../lod/core/a7/{ => render}/LodSection.java | 39 +-- .../core/a7/render/RenderBufferHandler.java | 5 +- .../lod/core/a7/render/RenderDataSource.java | 60 ----- .../a7/render/RenderDataSourceLoader.java | 23 -- .../lod/core/a7/save/io/DHFolderHandler.java | 105 -------- .../seibel/lod/core/a7/save/io/MetaFile.java | 10 +- .../core/a7/save/io/file/DataMetaFile.java | 42 ++- ...Provider.java => IDataSourceProvider.java} | 8 +- .../a7/save/io/file/LocalDataFileHandler.java | 8 +- .../save/io/file/RemoteDataFileHandler.java | 8 +- ...ovider.java => IRenderSourceProvider.java} | 7 +- .../a7/save/io/render/RenderFileHandler.java | 18 +- .../a7/{save/io => util}/FileScanner.java | 10 +- .../com/seibel/lod/core/a7/util/IOUtil.java | 6 + .../lod/core/a7/{ => util}/IdMappingUtil.java | 2 +- .../UncheckedInterruptedException.java | 2 +- .../core/a7/world/DhClientServerWorld.java | 29 +- .../lod/core/a7/world/DhClientWorld.java | 11 +- .../lod/core/a7/world/DhServerWorld.java | 5 +- .../com/seibel/lod/core/a7/world/DhWorld.java | 5 +- .../lod/core/a7/world/IClientWorld.java | 3 + .../lod/core/a7/world/IServerWorld.java | 1 + .../core/a7/{ => world}/WorldEnvironment.java | 2 +- .../lod/core/api/internal/a7/ClientApi.java | 78 +++--- .../lod/core/api/internal/a7/ServerApi.java | 49 ++-- .../lod/core/api/internal/a7/SharedApi.java | 7 +- .../bufferBuilding/CubicLodTemplate.java | 4 +- 63 files changed, 528 insertions(+), 1228 deletions(-) create mode 100644 src/main/java/com/seibel/lod/core/a7/Initializer.java delete mode 100644 src/main/java/com/seibel/lod/core/a7/RenderDataProvider.java delete mode 100644 src/main/java/com/seibel/lod/core/a7/data/LodDataSource.java delete mode 100644 src/main/java/com/seibel/lod/core/a7/data/OldFileConverter.java rename src/main/java/com/seibel/lod/core/a7/{data => datatype}/DataSourceLoader.java (75%) create mode 100644 src/main/java/com/seibel/lod/core/a7/datatype/EmptyRenderSource.java create mode 100644 src/main/java/com/seibel/lod/core/a7/datatype/LodDataSource.java create mode 100644 src/main/java/com/seibel/lod/core/a7/datatype/LodRenderSource.java create mode 100644 src/main/java/com/seibel/lod/core/a7/datatype/RenderSourceLoader.java delete mode 100644 src/main/java/com/seibel/lod/core/a7/datatype/column/Alpha6DataLoader.java delete mode 100644 src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDataLoader.java rename src/main/java/com/seibel/lod/core/a7/datatype/column/{ColumnDataPoint.java => ColumnFormat.java} (99%) rename src/main/java/com/seibel/lod/core/a7/datatype/column/{ColumnDatatype.java => ColumnRenderSource.java} (82%) delete mode 100644 src/main/java/com/seibel/lod/core/a7/datatype/column/DataSourceSaver.java delete mode 100644 src/main/java/com/seibel/lod/core/a7/datatype/column/OldColumnDatatype.java delete mode 100644 src/main/java/com/seibel/lod/core/a7/datatype/column/OldDataSourceLoader.java rename src/main/java/com/seibel/lod/core/a7/datatype/column/{ => accessor}/ColumnArrayView.java (89%) rename src/main/java/com/seibel/lod/core/a7/datatype/column/{ => accessor}/ColumnDataView.java (92%) rename src/main/java/com/seibel/lod/core/a7/datatype/column/{ => accessor}/ColumnQuadView.java (98%) rename src/main/java/com/seibel/lod/core/a7/datatype/column/{ => accessor}/IColumnDatatype.java (84%) rename src/main/java/com/seibel/lod/core/a7/datatype/column/{ => render}/ColumnBox.java (98%) rename src/main/java/com/seibel/lod/core/a7/datatype/column/{ => render}/ColumnRenderBuffer.java (97%) rename src/main/java/com/seibel/lod/core/a7/{data => datatype/full}/Data.java (96%) rename src/main/java/com/seibel/lod/core/a7/{ => datatype/full}/DhChunk.java (97%) delete mode 100644 src/main/java/com/seibel/lod/core/a7/datatype/full/FullDatatype.java rename src/main/java/com/seibel/lod/core/a7/{data/CompleteDataContainer.java => datatype/full/FullFormat.java} (54%) rename src/main/java/com/seibel/lod/core/a7/{ => datatype/full}/ProtoSection.java (85%) delete mode 100644 src/main/java/com/seibel/lod/core/a7/render/EmptyRenderContainer.java rename src/main/java/com/seibel/lod/core/a7/{ => render}/LodQuadTree.java (94%) rename src/main/java/com/seibel/lod/core/a7/{ => render}/LodSection.java (57%) delete mode 100644 src/main/java/com/seibel/lod/core/a7/render/RenderDataSource.java delete mode 100644 src/main/java/com/seibel/lod/core/a7/render/RenderDataSourceLoader.java delete mode 100644 src/main/java/com/seibel/lod/core/a7/save/io/DHFolderHandler.java rename src/main/java/com/seibel/lod/core/a7/save/io/file/{DataSourceProvider.java => IDataSourceProvider.java} (60%) rename src/main/java/com/seibel/lod/core/a7/save/io/render/{RenderSourceProvider.java => IRenderSourceProvider.java} (53%) rename src/main/java/com/seibel/lod/core/a7/{save/io => util}/FileScanner.java (84%) create mode 100644 src/main/java/com/seibel/lod/core/a7/util/IOUtil.java rename src/main/java/com/seibel/lod/core/a7/{ => util}/IdMappingUtil.java (74%) rename src/main/java/com/seibel/lod/core/a7/{ => util}/UncheckedInterruptedException.java (96%) rename src/main/java/com/seibel/lod/core/a7/{ => world}/WorldEnvironment.java (69%) diff --git a/src/main/java/com/seibel/lod/core/a7/Initializer.java b/src/main/java/com/seibel/lod/core/a7/Initializer.java new file mode 100644 index 000000000..4cc02a15f --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/Initializer.java @@ -0,0 +1,13 @@ +package com.seibel.lod.core.a7; + +import com.seibel.lod.core.a7.datatype.column.ColumnRenderLoader; +import com.seibel.lod.core.a7.render.LodQuadTree; + +public class Initializer { + public static void init() { + ColumnRenderLoader columnRenderLoader = new ColumnRenderLoader(); + LodQuadTree.registerLayerLoader(columnRenderLoader, (byte) 7); // 7 or above + + + } +} diff --git a/src/main/java/com/seibel/lod/core/a7/RenderDataProvider.java b/src/main/java/com/seibel/lod/core/a7/RenderDataProvider.java deleted file mode 100644 index d31be3fbf..000000000 --- a/src/main/java/com/seibel/lod/core/a7/RenderDataProvider.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.seibel.lod.core.a7; - -import com.seibel.lod.core.a7.pos.DhSectionPos; -import com.seibel.lod.core.a7.render.RenderDataSource; -import com.seibel.lod.core.a7.render.RenderDataSourceLoader; - -import java.util.concurrent.CompletableFuture; - -public interface RenderDataProvider { - CompletableFuture createRenderData(RenderDataSourceLoader renderSourceLoader, DhSectionPos pos); -} diff --git a/src/main/java/com/seibel/lod/core/a7/Server.java b/src/main/java/com/seibel/lod/core/a7/Server.java index d22b6e573..c7c793b78 100644 --- a/src/main/java/com/seibel/lod/core/a7/Server.java +++ b/src/main/java/com/seibel/lod/core/a7/Server.java @@ -1,8 +1,8 @@ package com.seibel.lod.core.a7; +@Deprecated // Use the DhXXXWorld public class Server { public final boolean isSinglePlayer; - public Server(boolean isSinglePlayer) { this.isSinglePlayer = isSinglePlayer; } diff --git a/src/main/java/com/seibel/lod/core/a7/data/LodDataSource.java b/src/main/java/com/seibel/lod/core/a7/data/LodDataSource.java deleted file mode 100644 index 21dd067d2..000000000 --- a/src/main/java/com/seibel/lod/core/a7/data/LodDataSource.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.seibel.lod.core.a7.data; - -import com.seibel.lod.core.a7.pos.DhSectionPos; - -public interface LodDataSource { - DataSourceLoader getLatestLoader(); - DhSectionPos getSectionPos(); - byte getDataDetail(); - void setLocalVersion(int localVer); -} diff --git a/src/main/java/com/seibel/lod/core/a7/data/OldFileConverter.java b/src/main/java/com/seibel/lod/core/a7/data/OldFileConverter.java deleted file mode 100644 index d14668a29..000000000 --- a/src/main/java/com/seibel/lod/core/a7/data/OldFileConverter.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.seibel.lod.core.a7.data; - -import com.seibel.lod.core.a7.level.DhClientServerLevel; - -import java.io.File; -import java.util.List; - -public interface OldFileConverter { - List scanAndConvert(File levelFolder, DhClientServerLevel level); -} diff --git a/src/main/java/com/seibel/lod/core/a7/data/DataSourceLoader.java b/src/main/java/com/seibel/lod/core/a7/datatype/DataSourceLoader.java similarity index 75% rename from src/main/java/com/seibel/lod/core/a7/data/DataSourceLoader.java rename to src/main/java/com/seibel/lod/core/a7/datatype/DataSourceLoader.java index 88207a338..0624d9ce5 100644 --- a/src/main/java/com/seibel/lod/core/a7/data/DataSourceLoader.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/DataSourceLoader.java @@ -1,34 +1,42 @@ -package com.seibel.lod.core.a7.data; +package com.seibel.lod.core.a7.datatype; import com.google.common.collect.HashMultimap; -import com.seibel.lod.core.a7.save.io.file.DataMetaFile; import com.seibel.lod.core.a7.level.ILevel; +import com.seibel.lod.core.a7.save.io.file.DataMetaFile; -import java.io.File; import java.io.IOException; import java.io.InputStream; import java.util.*; public abstract class DataSourceLoader { - public static final HashMultimap loaderRegistry = HashMultimap.create(); + public static final HashMultimap, DataSourceLoader> loaderRegistry = HashMultimap.create(); + public final Class clazz; public static final HashMap> datatypeIdRegistry = new HashMap<>(); + public static DataSourceLoader getLoader(long dataTypeId, byte dataVersion) { + return loaderRegistry.get(datatypeIdRegistry.get(dataTypeId)).stream() + .filter(l -> Arrays.binarySearch(l.loaderSupportedVersions, dataVersion) >= 0) + .findFirst().orElse(null); + } + public static DataSourceLoader getLoader(Class clazz, byte dataVersion) { + return loaderRegistry.get(clazz).stream() + .filter(l -> Arrays.binarySearch(l.loaderSupportedVersions, dataVersion) >= 0) + .findFirst().orElse(null); + } public final long datatypeId; public final byte[] loaderSupportedVersions; - public final Class clazz; public DataSourceLoader(Class clazz, long datatypeId, byte[] loaderSupportedVersions) { this.datatypeId = datatypeId; this.loaderSupportedVersions = loaderSupportedVersions; Arrays.sort(loaderSupportedVersions); // sort to allow fast access this.clazz = clazz; - if (datatypeIdRegistry.containsKey(datatypeId) && datatypeIdRegistry.get(datatypeId) != clazz) { throw new IllegalArgumentException("Loader for datatypeId " + datatypeId + " already registered with different class: " + datatypeIdRegistry.get(datatypeId) + " != " + clazz); } - Set loaders = loaderRegistry.get(datatypeId); + Set loaders = loaderRegistry.get(clazz); if (loaders.stream().anyMatch(other -> { // see if any loaderSupportsVersion conflicts with this one for (byte otherVer : other.loaderSupportedVersions) { @@ -40,20 +48,11 @@ public abstract class DataSourceLoader { + Arrays.toString(loaderSupportedVersions) + " already registered!"); } datatypeIdRegistry.put(datatypeId, clazz); - loaderRegistry.put(datatypeId, this); + loaderRegistry.put(clazz, this); } // Can return null as meaning the requirement is not met public abstract LodDataSource loadData(DataMetaFile dataFile, InputStream data, ILevel level) throws IOException; - public List foldersToScan(File levelFolderPath) { - return Collections.emptyList(); - } - - public static DataSourceLoader getLoader(long dataTypeId, byte loaderVersion) { - return loaderRegistry.get(dataTypeId).stream() - .filter(l -> Arrays.binarySearch(l.loaderSupportedVersions, loaderVersion) >= 0) - .findFirst().orElse(null); - } } diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/EmptyRenderSource.java b/src/main/java/com/seibel/lod/core/a7/datatype/EmptyRenderSource.java new file mode 100644 index 000000000..2bbd3964c --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/datatype/EmptyRenderSource.java @@ -0,0 +1,46 @@ +package com.seibel.lod.core.a7.datatype; + +import com.seibel.lod.core.a7.level.IClientLevel; +import com.seibel.lod.core.a7.render.LodQuadTree; +import com.seibel.lod.core.a7.render.RenderBuffer; +import com.seibel.lod.core.a7.save.io.render.RenderMetaFile; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicReference; + +public class EmptyRenderSource implements LodRenderSource { + public static final EmptyRenderSource INSTANCE = new EmptyRenderSource(); + + @Override + public void enableRender(LodQuadTree quadTree) { + } + + @Override + public void disableRender() { + } + + @Override + public boolean isRenderReady() { + return false; + } + + @Override + public void dispose() { + } + + @Override + public byte getDetailOffset() { + return 0; + } + + @Override + public boolean trySwapRenderBuffer(LodQuadTree quadTree, AtomicReference referenceSlot) { + return false; + } + + @Override + public void saveRender(IClientLevel level, RenderMetaFile file, OutputStream dataStream) throws IOException { + throw new UnsupportedOperationException("EmptyRenderSource should NEVER be saved!"); + } +} diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/LodDataSource.java b/src/main/java/com/seibel/lod/core/a7/datatype/LodDataSource.java new file mode 100644 index 000000000..abd1dc8c0 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/datatype/LodDataSource.java @@ -0,0 +1,25 @@ +package com.seibel.lod.core.a7.datatype; + +import com.seibel.lod.core.a7.level.ILevel; +import com.seibel.lod.core.a7.pos.DhSectionPos; +import com.seibel.lod.core.a7.save.io.file.DataMetaFile; +import com.seibel.lod.core.a7.util.IOUtil; + +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; + +public interface LodDataSource { + DhSectionPos getSectionPos(); + byte getDataDetail(); + void setLocalVersion(int localVer); + byte getDataVersion(); + + + // Saving related + void saveData(ILevel level, DataMetaFile file, OutputStream dataStream) throws IOException; + default File generateFilePathAndName(File levelFolderPath, ILevel level, DhSectionPos sectionPos) { + return new File(levelFolderPath, String.format("%s_v%d-%s%s", getClass().getSimpleName(), getDataVersion(), + sectionPos.serialize(), IOUtil.LOD_FILE_EXTENSION)); + } +} diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/LodRenderSource.java b/src/main/java/com/seibel/lod/core/a7/datatype/LodRenderSource.java new file mode 100644 index 000000000..256bb6eec --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/datatype/LodRenderSource.java @@ -0,0 +1,46 @@ +package com.seibel.lod.core.a7.datatype; + +import com.seibel.lod.core.a7.level.IClientLevel; +import com.seibel.lod.core.a7.level.ILevel; +import com.seibel.lod.core.a7.pos.DhSectionPos; +import com.seibel.lod.core.a7.render.LodQuadTree; +import com.seibel.lod.core.a7.render.RenderBuffer; +import com.seibel.lod.core.a7.save.io.file.DataMetaFile; +import com.seibel.lod.core.a7.save.io.render.RenderMetaFile; +import com.seibel.lod.core.objects.DHRegionPos; + +import java.io.IOException; +import java.io.OutputStream; +import java.util.concurrent.atomic.AtomicReference; + +/** + * Example on how to register a loader: + *
+     public static RenderDataSource testAndConstruct(LodDataSource dataSource, DhSectionPos sectionPos) {
+        ColumnRenderContainer container = new ColumnRenderContainer(10, -100);
+        container.startFillData(dataSource);
+        return container;
+     }
+     static {
+        RenderDataSource.registorLoader(ColumnRenderContainer::testAndConstruct, 0);
+     }
+ 
+ */ +public interface LodRenderSource { + void enableRender(LodQuadTree quadTree); + void disableRender(); + boolean isRenderReady(); + void dispose(); // notify the container that the parent lodSection is now disposed (can be in loaded or unloaded state) + byte getDetailOffset(); + + /** + * Try and swap in new render buffer for this section. Note that before this call, there should be no other + * places storing or referencing the render buffer. + * @param referenceSlot The slot for swapping in the new buffer. + * @return True if the swap was successful. False if swap is not needed or if it is in progress. + */ + boolean trySwapRenderBuffer(LodQuadTree quadTree, AtomicReference referenceSlot); + + void saveRender(IClientLevel level, RenderMetaFile file, OutputStream dataStream) throws IOException; + +} diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/RenderSourceLoader.java b/src/main/java/com/seibel/lod/core/a7/datatype/RenderSourceLoader.java new file mode 100644 index 000000000..cfb17ffc6 --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/datatype/RenderSourceLoader.java @@ -0,0 +1,60 @@ +package com.seibel.lod.core.a7.datatype; + +import com.google.common.collect.HashMultimap; +import com.seibel.lod.core.a7.level.IClientLevel; +import com.seibel.lod.core.a7.save.io.render.RenderMetaFile; + +import java.io.IOException; +import java.io.InputStream; +import java.util.*; + +public abstract class RenderSourceLoader { + public static final HashMultimap, RenderSourceLoader> loaderRegistry = HashMultimap.create(); + public static final HashMap> renderTypeIdRegistry = new HashMap<>(); + public static RenderSourceLoader getLoader(long renderTypeId, byte loaderVersion) { + return loaderRegistry.get(renderTypeIdRegistry.get(renderTypeId)).stream() + .filter(l -> Arrays.binarySearch(l.loaderSupportedVersions, loaderVersion) >= 0) + .findFirst().orElse(null); + } + public static RenderSourceLoader getLoader(Class clazz, byte loaderVersion) { + return loaderRegistry.get(clazz).stream() + .filter(l -> Arrays.binarySearch(l.loaderSupportedVersions, loaderVersion) >= 0) + .findFirst().orElse(null); + } + + public final Class clazz; + public final long renderTypeId; + public final byte[] loaderSupportedVersions; + public final byte detailOffset; + + public RenderSourceLoader(Class clazz, long renderTypeId, byte[] loaderSupportedVersions, byte detailOffset) { + this.renderTypeId = renderTypeId; + this.loaderSupportedVersions = loaderSupportedVersions; + Arrays.sort(loaderSupportedVersions); // sort to allow fast access + this.clazz = clazz; + if (renderTypeIdRegistry.containsKey(renderTypeId) && renderTypeIdRegistry.get(renderTypeId) != clazz) { + throw new IllegalArgumentException("Loader for renderTypeId " + renderTypeId + " already registered with different class: " + + renderTypeIdRegistry.get(renderTypeId) + " != " + clazz); + } + Set loaders = loaderRegistry.get(clazz); + if (loaders.stream().anyMatch(other -> { + // see if any loaderSupportsVersion conflicts with this one + for (byte otherVer : other.loaderSupportedVersions) { + if (Arrays.binarySearch(loaderSupportedVersions, otherVer) >= 0) return true; + } + return false; + })) { + throw new IllegalArgumentException("Loader for class " + clazz + " that supports one of the version in " + + Arrays.toString(loaderSupportedVersions) + " already registered!"); + } + renderTypeIdRegistry.put(renderTypeId, clazz); + loaderRegistry.put(clazz, this); + this.detailOffset = detailOffset; + } + + // Can return null as meaning the file is out of date or something + public abstract LodRenderSource loadRender(RenderMetaFile renderFile, InputStream data, IClientLevel level) throws IOException; + public abstract LodRenderSource createRender(LodDataSource dataSource, IClientLevel level); + + +} diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/Alpha6DataLoader.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/Alpha6DataLoader.java deleted file mode 100644 index 2108a121e..000000000 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/Alpha6DataLoader.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.seibel.lod.core.a7.datatype.column; - -import com.seibel.lod.core.a7.data.DataFileHandler; -import com.seibel.lod.core.a7.data.LodDataSource; -import com.seibel.lod.core.a7.data.OldFileConverter; -import com.seibel.lod.core.a7.pos.DhSectionPos; -import com.seibel.lod.core.enums.config.EVerticalQuality; -import com.seibel.lod.core.a7.level.DhClientServerLevel; -import com.seibel.lod.core.objects.a7.data.*; -import com.seibel.lod.core.a7.save.io.file.DataMetaFile; -import org.apache.commons.compress.compressors.xz.XZCompressorInputStream; - -import java.io.*; -import java.util.ArrayList; -import java.util.List; - -public class Alpha6DataLoader extends OldDataSourceLoader implements OldFileConverter { - - public static final Alpha6DataLoader INSTANCE = new Alpha6DataLoader(); - - private Alpha6DataLoader() { - super(OldColumnDatatype.class, OldColumnDatatype.DATA_TYPE_ID, new byte[]{0}); - DataFileHandler.CONVERTERS.add(this); - } - - @Override - public LodDataSource loadData(DataMetaFile dataFile, InputStream data, DhClientServerLevel level) { - //TODO: Add decompressor here - try ( - XZCompressorInputStream xzIn = new XZCompressorInputStream(data); - DataInputStream dis = new DataInputStream(xzIn); - ) { - return new OldColumnDatatype(dataFile.pos, dis, dataFile.loaderVersion, level, 1); - } catch (IOException e) { - //FIXME: Log error - return null; - } - } - - @Override - public DataSourceSaver getNewSaver() { - return null; // No re-saving of old datatype as any data should be converted to new format before saving - } - - - - - private static DataFile convert(File file, int detailLevel, EVerticalQuality quality) { - String oldName = file.getName(); - String regionStr = oldName.substring("lod.".length(), oldName.length() - ".xz".length()); - String[] parts = regionStr.split("\\."); - if (parts.length != 2) return null; - int regionX = Integer.parseInt(parts[0]); - int regionZ = Integer.parseInt(parts[1]); - - ColumnDatatype datatype; - - try (FileInputStream fileInStream = new FileInputStream(file)) { - XZCompressorInputStream inputStream = new XZCompressorInputStream(fileInStream); - int fileVersion = inputStream.read(); - - - DhSectionPos pos; - - //TODO: Implement - } catch (Exception e) { - e.printStackTrace(); - } - return null; - } - - @Override - public List scanAndConvert(File levelFolder, DhClientServerLevel level) { - - List files = new ArrayList<>(); - - List foldersToScan = new ArrayList<>(EVerticalQuality.values().length); - for (EVerticalQuality q : EVerticalQuality.values()) { - File qualityFolder = new File(levelFolder, q.toString()); - for (int i = 0; i < 10; i++) { - foldersToScan.add(new File(qualityFolder, "detail-"+i)); - } - } - - for (EVerticalQuality q : EVerticalQuality.values()) { - for (int i = 0; i < 10; i++) { - File detailFolder = new File(levelFolder, q.toString() + File.pathSeparator + "detail-" + i); - if (!detailFolder.exists() || !detailFolder.isDirectory()) continue; - File[] filesToScan = detailFolder.listFiles(); - if (filesToScan == null) continue; - for (File f : filesToScan) { - String fileName = f.getName(); - if (!fileName.endsWith(".xz") || fileName.startsWith("lod.")) continue; - DataFile converted = convert(f, i, q); - - - } - } - } - - return files; - } -} diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDataLoader.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDataLoader.java deleted file mode 100644 index 5703c2913..000000000 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDataLoader.java +++ /dev/null @@ -1,65 +0,0 @@ -package com.seibel.lod.core.a7.datatype.column; - -import com.seibel.lod.core.a7.data.DataFileHandler; -import com.seibel.lod.core.a7.data.LodDataSource; -import com.seibel.lod.core.a7.save.io.MetaFile; -import com.seibel.lod.core.a7.pos.DhSectionPos; -import com.seibel.lod.core.config.Config; -import com.seibel.lod.core.enums.config.EVerticalQuality; -import com.seibel.lod.core.a7.level.DhClientServerLevel; -import com.seibel.lod.core.a7.save.io.file.DataMetaFile; - -import java.io.*; -import java.util.ArrayList; -import java.util.List; - -public class ColumnDataLoader extends DataSourceSaver { - private static final byte COLUMN_DATA_LOADER_VERSION = 1; - public static final ColumnDataLoader INSTANCE = new ColumnDataLoader(); - - private ColumnDataLoader() { - super(ColumnDatatype.class, ColumnDatatype.DATA_TYPE_ID, new byte[]{COLUMN_DATA_LOADER_VERSION}); - } - - @Override - public LodDataSource loadData(DataMetaFile dataFile, InputStream data, DhClientServerLevel level) { - try ( - //TODO: Add decompressor here - DataInputStream dis = new DataInputStream(data); - ) { - return new ColumnDatatype(dataFile.pos, dis, dataFile.loaderVersion, level); - } catch (IOException e) { - //FIXME: Log error - return null; - } - } - - @Override - public void saveData(DhClientServerLevel level, LodDataSource loadedData, MetaFile file, OutputStream out) throws IOException { - //TODO: Add compressor here - try (DataOutputStream dos = new DataOutputStream(out)) { - ((ColumnDatatype) loadedData).writeData(dos); - } - } - - @Override - public File generateFilePathAndName(File levelFolderPath, DhClientServerLevel level, DhSectionPos sectionPos) { - return generateFilePathAndName(levelFolderPath, sectionPos, Config.Client.Graphics.Quality.verticalQuality.get()); - } - - public File generateFilePathAndName(File levelFolderPath, DhSectionPos sectionPos, EVerticalQuality quality) { - return new File(levelFolderPath, "cache" + File.separator + quality.toString() + File.separator + - String.format("%s_v%d-%s%s", clazz.getSimpleName(), COLUMN_DATA_LOADER_VERSION, - sectionPos.serialize(), DataFileHandler.FILE_EXTENSION)); - } - - @Override - public List foldersToScan(File levelFolderPath) { - File cacheFolder = new File(levelFolderPath, "cache"); - List foldersToScan = new ArrayList<>(EVerticalQuality.values().length); - for (EVerticalQuality q : EVerticalQuality.values()) { - foldersToScan.add(new File(cacheFolder, q.toString())); - } - return foldersToScan; - } -} diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDataPoint.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnFormat.java similarity index 99% rename from src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDataPoint.java rename to src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnFormat.java index 222707ec6..7d48ab975 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDataPoint.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnFormat.java @@ -19,6 +19,8 @@ package com.seibel.lod.core.a7.datatype.column; +import com.seibel.lod.core.a7.datatype.column.accessor.ColumnArrayView; +import com.seibel.lod.core.a7.datatype.column.accessor.ColumnDataView; import com.seibel.lod.core.logging.SpamReducedLogger; import com.seibel.lod.core.util.ColorUtil; @@ -30,7 +32,7 @@ import java.util.Arrays; * @author Leonardo Amato * @version ?? */ -public class ColumnDataPoint +public class ColumnFormat { /* diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java index dbaccc082..88c62add0 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderLoader.java @@ -1,190 +1,35 @@ package com.seibel.lod.core.a7.datatype.column; -import com.seibel.lod.core.a7.data.LodDataSource; -import com.seibel.lod.core.a7.datatype.full.FullDatatype; -import com.seibel.lod.core.a7.pos.DhSectionPos; -import com.seibel.lod.core.a7.render.RenderDataSource; -import com.seibel.lod.core.a7.render.RenderDataSourceLoader; -import com.seibel.lod.core.a7.level.DhClientServerLevel; -import com.seibel.lod.core.objects.a7.data.DataFile; -import com.seibel.lod.core.util.DetailDistanceUtil; -import com.seibel.lod.core.util.LodUtil; +import com.seibel.lod.core.a7.datatype.LodDataSource; +import com.seibel.lod.core.a7.level.IClientLevel; +import com.seibel.lod.core.a7.datatype.LodRenderSource; +import com.seibel.lod.core.a7.datatype.RenderSourceLoader; +import com.seibel.lod.core.a7.save.io.render.RenderMetaFile; -import java.util.Collections; -import java.util.LinkedList; -import java.util.List; -import java.util.Objects; +import java.io.DataInputStream; +import java.io.IOException; +import java.io.InputStream; -class ColumnRenderLoader extends RenderDataSourceLoader { +public class ColumnRenderLoader extends RenderSourceLoader { public ColumnRenderLoader() { - super(4); + super(ColumnRenderSource.class, ColumnRenderSource.TYPE_ID, new byte[]{ColumnRenderSource.LATEST_VERSION}, ColumnRenderSource.SECTION_SIZE_OFFSET); } @Override - public RenderDataSource construct(List dataSources, DhSectionPos sectionPos, DhClientServerLevel level) { - if (dataSources.size() == 0) return null; - - // Check for direct casting - if (dataSources.size() == 1 && dataSources.get(0) instanceof ColumnDatatype - && dataSources.get(0).getSectionPos().equals(sectionPos) - && dataSources.get(0).getDataDetail() == sectionPos.sectionDetail - ColumnDatatype.SECTION_SIZE_OFFSET) { - // Directly using the data source as the render data source is possible. - return (ColumnDatatype) dataSources.get(0); + public LodRenderSource loadRender(RenderMetaFile dataFile, InputStream data, IClientLevel level) throws IOException { + try ( + //TODO: Add decompressor here + DataInputStream dis = new DataInputStream(data); + ) { + return new ColumnRenderSource(dataFile.pos, dis, dataFile.dataVersion, level); } - - // Otherwise, we need to create a new render data source, and copy the data from the data sources. - ColumnDatatype renderDataSource = new ColumnDatatype(sectionPos, - DetailDistanceUtil.getMaxVerticalData(sectionPos.sectionDetail - ColumnDatatype.SECTION_SIZE_OFFSET), - level.getMinY()); - boolean completeCopy = dataSources.get(0).getSectionPos().getWidth().toBlock() >= sectionPos.getWidth().toBlock(); - - if (completeCopy) { - // If there is only one data source, we need to insure on copy, we don't copy out of bounds as we - // may just need to copy partial section of the data source. - LodUtil.assertTrue(dataSources.size() == 1, "Expected only one data source for complete copy"); - byte targetDataLevel = (byte) (sectionPos.sectionDetail - ColumnDatatype.SECTION_SIZE_OFFSET); - byte sourceDataLevel = dataSources.get(0).getDataDetail(); - LodUtil.assertTrue(targetDataLevel >= sourceDataLevel); - if (dataSources.get(0) instanceof IColumnDatatype) { - IColumnDatatype dataSource = (IColumnDatatype) dataSources.get(0); - DhSectionPos srcPos = dataSource.getSectionPos(); - - // Note that in here, the source data level will be always < target section level - int trgX = sectionPos.getCorner().getX().toBlock(); - int trgZ = sectionPos.getCorner().getZ().toBlock(); - int trgMaxX = trgX + sectionPos.getWidth().toBlock() - 1; - int trgMaxZ = trgZ + sectionPos.getWidth().toBlock() - 1; - int trgXSizeInSrc = (trgX >> sourceDataLevel) - (trgMaxX >> sourceDataLevel) + 1; - int trgZSizeInSrc = (trgZ >> sourceDataLevel) - (trgMaxZ >> sourceDataLevel) + 1; - int trgXInSrc = (trgX >> sourceDataLevel) % srcPos.getWidth(sourceDataLevel).value; - int trgZInSrc = (trgZ >> sourceDataLevel) % srcPos.getWidth(sourceDataLevel).value; - - ColumnQuadView srcView = dataSource.getDataInQuad(trgXInSrc, trgZInSrc, trgXSizeInSrc, trgZSizeInSrc); - ColumnQuadView trgView = renderDataSource.getFullQuad(); - trgView.mergeMultiColumnFrom(srcView); - } else { - if (!(dataSources.get(0) instanceof FullDatatype)) - throw new IllegalArgumentException("Unsupported data source type: " + dataSources.get(0).getClass().getName()); - FullDatatype dataSource = (FullDatatype) dataSources.get(0); - DhSectionPos srcPos = dataSource.getSectionPos(); - //TODO: Impl this - LodUtil.assertTrue(false, "Not implemented yet"); - } - } else { - // If there are multiple data sources, we need to merge them into the target data source - for (LodDataSource dataSource : dataSources) { - byte targetDataLevel = (byte) (sectionPos.sectionDetail - ColumnDatatype.SECTION_SIZE_OFFSET); - byte sourceDataLevel = dataSource.getDataDetail(); - DhSectionPos srcPos = dataSource.getSectionPos(); - - if (dataSource instanceof IColumnDatatype) { - IColumnDatatype clDataSource = (IColumnDatatype) dataSource; - - // Note that targetDataLevel can be > source section level - int srcX = srcPos.getCorner().getX().toBlock(); - int srcZ = srcPos.getCorner().getZ().toBlock(); - int srcMaxX = srcX + srcPos.getWidth().toBlock() - 1; - int srcMaxZ = srcZ + srcPos.getWidth().toBlock() - 1; - int srcXSizeInTrg = (srcX >> targetDataLevel) - (srcMaxX >> targetDataLevel) + 1; - int srcZSizeInTrg = (srcZ >> targetDataLevel) - (srcMaxZ >> targetDataLevel) + 1; - int srcXInTrg = (srcX >> targetDataLevel) % ColumnDatatype.SECTION_SIZE; - int srcZInTrg = (srcZ >> targetDataLevel) % ColumnDatatype.SECTION_SIZE; - - ColumnQuadView srcView = clDataSource.getFullQuad(); - ColumnQuadView trgView = renderDataSource.getDataInQuad(srcXInTrg, srcZInTrg, srcXSizeInTrg, srcZSizeInTrg); - trgView.mergeMultiColumnFrom(srcView); - } else { - if (!(dataSource instanceof FullDatatype)) - throw new IllegalArgumentException("Unsupported data source type: " + dataSource.getClass().getName()); - FullDatatype flDataSource = (FullDatatype) dataSource; - //TODO: Impl this - LodUtil.assertTrue(false, "Not implemented yet"); - } - } - } - - return renderDataSource; - } - - private static boolean IsColumnDatatype(Class clazz) { - return IColumnDatatype.class.isAssignableFrom(clazz); } @Override - public List selectFiles(DhSectionPos sectionPos, DhClientServerLevel level, List[] availableFiles) { - byte targetDataLevel = (byte) (sectionPos.sectionDetail - ColumnDatatype.SECTION_SIZE_OFFSET); - //No support for loading higher than the target level yet. - byte maxDataLevel = LodUtil.min((byte) (availableFiles.length - 1), targetDataLevel); - byte topValidDataLevel = Byte.MIN_VALUE; - List selectedFiles = new LinkedList<>(); - - for (int detail = maxDataLevel; detail >= 0; detail--) { - if (availableFiles[detail] == null) continue; - if (topValidDataLevel == Byte.MIN_VALUE) { - for (DataFile dataFile : availableFiles[detail]) { - if (dataFile.dataLevel > targetDataLevel) continue; - if (IsColumnDatatype(dataFile.dataType) || dataFile.dataType == FullDatatype.class - || dataFile.dataType == OldColumnDatatype.class) { - topValidDataLevel = LodUtil.max(topValidDataLevel, dataFile.dataLevel); - break; - } - } - } - if (topValidDataLevel == Byte.MIN_VALUE) continue; - - - DataFile singleCoveringColumnFile = null; - DataFile singleCoveringFullFile = null; - - for (DataFile dataFile : availableFiles[detail]) { - if (dataFile.pos.getWidth().toBlock() == sectionPos.getWidth().toBlock()) { - if (IsColumnDatatype(dataFile.dataType)) { - singleCoveringColumnFile = dataFile; - break; - } else if (dataFile.dataType == FullDatatype.class) { - singleCoveringFullFile = dataFile; - // Don't break as there may be a column file later. - } - } else if (dataFile.pos.getWidth().toBlock() > sectionPos.getWidth().toBlock()) { - if (IsColumnDatatype(dataFile.dataType) && singleCoveringColumnFile == null) - singleCoveringColumnFile = dataFile; - else if (dataFile.dataType == FullDatatype.class && singleCoveringFullFile == null) - singleCoveringFullFile = dataFile; - } - } - - // First, try select single file that has enough width to cover the section - if (singleCoveringColumnFile != null) return Collections.singletonList(singleCoveringColumnFile); - if (singleCoveringFullFile != null) return Collections.singletonList(singleCoveringFullFile); - - // If no single file covers the section, try to select all files without any duplicates - for (DataFile dataFile : availableFiles[detail]) { - boolean isDuplicate = false; - boolean isSet = false; - for (int i = 0; i < selectedFiles.size(); i++) { - DataFile selectedFile = selectedFiles.get(i); - if (selectedFile == null) continue; - if (selectedFile.pos.overlaps(dataFile.pos)) { - // Now, the already selected file muct have same or higher data level - // so, we just select the file with a position that covers the most area. - // Therefore, we choose the file with the higher section level. - if (selectedFile.pos.sectionDetail < dataFile.pos.sectionDetail) { - if (isSet) selectedFiles.set(i, null); - else selectedFiles.set(i, dataFile); - isSet = true; - } else { - LodUtil.assertTrue(!isSet); // We should not have encountered a smaller section level. - // This mean its completely covered by the selected file, so we can skip it. - isDuplicate = true; - break; - } - } - } - if (!isDuplicate && !isSet) selectedFiles.add(dataFile); - } - } - if (topValidDataLevel == Byte.MIN_VALUE) return Collections.emptyList(); - selectedFiles.removeIf(Objects::isNull); - return selectedFiles; + public LodRenderSource createRender(LodDataSource dataSource, IClientLevel level) { + //TODO + return null; } + + } diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDatatype.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderSource.java similarity index 82% rename from src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDatatype.java rename to src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderSource.java index 208bb2d2a..f95e62801 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnDatatype.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderSource.java @@ -1,29 +1,35 @@ package com.seibel.lod.core.a7.datatype.column; -import com.seibel.lod.core.a7.data.DataSourceLoader; +import com.seibel.lod.core.a7.datatype.column.accessor.ColumnArrayView; +import com.seibel.lod.core.a7.datatype.column.accessor.ColumnQuadView; +import com.seibel.lod.core.a7.datatype.column.accessor.IColumnDatatype; +import com.seibel.lod.core.a7.datatype.column.render.ColumnRenderBuffer; +import com.seibel.lod.core.a7.level.IClientLevel; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.a7.render.RenderBuffer; +import com.seibel.lod.core.a7.save.io.render.RenderMetaFile; import com.seibel.lod.core.enums.ELodDirection; import com.seibel.lod.core.objects.LodDataView; -import com.seibel.lod.core.a7.level.DhClientServerLevel; -import com.seibel.lod.core.a7.LodQuadTree; -import com.seibel.lod.core.a7.LodSection; -import com.seibel.lod.core.a7.render.RenderDataSource; +import com.seibel.lod.core.a7.level.ILevel; +import com.seibel.lod.core.a7.render.LodQuadTree; +import com.seibel.lod.core.a7.render.LodSection; +import com.seibel.lod.core.a7.datatype.LodRenderSource; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.io.OutputStream; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; -public class ColumnDatatype implements RenderDataSource, IColumnDatatype { +public class ColumnRenderSource implements LodRenderSource, IColumnDatatype { public static final boolean DO_SAFETY_CHECKS = true; public static final byte SECTION_SIZE_OFFSET = 6; public static final int SECTION_SIZE = 1 << SECTION_SIZE_OFFSET; - public static final int LATEST_VERSION = 10; - public static final long DATA_TYPE_ID = "ColumnDatatype".hashCode(); + public static final byte LATEST_VERSION = 1; + public static final long TYPE_ID = "ColumnRenderSource".hashCode(); public static final int AIR_LODS_SIZE = 16; public static final int AIR_SECTION_SIZE = SECTION_SIZE/AIR_LODS_SIZE; @@ -38,7 +44,7 @@ public class ColumnDatatype implements RenderDataSource, IColumnDatatype { * Constructor of the ColumnDataType * @param maxVerticalSize the maximum vertical size of the container */ - public ColumnDatatype(DhSectionPos sectionPos, int maxVerticalSize, int yOffset) { + public ColumnRenderSource(DhSectionPos sectionPos, int maxVerticalSize, int yOffset) { verticalSize = maxVerticalSize; dataContainer = new long[SECTION_SIZE * SECTION_SIZE * verticalSize]; airDataContainer = new int[AIR_SECTION_SIZE * AIR_SECTION_SIZE * verticalSize]; @@ -64,13 +70,13 @@ public class ColumnDatatype implements RenderDataSource, IColumnDatatype { bb.asLongBuffer().get(result); if (tempMinHeight != yOffset) { for (int i=0; i referenceSlot) { if (inBuildRenderBuffer != null && inBuildRenderBuffer.isDone()) { RenderBuffer oldBuffer = referenceSlot.getAndSet(inBuildRenderBuffer.join()); - if (oldBuffer != null && oldBuffer instanceof ColumnRenderBuffer) usedBuffer = (ColumnRenderBuffer) oldBuffer; + if (oldBuffer instanceof ColumnRenderBuffer) usedBuffer = (ColumnRenderBuffer) oldBuffer; inBuildRenderBuffer = null; return true; } else { @@ -314,6 +302,10 @@ public class ColumnDatatype implements RenderDataSource, IColumnDatatype { return false; } - - + @Override + public void saveRender(IClientLevel level, RenderMetaFile file, OutputStream dataStream) throws IOException { + try (DataOutputStream dos = new DataOutputStream(dataStream)) { + writeData(dos); + } + } } diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/DataSourceSaver.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/DataSourceSaver.java deleted file mode 100644 index f7647dd38..000000000 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/DataSourceSaver.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.seibel.lod.core.a7.datatype.column; - -import com.seibel.lod.core.a7.data.DataFileHandler; -import com.seibel.lod.core.a7.data.DataSourceLoader; -import com.seibel.lod.core.a7.data.LodDataSource; -import com.seibel.lod.core.a7.save.io.MetaFile; -import com.seibel.lod.core.a7.level.ILevel; -import com.seibel.lod.core.a7.pos.DhSectionPos; -import com.seibel.lod.core.a7.level.DhClientServerLevel; - -import java.io.File; -import java.io.IOException; -import java.io.OutputStream; - -public abstract class DataSourceSaver extends DataSourceLoader { - public DataSourceSaver(Class clazz, long datatypeId, byte[] loaderSupportedVersions) { - super(clazz, datatypeId, loaderSupportedVersions); - } - - public abstract void saveData(ILevel level, LodDataSource loadedData, MetaFile file, OutputStream dataStream) throws IOException; - // generate the default file path and file name based on various parameters. - // Ensure the file extension is '.lod'! - public File generateFilePathAndName(File levelFolderPath, DhClientServerLevel level, DhSectionPos sectionPos) { - return new File(levelFolderPath, String.format("%s_v%d-%s%s", clazz.getSimpleName(), getSaverVersion(), - sectionPos.serialize(), DataFileHandler.FILE_EXTENSION)); - } - - public byte getSaverVersion() { - return loaderSupportedVersions[loaderSupportedVersions.length - 1]; - } -} diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/OldColumnDatatype.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/OldColumnDatatype.java deleted file mode 100644 index 5178616d8..000000000 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/OldColumnDatatype.java +++ /dev/null @@ -1,249 +0,0 @@ -package com.seibel.lod.core.a7.datatype.column; - -import com.seibel.lod.core.a7.data.DataSourceLoader; -import com.seibel.lod.core.a7.pos.DhSectionPos; -import com.seibel.lod.core.objects.LodDataView; -import com.seibel.lod.core.a7.level.DhClientServerLevel; - -import java.io.DataInputStream; -import java.io.IOException; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - -public class OldColumnDatatype implements IColumnDatatype { - public static final boolean DO_SAFETY_CHECKS = true; - public static final int LATEST_VERSION = 10; - public static final long DATA_TYPE_ID = "OldColumnDatatype".hashCode(); - - public final byte sectionSizeOffset; - public final int getSectSize() { - return 1 << sectionSizeOffset; - } - - public final int verticalSize; - public final DhSectionPos sectionPos; - public final int yOffset; - public final long[] dataContainer; - - /** - * Constructor of the ColumnDataType - * @param maxVerticalSize the maximum vertical size of the container - */ - public OldColumnDatatype(DhSectionPos sectionPos, int maxVerticalSize, int yOffset, int sectionSizeOffset) { - this.sectionSizeOffset = (byte) sectionSizeOffset; - verticalSize = maxVerticalSize; - dataContainer = new long[getSectSize() * getSectSize() * verticalSize]; - this.sectionPos = sectionPos; - this.yOffset = yOffset; - } - - private long[] loadData(DataInputStream inputData, int version, int verticalSize) throws IOException { - switch (version) { - case 6: - return readDataVersion6(inputData, verticalSize); - case 7: - return readDataVersion7(inputData, verticalSize); - case 8: - return readDataVersion8(inputData, verticalSize); - case 9: - case 10: - return readDataVersion9(inputData, verticalSize); - default: - throw new IOException("Invalid Data: The version of the data is not supported"); - } - } - - // Load from data stream with maxVerticalSize loaded from the data stream - public OldColumnDatatype(DhSectionPos sectionPos, DataInputStream inputData, int version, DhClientServerLevel level, int sectionSizeOffset) throws IOException { - this.sectionSizeOffset = (byte) sectionSizeOffset; - this.sectionPos = sectionPos; - yOffset = level.getMinY(); - byte detailLevel = inputData.readByte(); - if (sectionPos.sectionDetail - sectionSizeOffset != detailLevel) { - throw new IOException("Invalid data: detail level does not match"); - } - verticalSize = inputData.readByte() & 0b01111111; - dataContainer = loadData(inputData, version, verticalSize); - } - - @Override - public byte getDetailOffset() { - return sectionSizeOffset; - } - - public void clear(int posX, int posZ) - { - throw new UnsupportedOperationException("OldColumnDatatype only supports read-only access." + - " Convert to ColumnDatatype first before doing any modifications."); - } - - public boolean addData(long data, int posX, int posZ, int verticalIndex) - { - throw new UnsupportedOperationException("OldColumnDatatype only supports read-only access." + - " Convert to ColumnDatatype first before doing any modifications."); - } - - public boolean copyVerticalData(LodDataView data, int posX, int posZ, boolean override) { - throw new UnsupportedOperationException("OldColumnDatatype only supports read-only access." + - " Convert to ColumnDatatype first before doing any modifications."); - } - - public long getData(int posX, int posZ, int verticalIndex) - { - return dataContainer[posX * getSectSize() * verticalSize + posZ * verticalSize + verticalIndex]; - } - - public long[] getAllData(int posX, int posZ) - { - long[] result = new long[verticalSize]; - int index = posX * getSectSize() * verticalSize + posZ * verticalSize; - System.arraycopy(dataContainer, index, result, 0, verticalSize); - return result; - } - - public ColumnArrayView getVerticalDataView(int posX, int posZ) { - return new ColumnArrayView(dataContainer, verticalSize, - posX * getSectSize() * verticalSize + posZ * verticalSize, verticalSize); - } - - public ColumnQuadView getDataInQuad(int quadX, int quadZ, int quadXSize, int quadZSize) { - return new ColumnQuadView(dataContainer, getSectSize(), verticalSize, quadX, quadZ, quadXSize, quadZSize); - } - public ColumnQuadView getFullQuad() { - return new ColumnQuadView(dataContainer, getSectSize(), verticalSize, 0, 0, getSectSize(), getSectSize()); - } - - public int getVerticalSize() - { - return verticalSize; - } - - public boolean doesItExist(int posX, int posZ) - { - return ColumnDataPoint.doesItExist(getSingleData(posX, posZ)); - } - - @Override - public void generateData(ColumnDatatype lowerDataContainer, int posX, int posZ) { - throw new UnsupportedOperationException("OldColumnDatatype only supports read-only access." + - " Convert to ColumnDatatype first before doing any modifications."); - } - - private long[] readDataVersion6(DataInputStream inputData, int tempMaxVerticalData) throws IOException { - int x = getSectSize() * getSectSize() * tempMaxVerticalData; - byte[] data = new byte[x * Long.BYTES]; - ByteBuffer bb = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN); - inputData.readFully(data); - long[] result = new long[x]; - bb.asLongBuffer().get(result); - patchVersion9Reorder(result); - patchHeightAndDepth(result,-yOffset); - return result; - } - private long[] readDataVersion7(DataInputStream inputData, int tempMaxVerticalData) throws IOException { - int x = getSectSize() * getSectSize() * tempMaxVerticalData; - byte[] data = new byte[x * Long.BYTES]; - ByteBuffer bb = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN); - inputData.readFully(data); - long[] result = new long[x]; - bb.asLongBuffer().get(result); - patchVersion9Reorder(result); - patchHeightAndDepth(result, 64 - yOffset); - return result; - } - private long[] readDataVersion8(DataInputStream inputData, int tempMaxVerticalData) throws IOException { - int x = getSectSize() * getSectSize() * tempMaxVerticalData; - byte[] data = new byte[x * Long.BYTES]; - short tempMinHeight = Short.reverseBytes(inputData.readShort()); - ByteBuffer bb = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN); - inputData.readFully(data); - long[] result = new long[x]; - bb.asLongBuffer().get(result); - patchVersion9Reorder(result); - if (tempMinHeight != yOffset) { - patchHeightAndDepth(result,tempMinHeight - yOffset); - } - return result; - } - private long[] readDataVersion9(DataInputStream inputData, int tempMaxVerticalData) throws IOException { - int x = getSectSize() * getSectSize() * tempMaxVerticalData; - byte[] data = new byte[x * Long.BYTES]; - short tempMinHeight = Short.reverseBytes(inputData.readShort()); - ByteBuffer bb = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN); - inputData.readFully(data); - long[] result = new long[x]; - bb.asLongBuffer().get(result); - if (tempMinHeight != yOffset) { - patchHeightAndDepth(result,tempMinHeight - yOffset); - } - return result; - } - - private static void patchHeightAndDepth(long[] data, int offset) { - for (int i=0; i clazz, long datatypeId, byte[] loaderVersions) { - super(clazz, datatypeId, loaderVersions); - } - abstract public DataSourceSaver getNewSaver(); -} diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnArrayView.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/accessor/ColumnArrayView.java similarity index 89% rename from src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnArrayView.java rename to src/main/java/com/seibel/lod/core/a7/datatype/column/accessor/ColumnArrayView.java index e3e33ca0c..f3210bbe1 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnArrayView.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/accessor/ColumnArrayView.java @@ -1,6 +1,8 @@ -package com.seibel.lod.core.a7.datatype.column; +package com.seibel.lod.core.a7.datatype.column.accessor; +import com.seibel.lod.core.a7.datatype.column.ColumnFormat; + import java.util.Arrays; public final class ColumnArrayView implements ColumnDataView { @@ -78,12 +80,12 @@ public final class ColumnArrayView implements ColumnDataView { boolean anyChange = false; for (int o=0; o<(source.size()*vertSize); o+=vertSize) { if (override) { - if (ColumnDataPoint.compareDatapointPriority(source.get(o), get(o)) >= 0) { + if (ColumnFormat.compareDatapointPriority(source.get(o), get(o)) >= 0) { anyChange = true; System.arraycopy(source.data, source.offset+o, data, offset+o, vertSize); } } else { - if (ColumnDataPoint.compareDatapointPriority(source.get(o), get(o)) > 0) { + if (ColumnFormat.compareDatapointPriority(source.get(o), get(o)) > 0) { anyChange = true; System.arraycopy(source.data, source.offset+o, data, offset+o, vertSize); } @@ -100,7 +102,7 @@ public final class ColumnArrayView implements ColumnDataView { copyFrom(source); } else { for (int i=0; i. */ -package com.seibel.lod.core.a7.datatype.column; +package com.seibel.lod.core.a7.datatype.column.render; +import com.seibel.lod.core.a7.datatype.column.accessor.ColumnArrayView; import com.seibel.lod.core.builders.lodBuilding.bufferBuilding.LodQuadBuilder; import com.seibel.lod.core.enums.ELodDirection; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderBuffer.java b/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnRenderBuffer.java similarity index 97% rename from src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderBuffer.java rename to src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnRenderBuffer.java index 6ff4e56c2..ef5877674 100644 --- a/src/main/java/com/seibel/lod/core/a7/datatype/column/ColumnRenderBuffer.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/column/render/ColumnRenderBuffer.java @@ -1,6 +1,8 @@ -package com.seibel.lod.core.a7.datatype.column; +package com.seibel.lod.core.a7.datatype.column.render; -import com.seibel.lod.core.a7.UncheckedInterruptedException; +import com.seibel.lod.core.a7.datatype.column.ColumnRenderSource; +import com.seibel.lod.core.a7.datatype.column.accessor.ColumnArrayView; +import com.seibel.lod.core.a7.util.UncheckedInterruptedException; import com.seibel.lod.core.a7.render.RenderBuffer; import com.seibel.lod.core.config.Config; import com.seibel.lod.core.api.internal.ClientApi; @@ -180,7 +182,7 @@ public class ColumnRenderBuffer extends RenderBuffer { } - public static CompletableFuture build(ColumnRenderBuffer usedBuffer, ColumnDatatype data, ColumnDatatype[] adjData) { + public static CompletableFuture build(ColumnRenderBuffer usedBuffer, ColumnRenderSource data, ColumnRenderSource[] adjData) { EVENT_LOGGER.trace("RenderRegion startBuild @ {}", data.sectionPos); return CompletableFuture.supplyAsync(() -> { try { @@ -236,7 +238,7 @@ public class ColumnRenderBuffer extends RenderBuffer { - private static void makeLodRenderData(LodQuadBuilder quadBuilder, ColumnDatatype region, ColumnDatatype[] adjRegions) { + private static void makeLodRenderData(LodQuadBuilder quadBuilder, ColumnRenderSource region, ColumnRenderSource[] adjRegions) { // Variable initialization EDebugMode debugMode = Config.Client.Advanced.Debugging.debugMode.get(); @@ -274,7 +276,7 @@ public class ColumnRenderBuffer extends RenderBuffer { int zAdj = z + lodDirection.getNormal().z; boolean isCrossRegionBoundary = (xAdj < 0 || xAdj >= dataSize) || (zAdj < 0 || zAdj >= dataSize); - ColumnDatatype adjRegion; + ColumnRenderSource adjRegion; byte adjDetail; //we check if the detail of the adjPos is equal to the correct one (region border fix) diff --git a/src/main/java/com/seibel/lod/core/a7/data/Data.java b/src/main/java/com/seibel/lod/core/a7/datatype/full/Data.java similarity index 96% rename from src/main/java/com/seibel/lod/core/a7/data/Data.java rename to src/main/java/com/seibel/lod/core/a7/datatype/full/Data.java index 4a7303fb6..16dc84e10 100644 --- a/src/main/java/com/seibel/lod/core/a7/data/Data.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/full/Data.java @@ -1,4 +1,4 @@ -package com.seibel.lod.core.a7.data; +package com.seibel.lod.core.a7.datatype.full; // Static class for the data format: // ID: blockState id Y: Height(signed) DP: Depth(signed?) diff --git a/src/main/java/com/seibel/lod/core/a7/DhChunk.java b/src/main/java/com/seibel/lod/core/a7/datatype/full/DhChunk.java similarity index 97% rename from src/main/java/com/seibel/lod/core/a7/DhChunk.java rename to src/main/java/com/seibel/lod/core/a7/datatype/full/DhChunk.java index cb53a53da..7f098212b 100644 --- a/src/main/java/com/seibel/lod/core/a7/DhChunk.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/full/DhChunk.java @@ -1,4 +1,4 @@ -package com.seibel.lod.core.a7; +package com.seibel.lod.core.a7.datatype.full; import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; diff --git a/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDatatype.java b/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDatatype.java deleted file mode 100644 index 826ab55ad..000000000 --- a/src/main/java/com/seibel/lod/core/a7/datatype/full/FullDatatype.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.seibel.lod.core.a7.datatype.full; - -import com.seibel.lod.core.a7.data.DataSourceLoader; -import com.seibel.lod.core.a7.data.LodDataSource; -import com.seibel.lod.core.a7.pos.DhSectionPos; - -public class FullDatatype implements LodDataSource { - @Override - public DataSourceLoader getLatestLoader() { - return null; - } - - @Override - public DhSectionPos getSectionPos() { - return null; - } - - @Override - public byte getDataDetail() { - return 0; - } -} diff --git a/src/main/java/com/seibel/lod/core/a7/data/CompleteDataContainer.java b/src/main/java/com/seibel/lod/core/a7/datatype/full/FullFormat.java similarity index 54% rename from src/main/java/com/seibel/lod/core/a7/data/CompleteDataContainer.java rename to src/main/java/com/seibel/lod/core/a7/datatype/full/FullFormat.java index d98214cbe..3a8d28bc4 100644 --- a/src/main/java/com/seibel/lod/core/a7/data/CompleteDataContainer.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/full/FullFormat.java @@ -1,25 +1,25 @@ -package com.seibel.lod.core.a7.data; +package com.seibel.lod.core.a7.datatype.full; -import com.seibel.lod.core.a7.IdMappingUtil; +import com.seibel.lod.core.a7.level.ILevel; +import com.seibel.lod.core.a7.save.io.file.DataMetaFile; +import com.seibel.lod.core.a7.datatype.LodDataSource; +import com.seibel.lod.core.a7.util.IdMappingUtil; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; +import java.io.IOException; +import java.io.OutputStream; import java.util.ArrayList; import java.util.HashMap; -public class CompleteDataContainer implements LodDataSource { // 1 chunk +public class FullFormat implements LodDataSource { // 1 chunk private DhSectionPos sectionPos; ArrayList idMap; - protected CompleteDataContainer() { + protected FullFormat() { idMap = new ArrayList(); } - @Override - public DataSourceLoader getLatestLoader() { - return null; - } - @Override public DhSectionPos getSectionPos() { return sectionPos; @@ -30,8 +30,23 @@ public class CompleteDataContainer implements LodDataSource { // 1 chunk return 0; } - public static CompleteDataContainer createNewFromChunk(IChunkWrapper chunk) { - CompleteDataContainer dataContainer = new CompleteDataContainer(); + @Override + public void setLocalVersion(int localVer) { + + } + + @Override + public byte getDataVersion() { + return 0; + } + + @Override + public void saveData(ILevel level, DataMetaFile file, OutputStream dataStream) throws IOException { + + } + + public static FullFormat createNewFromChunk(IChunkWrapper chunk) { + FullFormat dataContainer = new FullFormat(); HashMap idMap = new HashMap(); idMap.put(IdMappingUtil.BLOCKSTATE_ID_AIR, 0); diff --git a/src/main/java/com/seibel/lod/core/a7/ProtoSection.java b/src/main/java/com/seibel/lod/core/a7/datatype/full/ProtoSection.java similarity index 85% rename from src/main/java/com/seibel/lod/core/a7/ProtoSection.java rename to src/main/java/com/seibel/lod/core/a7/datatype/full/ProtoSection.java index 796a3b820..8bc6886f7 100644 --- a/src/main/java/com/seibel/lod/core/a7/ProtoSection.java +++ b/src/main/java/com/seibel/lod/core/a7/datatype/full/ProtoSection.java @@ -1,5 +1,6 @@ -package com.seibel.lod.core.a7; +package com.seibel.lod.core.a7.datatype.full; +import com.seibel.lod.core.a7.render.LodSection; import com.seibel.lod.core.wrapperInterfaces.block.IBlockDetailWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; diff --git a/src/main/java/com/seibel/lod/core/a7/level/DhClientLevel.java b/src/main/java/com/seibel/lod/core/a7/level/DhClientLevel.java index 4b24aee5b..fadc156c7 100644 --- a/src/main/java/com/seibel/lod/core/a7/level/DhClientLevel.java +++ b/src/main/java/com/seibel/lod/core/a7/level/DhClientLevel.java @@ -1,7 +1,7 @@ package com.seibel.lod.core.a7.level; -import com.seibel.lod.core.a7.LodQuadTree; -import com.seibel.lod.core.a7.save.io.FileScanner; +import com.seibel.lod.core.a7.render.LodQuadTree; +import com.seibel.lod.core.a7.util.FileScanner; import com.seibel.lod.core.a7.save.io.file.RemoteDataFileHandler; import com.seibel.lod.core.a7.save.io.render.RenderFileHandler; import com.seibel.lod.core.a7.pos.DhBlockPos2D; @@ -15,7 +15,6 @@ 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 java.util.Scanner; import java.util.concurrent.CompletableFuture; public class DhClientLevel implements IClientLevel { @@ -49,12 +48,6 @@ public class DhClientLevel implements IClientLevel { //TODO } - @Override - public void startRenderer() { - //TODO - - } - @Override public void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler) { if (renderer == null) { @@ -63,12 +56,6 @@ public class DhClientLevel implements IClientLevel { renderer.drawLODs(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler); } - @Override - public void stopRenderer() { - //TODO - - } - @Override public RenderBufferHandler getRenderBufferHandler() { return renderBufferHandler; 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 c4ebd5bef..0c171f043 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 @@ -1,7 +1,7 @@ package com.seibel.lod.core.a7.level; -import com.seibel.lod.core.a7.LodQuadTree; -import com.seibel.lod.core.a7.save.io.FileScanner; +import com.seibel.lod.core.a7.render.LodQuadTree; +import com.seibel.lod.core.a7.util.FileScanner; import com.seibel.lod.core.a7.save.io.file.LocalDataFileHandler; import com.seibel.lod.core.a7.save.io.render.RenderFileHandler; import com.seibel.lod.core.a7.pos.DhBlockPos2D; @@ -38,12 +38,14 @@ public class DhClientServerLevel implements IClientLevel, IServerLevel { FileScanner.scanFile(save, level, dataFileHandler, renderFileHandler); } - public void tick() { + public void clientTick() { tree.tick(new DhBlockPos2D(MC_CLIENT.getPlayerBlockPos())); renderBufferHandler.update(); } - @Override + public void serverTick() { + //TODO Update network packet and stuff or state or etc.. + } public void startRenderer() { //TODO } @@ -56,7 +58,6 @@ public class DhClientServerLevel implements IClientLevel, IServerLevel { renderer.drawLODs(mcModelViewMatrix, mcProjectionMatrix, partialTicks, profiler); } - @Override public void stopRenderer() { renderFileHandler.flushAndSave(); //Ignore the completion feature so that this action is async //TODO diff --git a/src/main/java/com/seibel/lod/core/a7/level/DhServerLevel.java b/src/main/java/com/seibel/lod/core/a7/level/DhServerLevel.java index bb3df023a..51383db09 100644 --- a/src/main/java/com/seibel/lod/core/a7/level/DhServerLevel.java +++ b/src/main/java/com/seibel/lod/core/a7/level/DhServerLevel.java @@ -1,6 +1,6 @@ package com.seibel.lod.core.a7.level; -import com.seibel.lod.core.a7.save.io.FileScanner; +import com.seibel.lod.core.a7.util.FileScanner; import com.seibel.lod.core.a7.save.io.file.LocalDataFileHandler; import com.seibel.lod.core.a7.save.structure.LocalSaveStructure; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; @@ -19,7 +19,7 @@ public class DhServerLevel implements IServerLevel { FileScanner.scanFile(save, level, dataFileHandler, null); } - public void tick() { + public void serverTick() { //Nothing for now } diff --git a/src/main/java/com/seibel/lod/core/a7/level/IClientLevel.java b/src/main/java/com/seibel/lod/core/a7/level/IClientLevel.java index 7880b00df..86a3c09cd 100644 --- a/src/main/java/com/seibel/lod/core/a7/level/IClientLevel.java +++ b/src/main/java/com/seibel/lod/core/a7/level/IClientLevel.java @@ -5,9 +5,9 @@ import com.seibel.lod.core.objects.math.Mat4f; import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper; public interface IClientLevel extends ILevel { - void startRenderer(); + void clientTick(); + void render(Mat4f mcModelViewMatrix, Mat4f mcProjectionMatrix, float partialTicks, IProfilerWrapper profiler); - void stopRenderer(); RenderBufferHandler getRenderBufferHandler(); } diff --git a/src/main/java/com/seibel/lod/core/a7/level/IServerLevel.java b/src/main/java/com/seibel/lod/core/a7/level/IServerLevel.java index c910f7fa0..844c6a21a 100644 --- a/src/main/java/com/seibel/lod/core/a7/level/IServerLevel.java +++ b/src/main/java/com/seibel/lod/core/a7/level/IServerLevel.java @@ -1,5 +1,6 @@ package com.seibel.lod.core.a7.level; public interface IServerLevel extends ILevel { + void serverTick(); void doWorldGen(); } diff --git a/src/main/java/com/seibel/lod/core/a7/render/EmptyRenderContainer.java b/src/main/java/com/seibel/lod/core/a7/render/EmptyRenderContainer.java deleted file mode 100644 index 6422c92e2..000000000 --- a/src/main/java/com/seibel/lod/core/a7/render/EmptyRenderContainer.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.seibel.lod.core.a7.render; - -import com.seibel.lod.core.a7.LodQuadTree; - -import java.util.concurrent.atomic.AtomicReference; - -public class EmptyRenderContainer implements RenderDataSource { - public static final EmptyRenderContainer INSTANCE = new EmptyRenderContainer(); - - // NOTE: No register() needed since this should never be loaded from a actual data. - - - @Override - public void enableRender(LodQuadTree quadTree) { - - } - - @Override - public void disableRender() { - - } - - @Override - public boolean isRenderReady() { - return false; - } - - @Override - public void dispose() { - - } - - @Override - public byte getDetailOffset() { - return 0; - } - - @Override - public boolean trySwapRenderBuffer(LodQuadTree quadTree, AtomicReference referenceSlot) { - return false; // no swap - } -} diff --git a/src/main/java/com/seibel/lod/core/a7/LodQuadTree.java b/src/main/java/com/seibel/lod/core/a7/render/LodQuadTree.java similarity index 94% rename from src/main/java/com/seibel/lod/core/a7/LodQuadTree.java rename to src/main/java/com/seibel/lod/core/a7/render/LodQuadTree.java index 525c63061..30e2828e7 100644 --- a/src/main/java/com/seibel/lod/core/a7/LodQuadTree.java +++ b/src/main/java/com/seibel/lod/core/a7/render/LodQuadTree.java @@ -1,9 +1,9 @@ -package com.seibel.lod.core.a7; +package com.seibel.lod.core.a7.render; -import com.seibel.lod.core.a7.datatype.column.ColumnDatatype; +import com.seibel.lod.core.a7.datatype.RenderSourceLoader; import com.seibel.lod.core.a7.pos.DhBlockPos2D; import com.seibel.lod.core.a7.pos.DhSectionPos; -import com.seibel.lod.core.a7.render.RenderDataSourceLoader; +import com.seibel.lod.core.a7.save.io.render.IRenderSourceProvider; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.util.DetailDistanceUtil; import com.seibel.lod.core.util.LodUtil; @@ -34,11 +34,11 @@ public class LodQuadTree { public final byte startingSectionLevel; private final MovableGridRingList[] ringLists; - static final ArrayList layerLoaderConfig = new ArrayList<>(); + static final ArrayList layerLoaderConfig = new ArrayList<>(); static final Logger LOGGER = DhLoggerBuilder.getLogger("LodQuadTree"); - public static void registerLayerLoader(RenderDataSourceLoader loader, byte sectionLevel) { + public static void registerLayerLoader(RenderSourceLoader loader, byte sectionLevel) { LOGGER.info("Registering loader for section level " + sectionLevel + " for " + loader.getClass().getSimpleName()); while (layerLoaderConfig.size() <= sectionLevel) { layerLoaderConfig.add(null); @@ -65,8 +65,8 @@ public class LodQuadTree { static class SectionDetailLayer { final byte targetDataDetail; - final RenderDataSourceLoader containerType; - public SectionDetailLayer(byte targetDataDetail, RenderDataSourceLoader containerType) { + final RenderSourceLoader containerType; + public SectionDetailLayer(byte targetDataDetail, RenderSourceLoader containerType) { this.targetDataDetail = targetDataDetail; this.containerType = containerType; } @@ -77,7 +77,7 @@ public class LodQuadTree { for (int i = 0; i < layerLoaderConfig.size(); i++) { if (layerLoaderConfig.get(i) == null) continue; isInFront = false; - RenderDataSourceLoader entry = layerLoaderConfig.get(i); + RenderSourceLoader entry = layerLoaderConfig.get(i); if (i - entry.detailOffset < 0) { throw new RuntimeException("ContainerTypeConfigEntry " + i + " has a levelOffset of " + entry.detailOffset + " which makes the dataDetail be " + (i - entry.detailOffset) + "," + @@ -95,7 +95,7 @@ public class LodQuadTree { final SectionDetailLayer[] sectionDetailLayers; public final int viewDistance; - private final RenderDataProvider renderDataProvider; + private final IRenderSourceProvider renderSourceProvider; /** * Constructor of the quadTree @@ -103,9 +103,8 @@ public class LodQuadTree { * @param initialPlayerX player x coordinate * @param initialPlayerZ player z coordinate */ - public LodQuadTree(int viewDistance, int initialPlayerX, int initialPlayerZ, RenderDataProvider provider) { - ColumnDatatype.REGISTER(); //FIXME: This is a hack to make sure the datatype is registered - renderDataProvider = provider; + public LodQuadTree(int viewDistance, int initialPlayerX, int initialPlayerZ, IRenderSourceProvider provider) { + renderSourceProvider = provider; assertContainerTypeConfigCorrect(); this.viewDistance = viewDistance; @@ -113,7 +112,7 @@ public class LodQuadTree { //FIXME: Rework this mess of code! { // Calculate the max section detail byte maxDetailLevel = getMaxDetailInRange(viewDistance * Math.sqrt(2)); - RenderDataSourceLoader finalEntry = null; + RenderSourceLoader finalEntry = null; byte topSectionLevel = 0; byte firstLevel = -1; for (; topSectionLevel < layerLoaderConfig.size(); topSectionLevel++) { @@ -137,7 +136,7 @@ public class LodQuadTree { byte lastNonNullEntry = -1; for (byte i = startingSectionLevel; i < numbersOfSectionLevels; i++) { byte targetDataDetail; - RenderDataSourceLoader containerType; + RenderSourceLoader containerType; if (i < layerLoaderConfig.size()) { if (layerLoaderConfig.get(i) == null) { @@ -146,14 +145,14 @@ public class LodQuadTree { containerType = null; } else { lastNonNullEntry = i; - RenderDataSourceLoader entry = layerLoaderConfig.get(i); + RenderSourceLoader entry = layerLoaderConfig.get(i); targetDataDetail = (byte) (i - entry.detailOffset); containerType = entry; } } else { LodUtil.assertTrue(layerLoaderConfig.get(layerLoaderConfig.size() - 1) != null, "The last entry must not be null!"); - RenderDataSourceLoader entry = layerLoaderConfig.get(layerLoaderConfig.size() - 1); + RenderSourceLoader entry = layerLoaderConfig.get(layerLoaderConfig.size() - 1); targetDataDetail = (byte) (i - entry.detailOffset); containerType = entry; } @@ -326,7 +325,7 @@ public class LodQuadTree { final MovableGridRingList parentRingList = sectLevel == numbersOfSectionLevels - 1 ? null : ringLists[sectLevel - startingSectionLevel + 1]; final byte f_sectLevel = sectLevel; - RenderDataSourceLoader containerType = sectionDetailLayers[sectLevel - startingSectionLevel].containerType; + RenderSourceLoader containerType = sectionDetailLayers[sectLevel - startingSectionLevel].containerType; ringList.forEachPosOrdered((section, pos) -> { if (f_sectLevel == 0 && section != null) { section.childCount = 0; @@ -418,7 +417,7 @@ public class LodQuadTree { final MovableGridRingList childRingList = sectLevel == startingSectionLevel ? null : ringLists[sectLevel - startingSectionLevel - 1]; final boolean doCacsade = sectionDetailLayers[sectLevel - startingSectionLevel].containerType == null; - RenderDataSourceLoader containerType = sectionDetailLayers[sectLevel - startingSectionLevel].containerType; + RenderSourceLoader containerType = sectionDetailLayers[sectLevel - startingSectionLevel].containerType; ringList.forEachPosOrdered((section, pos) -> { if (section == null) return; @@ -464,7 +463,7 @@ public class LodQuadTree { section.dispose(); } else { if (!section.isLoaded() && !section.isLoading()) { - section.load(renderDataProvider, containerType); + section.load(renderSourceProvider, containerType); } if (section.childCount == 4) section.enableRender(this); if (section.childCount == 0) section.disableRender(); diff --git a/src/main/java/com/seibel/lod/core/a7/LodSection.java b/src/main/java/com/seibel/lod/core/a7/render/LodSection.java similarity index 57% rename from src/main/java/com/seibel/lod/core/a7/LodSection.java rename to src/main/java/com/seibel/lod/core/a7/render/LodSection.java index dc90c1108..aae566aa5 100644 --- a/src/main/java/com/seibel/lod/core/a7/LodSection.java +++ b/src/main/java/com/seibel/lod/core/a7/render/LodSection.java @@ -1,8 +1,9 @@ -package com.seibel.lod.core.a7; +package com.seibel.lod.core.a7.render; +import com.seibel.lod.core.a7.datatype.RenderSourceLoader; import com.seibel.lod.core.a7.pos.DhSectionPos; -import com.seibel.lod.core.a7.render.RenderDataSource; -import com.seibel.lod.core.a7.render.RenderDataSourceLoader; +import com.seibel.lod.core.a7.datatype.LodRenderSource; +import com.seibel.lod.core.a7.save.io.render.IRenderSourceProvider; import java.util.concurrent.CompletableFuture; @@ -17,8 +18,8 @@ public class LodSection { public byte childCount = 0; // TODO: Should I provide a way to change the render source? - private RenderDataSource renderDataSource; - private CompletableFuture loadFuture; + private LodRenderSource lodRenderSource; + private CompletableFuture loadFuture; private boolean isRenderEnabled = false; // Create sub region @@ -28,56 +29,56 @@ public class LodSection { public void enableRender(LodQuadTree quadTree) { if (isRenderEnabled) return; - if (renderDataSource != null) { - renderDataSource.enableRender(quadTree); + if (lodRenderSource != null) { + lodRenderSource.enableRender(quadTree); } isRenderEnabled = true; } public void disableRender() { if (!isRenderEnabled) return; - if (renderDataSource != null) { - renderDataSource.disableRender(); + if (lodRenderSource != null) { + lodRenderSource.disableRender(); } isRenderEnabled = false; } - public void load(RenderDataProvider renderDataProvider, RenderDataSourceLoader renderDataSourceClass) { - if (loadFuture != null || renderDataSource != null) throw new IllegalStateException("Reloading is not supported!"); + public void load(IRenderSourceProvider renderDataProvider, RenderSourceLoader renderDataSourceClass) { + if (loadFuture != null || lodRenderSource != null) throw new IllegalStateException("Reloading is not supported!"); loadFuture = renderDataProvider.createRenderData(renderDataSourceClass, pos); } public void tick(LodQuadTree quadTree) { if (loadFuture != null && loadFuture.isDone()) { - renderDataSource = loadFuture.join(); + lodRenderSource = loadFuture.join(); loadFuture = null; if (isRenderEnabled) { - renderDataSource.enableRender(quadTree); + lodRenderSource.enableRender(quadTree); } } } public void dispose() { - if (renderDataSource != null) { - renderDataSource.dispose(); + if (lodRenderSource != null) { + lodRenderSource.dispose(); } else if (loadFuture != null) { loadFuture.cancel(true); } } public boolean canRender() { - return isLoaded() && renderDataSource.isRenderReady(); + return isLoaded() && lodRenderSource.isRenderReady(); } public boolean isLoaded() { - return renderDataSource != null; + return lodRenderSource != null; } public boolean isLoading() { return loadFuture != null; } - public RenderDataSource getRenderContainer() { - return renderDataSource; + public LodRenderSource getRenderContainer() { + return lodRenderSource; } } diff --git a/src/main/java/com/seibel/lod/core/a7/render/RenderBufferHandler.java b/src/main/java/com/seibel/lod/core/a7/render/RenderBufferHandler.java index cebb8a7d7..49f501711 100644 --- a/src/main/java/com/seibel/lod/core/a7/render/RenderBufferHandler.java +++ b/src/main/java/com/seibel/lod/core/a7/render/RenderBufferHandler.java @@ -1,8 +1,7 @@ package com.seibel.lod.core.a7.render; +import com.seibel.lod.core.a7.datatype.LodRenderSource; import com.seibel.lod.core.objects.Pos2D; -import com.seibel.lod.core.a7.LodQuadTree; -import com.seibel.lod.core.a7.LodSection; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.render.LodRenderProgram; import com.seibel.lod.core.util.LodUtil; @@ -45,7 +44,7 @@ public class RenderBufferHandler { // If this fails, there may be concurrent modification of the quad tree // (as this update() should be called from the same thread that calls update() on the quad tree) LodUtil.assertTrue(section != null); - RenderDataSource container = section.getRenderContainer(); + LodRenderSource container = section.getRenderContainer(); // Update self's render buffer state boolean shouldRender = section.isLoaded(); diff --git a/src/main/java/com/seibel/lod/core/a7/render/RenderDataSource.java b/src/main/java/com/seibel/lod/core/a7/render/RenderDataSource.java deleted file mode 100644 index d3134107c..000000000 --- a/src/main/java/com/seibel/lod/core/a7/render/RenderDataSource.java +++ /dev/null @@ -1,60 +0,0 @@ -package com.seibel.lod.core.a7.render; - -import com.seibel.lod.core.a7.LodQuadTree; - -import java.util.concurrent.atomic.AtomicReference; - -/** - * Example on how to register a loader: - *
-     public static RenderDataSource testAndConstruct(LodDataSource dataSource, DhSectionPos sectionPos) {
-        ColumnRenderContainer container = new ColumnRenderContainer(10, -100);
-        container.startFillData(dataSource);
-        return container;
-     }
-     static {
-        RenderDataSource.registorLoader(ColumnRenderContainer::testAndConstruct, 0);
-     }
- 
- */ -public interface RenderDataSource { - // Don't think this is needed with the newer quad tree structure... -// interface RenderContainerConstructor { -// // Can return null as meaning the requirement is not met -// RenderDataSource testAndConstruct(LodDataSource dataSource, DhSectionPos sectionPos); -// } -// SortedMap -// renderContainerLoaderRegistry = new TreeMap(); -// static void registorLoader(RenderContainerConstructor func, int priority) { -// if (func == null) { -// throw new IllegalArgumentException("loader must be non-null"); -// } -// renderContainerLoaderRegistry.put(priority, func); -// } -// -// static RenderDataSource tryConstruct(LodDataSource dataSource, DhSectionPos pos) { -// for (RenderContainerConstructor func : renderContainerLoaderRegistry.values()) { -// RenderDataSource container = func.testAndConstruct(dataSource, pos); -// if (container != null) { -// return container; -// } -// } -// return null; -// } - - void enableRender(LodQuadTree quadTree); - void disableRender(); - boolean isRenderReady(); - void dispose(); // notify the container that the parent lodSection is now disposed (can be in loaded or unloaded state) - - byte getDetailOffset(); - - /** - * Try and swap in new render buffer for this section. Note that before this call, there should be no other - * places storing or referencing the render buffer. - * @param referenceSlot The slot for swapping in the new buffer. - * @return True if the swap was successful. False if swap is not needed or if it is in progress. - */ - boolean trySwapRenderBuffer(LodQuadTree quadTree, AtomicReference referenceSlot); - -} diff --git a/src/main/java/com/seibel/lod/core/a7/render/RenderDataSourceLoader.java b/src/main/java/com/seibel/lod/core/a7/render/RenderDataSourceLoader.java deleted file mode 100644 index 90dc8e8fa..000000000 --- a/src/main/java/com/seibel/lod/core/a7/render/RenderDataSourceLoader.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.seibel.lod.core.a7.render; - -import com.seibel.lod.core.a7.data.LodDataSource; -import com.seibel.lod.core.a7.pos.DhSectionPos; -import com.seibel.lod.core.a7.level.DhClientServerLevel; -import com.seibel.lod.core.a7.data.DataFile; - -import java.util.*; -import java.util.stream.Collectors; - -public abstract class RenderDataSourceLoader { - public final int detailOffset; - public RenderDataSourceLoader(int detailOffset) { - this.detailOffset = detailOffset; - } - - public abstract RenderDataSource construct(List dataSources, DhSectionPos sectionPos, DhClientServerLevel level); - - public List selectFiles(DhSectionPos sectionPos, DhClientServerLevel level, List[] availableFiles) { - return Arrays.stream(availableFiles).flatMap(Collection::stream).collect(Collectors.toList()); - } - -} diff --git a/src/main/java/com/seibel/lod/core/a7/save/io/DHFolderHandler.java b/src/main/java/com/seibel/lod/core/a7/save/io/DHFolderHandler.java deleted file mode 100644 index 853975a68..000000000 --- a/src/main/java/com/seibel/lod/core/a7/save/io/DHFolderHandler.java +++ /dev/null @@ -1,105 +0,0 @@ -package com.seibel.lod.core.a7.save.io; - -import com.seibel.lod.core.config.Config; -import com.seibel.lod.core.enums.config.EServerFolderNameMode; -import com.seibel.lod.core.handlers.LodDimensionFinder; -import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; -import com.seibel.lod.core.logging.ConfigBasedLogger; -import com.seibel.lod.core.objects.ParsedIp; -import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import org.apache.logging.log4j.LogManager; - -import java.io.File; -import java.io.IOException; - -public class DHFolderHandler { - /** - * This regex finds any characters that are invalid for use in a windows - * (and by extension mac and linux) file path - */ - public static final String INVALID_FILE_CHARACTERS_REGEX = "[\\\\/:*?\"<>|]"; - private static final IMinecraftClientWrapper MC = SingletonHandler.get(IMinecraftClientWrapper.class); - public static final ConfigBasedLogger LOGGER = new ConfigBasedLogger(LogManager.getLogger(LodDimensionFinder.class), - () -> Config.Client.Advanced.Debugging.DebugSwitch.logFileSubDimEvent.get()); - - public static File getCurrentWorldFolder() { - File dimensionFolder; - try - { - if (MC.hasSinglePlayerServer()) - { - // local world - dimensionFolder = new File(MC.getSinglePlayerServerFolder(), "lod"); - } - else - { - // multiplayer world - dimensionFolder = new File(MC.getGameDirectory().getCanonicalFile().getPath() + - File.separatorChar + "Distant_Horizons_server_data" + File.separatorChar + getServerFolderName()); - } - } - catch (IOException e) - { - LOGGER.error("Unable to get world folder directory: ", e); - throw new RuntimeException("Critical error: Unable to get world folder directory", e); - } - - return dimensionFolder; - } - private static String getServerFolderName() - { - // parse the current server's IP - ParsedIp parsedIp = new ParsedIp(MC.getCurrentServerIp()); - String serverIpCleaned = parsedIp.ip.replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); - String serverPortCleaned = parsedIp.port != null ? parsedIp.port.replaceAll(INVALID_FILE_CHARACTERS_REGEX, "") : ""; - - - // determine the format of the folder name - EServerFolderNameMode folderNameMode = Config.Client.Multiplayer.serverFolderNameMode.get(); - if (folderNameMode == EServerFolderNameMode.AUTO) - { - if (parsedIp.isLan()) - { - // LAN - folderNameMode = EServerFolderNameMode.NAME_IP; - } - else - { - // normal multiplayer - folderNameMode = EServerFolderNameMode.NAME_IP_PORT; - } - } - String serverName = MC.getCurrentServerName().replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); - String serverMcVersion = MC.getCurrentServerVersion().replaceAll(INVALID_FILE_CHARACTERS_REGEX, ""); - // generate the folder name - String folderName = ""; - switch (folderNameMode) - { - // default and auto shouldn't be used - // and are just here to make the compiler happy - default: - case AUTO: - case NAME_ONLY: - folderName = serverName; - break; - - case NAME_IP: - folderName = serverName + ", IP " + serverIpCleaned; - break; - case NAME_IP_PORT: - folderName = serverName + ", IP " + serverIpCleaned + (serverPortCleaned.length() != 0 ? ("-" + serverPortCleaned) : ""); - break; - case NAME_IP_PORT_MC_VERSION: - folderName = serverName + ", IP " + serverIpCleaned + (serverPortCleaned.length() != 0 ? ("-" + serverPortCleaned) : "") + ", GameVersion " + serverMcVersion; - break; - } - - return folderName; - } - - - - - - -} diff --git a/src/main/java/com/seibel/lod/core/a7/save/io/MetaFile.java b/src/main/java/com/seibel/lod/core/a7/save/io/MetaFile.java index 0a042b93c..e033ef91c 100644 --- a/src/main/java/com/seibel/lod/core/a7/save/io/MetaFile.java +++ b/src/main/java/com/seibel/lod/core/a7/save/io/MetaFile.java @@ -12,7 +12,7 @@ import java.util.function.BiConsumer; import java.util.zip.Adler32; import java.util.zip.CheckedOutputStream; -import com.seibel.lod.core.a7.data.DataSourceLoader; +import com.seibel.lod.core.a7.datatype.DataSourceLoader; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.util.LodUtil; @@ -49,7 +49,7 @@ public class MetaFile { //Loader stuff public DataSourceLoader loader; public Class dataType; - public byte loaderVersion; + public byte dataVersion; // Load a metaFile in this path. It also automatically read the metadata. protected MetaFile(File path) throws IOException { @@ -80,7 +80,7 @@ public class MetaFile { throw new IOException("Invalid file: Data type loader not found: " + dataTypeId + "(v" + loaderVersion + ")"); } this.dataType = loader.clazz; - this.loaderVersion = loaderVersion; + this.dataVersion = loaderVersion; } } @@ -128,7 +128,7 @@ public class MetaFile { throw new IOException("Invalid file: Data type loader not found: " + dataTypeId + "(v" + loaderVersion + ")"); } this.dataType = loader.clazz; - this.loaderVersion = loaderVersion; + this.dataVersion = loaderVersion; } } @@ -159,7 +159,7 @@ public class MetaFile { buff.putInt(checksum); buff.put(pos.sectionDetail); buff.put(dataLevel); - buff.put(loaderVersion); + buff.put(dataVersion); buff.put(Byte.MIN_VALUE); // Unused buff.putLong(loader.datatypeId); buff.putLong(timestamp); diff --git a/src/main/java/com/seibel/lod/core/a7/save/io/file/DataMetaFile.java b/src/main/java/com/seibel/lod/core/a7/save/io/file/DataMetaFile.java index c36c95f3a..f0ad1851e 100644 --- a/src/main/java/com/seibel/lod/core/a7/save/io/file/DataMetaFile.java +++ b/src/main/java/com/seibel/lod/core/a7/save/io/file/DataMetaFile.java @@ -9,17 +9,14 @@ import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantReadWriteLock; -import java.util.function.BiConsumer; -import com.seibel.lod.core.a7.data.DataSourceLoader; -import com.seibel.lod.core.a7.data.LodDataSource; -import com.seibel.lod.core.a7.datatype.full.FullDatatype; +import com.seibel.lod.core.a7.datatype.LodDataSource; +import com.seibel.lod.core.a7.datatype.DataSourceLoader; +import com.seibel.lod.core.a7.datatype.full.Data; import com.seibel.lod.core.a7.save.io.MetaFile; import com.seibel.lod.core.a7.level.ILevel; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.logging.DhLoggerBuilder; -import com.seibel.lod.core.a7.datatype.column.DataSourceSaver; -import com.seibel.lod.core.a7.datatype.column.OldDataSourceLoader; import com.seibel.lod.core.util.LodUtil; import org.apache.logging.log4j.Logger; @@ -39,13 +36,13 @@ public class DataMetaFile extends MetaFile { //TODO: use ConcurrentAppendSingleSwapContainer instead of below: private static class GuardedMultiAppendQueue { ReentrantReadWriteLock appendLock = new ReentrantReadWriteLock(); - ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>(); + ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>(); } AtomicReference writeQueue = new AtomicReference<>(new GuardedMultiAppendQueue()); GuardedMultiAppendQueue _backQueue = new GuardedMultiAppendQueue(); - public void addToWriteQueue(FullDatatype datatype) { + public void addToWriteQueue(Data datatype) { GuardedMultiAppendQueue queue = writeQueue.get(); // Using read lock is OK, because the queue's underlying data structure is thread-safe. // This lock is only used to insure on polling the queue, that the queue is not being @@ -205,25 +202,18 @@ public class DataMetaFile extends MetaFile { } private void write(LodDataSource data) { - DataSourceSaver saver; - if (loader instanceof DataSourceSaver) saver = (DataSourceSaver) loader; - else if (loader instanceof OldDataSourceLoader) saver = ((OldDataSourceLoader) loader).getNewSaver(); - else saver = null; - if (saver == null) return; - - BiConsumer dataWriter = (meta, out) -> { - meta.dataLevel = data.getDataDetail(); - meta.dataType = DataSourceLoader.datatypeIdRegistry.get(saver.datatypeId); - meta.loader = saver; - meta.loaderVersion = saver.getSaverVersion(); - try { - saver.saveData(level, data, this, out); - } catch (IOException e) { - LOGGER.error("Failed to save data for file {}", path, e); - } - }; try { - super.writeData(dataWriter); + super.writeData((meta, out) -> { + meta.dataLevel = data.getDataDetail(); + meta.dataType = data.getClass(); + meta.loader = DataSourceLoader.getLoader(data.getClass(), data.getDataVersion()); + meta.dataVersion = data.getDataVersion(); + try { + data.saveData(level, this, out); + } catch (IOException e) { + LOGGER.error("Failed to save data for file {}", path, e); + } + }); } catch (IOException e) { LOGGER.error("Failed to write data for file {}", path, e); } diff --git a/src/main/java/com/seibel/lod/core/a7/save/io/file/DataSourceProvider.java b/src/main/java/com/seibel/lod/core/a7/save/io/file/IDataSourceProvider.java similarity index 60% rename from src/main/java/com/seibel/lod/core/a7/save/io/file/DataSourceProvider.java rename to src/main/java/com/seibel/lod/core/a7/save/io/file/IDataSourceProvider.java index 392bdffc8..feb45b62c 100644 --- a/src/main/java/com/seibel/lod/core/a7/save/io/file/DataSourceProvider.java +++ b/src/main/java/com/seibel/lod/core/a7/save/io/file/IDataSourceProvider.java @@ -1,17 +1,17 @@ package com.seibel.lod.core.a7.save.io.file; -import com.seibel.lod.core.a7.data.LodDataSource; -import com.seibel.lod.core.a7.datatype.full.FullDatatype; +import com.seibel.lod.core.a7.datatype.LodDataSource; +import com.seibel.lod.core.a7.datatype.full.Data; import com.seibel.lod.core.a7.pos.DhSectionPos; import java.io.File; import java.util.Collection; import java.util.concurrent.CompletableFuture; -public interface DataSourceProvider extends AutoCloseable { +public interface IDataSourceProvider extends AutoCloseable { void addScannedFile(Collection detectedFiles); CompletableFuture read(DhSectionPos pos); - void write(DhSectionPos sectionPos, FullDatatype chunkData); + void write(DhSectionPos sectionPos, Data chunkData); CompletableFuture flushAndSave(); } diff --git a/src/main/java/com/seibel/lod/core/a7/save/io/file/LocalDataFileHandler.java b/src/main/java/com/seibel/lod/core/a7/save/io/file/LocalDataFileHandler.java index e7b997191..d8a55a9ed 100644 --- a/src/main/java/com/seibel/lod/core/a7/save/io/file/LocalDataFileHandler.java +++ b/src/main/java/com/seibel/lod/core/a7/save/io/file/LocalDataFileHandler.java @@ -1,8 +1,8 @@ package com.seibel.lod.core.a7.save.io.file; import com.google.common.collect.HashMultimap; -import com.seibel.lod.core.a7.data.LodDataSource; -import com.seibel.lod.core.a7.datatype.full.FullDatatype; +import com.seibel.lod.core.a7.datatype.LodDataSource; +import com.seibel.lod.core.a7.datatype.full.Data; import com.seibel.lod.core.a7.level.IServerLevel; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.logging.DhLoggerBuilder; @@ -19,7 +19,7 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutorService; -public class LocalDataFileHandler implements DataSourceProvider { +public class LocalDataFileHandler implements IDataSourceProvider { // Note: Single main thread only for now. May make it multi-thread later, depending on the usage. ExecutorService fileReaderThread = LodUtil.makeSingleThreadPool("FileReaderThread"); Logger logger = DhLoggerBuilder.getLogger("LocalDataFileHandler"); @@ -110,7 +110,7 @@ public class LocalDataFileHandler implements DataSourceProvider { * This call is concurrent. I.e. it supports multiple threads calling this method at the same time. */ @Override - public void write(DhSectionPos sectionPos, FullDatatype chunkData) { + public void write(DhSectionPos sectionPos, Data chunkData) { DataMetaFile metaFile = files.get(sectionPos); if (metaFile != null) { // Fast path: if there is a file for this section, just write to it. metaFile.addToWriteQueue(chunkData); diff --git a/src/main/java/com/seibel/lod/core/a7/save/io/file/RemoteDataFileHandler.java b/src/main/java/com/seibel/lod/core/a7/save/io/file/RemoteDataFileHandler.java index 52884803e..5a5d34c64 100644 --- a/src/main/java/com/seibel/lod/core/a7/save/io/file/RemoteDataFileHandler.java +++ b/src/main/java/com/seibel/lod/core/a7/save/io/file/RemoteDataFileHandler.java @@ -1,14 +1,14 @@ package com.seibel.lod.core.a7.save.io.file; -import com.seibel.lod.core.a7.data.LodDataSource; -import com.seibel.lod.core.a7.datatype.full.FullDatatype; +import com.seibel.lod.core.a7.datatype.LodDataSource; +import com.seibel.lod.core.a7.datatype.full.Data; import com.seibel.lod.core.a7.pos.DhSectionPos; import java.io.File; import java.util.Collection; import java.util.concurrent.CompletableFuture; -public class RemoteDataFileHandler implements DataSourceProvider { +public class RemoteDataFileHandler implements IDataSourceProvider { @Override public void addScannedFile(Collection detectedFiles) { @@ -20,7 +20,7 @@ public class RemoteDataFileHandler implements DataSourceProvider { } @Override - public void write(DhSectionPos sectionPos, FullDatatype chunkData) { + public void write(DhSectionPos sectionPos, Data chunkData) { } diff --git a/src/main/java/com/seibel/lod/core/a7/save/io/render/RenderSourceProvider.java b/src/main/java/com/seibel/lod/core/a7/save/io/render/IRenderSourceProvider.java similarity index 53% rename from src/main/java/com/seibel/lod/core/a7/save/io/render/RenderSourceProvider.java rename to src/main/java/com/seibel/lod/core/a7/save/io/render/IRenderSourceProvider.java index 4d9b508ae..63430309f 100644 --- a/src/main/java/com/seibel/lod/core/a7/save/io/render/RenderSourceProvider.java +++ b/src/main/java/com/seibel/lod/core/a7/save/io/render/IRenderSourceProvider.java @@ -1,15 +1,14 @@ package com.seibel.lod.core.a7.save.io.render; -import com.seibel.lod.core.a7.RenderDataProvider; -import com.seibel.lod.core.a7.datatype.full.FullDatatype; +import com.seibel.lod.core.a7.datatype.full.Data; import com.seibel.lod.core.a7.pos.DhSectionPos; import java.io.File; import java.util.Collection; import java.util.concurrent.CompletableFuture; -public interface RenderSourceProvider extends RenderDataProvider, AutoCloseable { +public interface IRenderSourceProvider extends AutoCloseable { void addScannedFile(Collection detectedFiles); - void write(DhSectionPos sectionPos, FullDatatype chunkData); + void write(DhSectionPos sectionPos, Data chunkData); CompletableFuture flushAndSave(); } diff --git a/src/main/java/com/seibel/lod/core/a7/save/io/render/RenderFileHandler.java b/src/main/java/com/seibel/lod/core/a7/save/io/render/RenderFileHandler.java index 923856353..ef687baf9 100644 --- a/src/main/java/com/seibel/lod/core/a7/save/io/render/RenderFileHandler.java +++ b/src/main/java/com/seibel/lod/core/a7/save/io/render/RenderFileHandler.java @@ -1,11 +1,11 @@ package com.seibel.lod.core.a7.save.io.render; -import com.seibel.lod.core.a7.datatype.full.FullDatatype; -import com.seibel.lod.core.a7.save.io.file.DataSourceProvider; +import com.seibel.lod.core.a7.datatype.RenderSourceLoader; +import com.seibel.lod.core.a7.datatype.full.Data; +import com.seibel.lod.core.a7.save.io.file.IDataSourceProvider; import com.seibel.lod.core.a7.pos.DhSectionPos; import com.seibel.lod.core.logging.DhLoggerBuilder; -import com.seibel.lod.core.a7.render.RenderDataSource; -import com.seibel.lod.core.a7.render.RenderDataSourceLoader; +import com.seibel.lod.core.a7.datatype.LodRenderSource; import com.seibel.lod.core.util.LodUtil; import org.apache.logging.log4j.Logger; @@ -14,19 +14,19 @@ import java.util.Collection; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; -public class RenderFileHandler implements RenderSourceProvider { +public class RenderFileHandler implements IRenderSourceProvider { final File renderCacheFolder; - final DataSourceProvider dataSourceProvider; + final IDataSourceProvider dataSourceProvider; ExecutorService renderCacheThread = LodUtil.makeSingleThreadPool("RenderCacheThread"); Logger logger = DhLoggerBuilder.getLogger("RenderCache"); - public RenderFileHandler(DataSourceProvider sourceProvider, File renderCacheFolder) { + public RenderFileHandler(IDataSourceProvider sourceProvider, File renderCacheFolder) { this.dataSourceProvider = sourceProvider; this.renderCacheFolder = renderCacheFolder; } @Override - public CompletableFuture createRenderData(RenderDataSourceLoader renderSourceLoader, DhSectionPos pos) { + public CompletableFuture createRenderData(RenderSourceLoader renderSourceLoader, DhSectionPos pos) { return null; } @@ -36,7 +36,7 @@ public class RenderFileHandler implements RenderSourceProvider { } @Override - public void write(DhSectionPos sectionPos, FullDatatype chunkData) { + public void write(DhSectionPos sectionPos, Data chunkData) { } diff --git a/src/main/java/com/seibel/lod/core/a7/save/io/FileScanner.java b/src/main/java/com/seibel/lod/core/a7/util/FileScanner.java similarity index 84% rename from src/main/java/com/seibel/lod/core/a7/save/io/FileScanner.java rename to src/main/java/com/seibel/lod/core/a7/util/FileScanner.java index 16e3642d4..32e6537f3 100644 --- a/src/main/java/com/seibel/lod/core/a7/save/io/FileScanner.java +++ b/src/main/java/com/seibel/lod/core/a7/util/FileScanner.java @@ -1,7 +1,7 @@ -package com.seibel.lod.core.a7.save.io; +package com.seibel.lod.core.a7.util; -import com.seibel.lod.core.a7.save.io.file.DataSourceProvider; -import com.seibel.lod.core.a7.save.io.render.RenderSourceProvider; +import com.seibel.lod.core.a7.save.io.file.IDataSourceProvider; +import com.seibel.lod.core.a7.save.io.render.IRenderSourceProvider; import com.seibel.lod.core.a7.save.structure.SaveStructure; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; @@ -19,8 +19,8 @@ public class FileScanner { public static final int MAX_SCAN_DEPTH = 5; public static final String LOD_FILE_POSTFIX = ".lod"; public static void scanFile(SaveStructure save, ILevelWrapper level, - @Nullable DataSourceProvider dataSource, - @Nullable RenderSourceProvider renderSource) { + @Nullable IDataSourceProvider dataSource, + @Nullable IRenderSourceProvider renderSource) { if (dataSource != null) { try (Stream pathStream = Files.walk(save.getDataFolder(level).toPath(), MAX_SCAN_DEPTH)) { dataSource.addScannedFile(pathStream.filter(( diff --git a/src/main/java/com/seibel/lod/core/a7/util/IOUtil.java b/src/main/java/com/seibel/lod/core/a7/util/IOUtil.java new file mode 100644 index 000000000..0f54d281c --- /dev/null +++ b/src/main/java/com/seibel/lod/core/a7/util/IOUtil.java @@ -0,0 +1,6 @@ +package com.seibel.lod.core.a7.util; + +public class IOUtil { + public static final String LOD_FILE_EXTENSION = ".lod"; + +} diff --git a/src/main/java/com/seibel/lod/core/a7/IdMappingUtil.java b/src/main/java/com/seibel/lod/core/a7/util/IdMappingUtil.java similarity index 74% rename from src/main/java/com/seibel/lod/core/a7/IdMappingUtil.java rename to src/main/java/com/seibel/lod/core/a7/util/IdMappingUtil.java index 974d24ec8..006df4fab 100644 --- a/src/main/java/com/seibel/lod/core/a7/IdMappingUtil.java +++ b/src/main/java/com/seibel/lod/core/a7/util/IdMappingUtil.java @@ -1,4 +1,4 @@ -package com.seibel.lod.core.a7; +package com.seibel.lod.core.a7.util; public class IdMappingUtil { public static final String BLOCKSTATE_ID_AIR = "air"; diff --git a/src/main/java/com/seibel/lod/core/a7/UncheckedInterruptedException.java b/src/main/java/com/seibel/lod/core/a7/util/UncheckedInterruptedException.java similarity index 96% rename from src/main/java/com/seibel/lod/core/a7/UncheckedInterruptedException.java rename to src/main/java/com/seibel/lod/core/a7/util/UncheckedInterruptedException.java index 3e087481d..8c9e93372 100644 --- a/src/main/java/com/seibel/lod/core/a7/UncheckedInterruptedException.java +++ b/src/main/java/com/seibel/lod/core/a7/util/UncheckedInterruptedException.java @@ -1,4 +1,4 @@ -package com.seibel.lod.core.a7; +package com.seibel.lod.core.a7.util; public class UncheckedInterruptedException extends RuntimeException { public UncheckedInterruptedException(String message) { diff --git a/src/main/java/com/seibel/lod/core/a7/world/DhClientServerWorld.java b/src/main/java/com/seibel/lod/core/a7/world/DhClientServerWorld.java index 2f40bd4c2..e53087b88 100644 --- a/src/main/java/com/seibel/lod/core/a7/world/DhClientServerWorld.java +++ b/src/main/java/com/seibel/lod/core/a7/world/DhClientServerWorld.java @@ -1,9 +1,9 @@ package com.seibel.lod.core.a7.world; -import com.seibel.lod.core.a7.WorldEnvironment; import com.seibel.lod.core.a7.level.DhClientServerLevel; import com.seibel.lod.core.a7.save.structure.LocalSaveStructure; import com.seibel.lod.core.config.Config; +import com.seibel.lod.core.util.EventLoop; import com.seibel.lod.core.util.LodUtil; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; @@ -11,10 +11,13 @@ import java.io.File; import java.util.HashMap; import java.util.Iterator; import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; public class DhClientServerWorld extends DhWorld implements IClientWorld, IServerWorld { private final HashMap levels; public final LocalSaveStructure saveStructure; + public ExecutorService dhTickerThread = LodUtil.makeSingleThreadPool("DHTickerThread", 2); + public EventLoop eventLoop = new EventLoop(dhTickerThread, this::_clientTick); public DhClientServerWorld() { super(WorldEnvironment.Client_Server); @@ -45,18 +48,25 @@ public class DhClientServerWorld extends DhWorld implements IClientWorld, IServe } } - public void tick() { + private void _clientTick() { int newViewDistance = Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * 16; Iterator iterator = levels.values().iterator(); while (iterator.hasNext()) { DhClientServerLevel level = iterator.next(); if (level.tree.viewDistance != newViewDistance) { - level.close(); + level.close(); //FIXME: Is this fine for current logic? iterator.remove(); } } //DetailDistanceUtil.updateSettings(); - levels.values().forEach(DhClientServerLevel::tick); + levels.values().forEach(DhClientServerLevel::clientTick); + } + public void clientTick() { + eventLoop.tick(); + } + + public void serverTick() { + levels.values().forEach(DhClientServerLevel::serverTick); } public void doWorldGen() { @@ -77,4 +87,15 @@ public class DhClientServerWorld extends DhWorld implements IClientWorld, IServe } levels.clear(); } + + public void enableRendering(ILevelWrapper wrapper) { + DhClientServerLevel level = levels.get(wrapper); + if (level==null) return; + level.startRenderer(); + } + public void disableRendering(ILevelWrapper wrapper) { + DhClientServerLevel level = levels.get(wrapper); + if (level==null) return; + level.stopRenderer(); + } } diff --git a/src/main/java/com/seibel/lod/core/a7/world/DhClientWorld.java b/src/main/java/com/seibel/lod/core/a7/world/DhClientWorld.java index 34e242a91..80f41c2ec 100644 --- a/src/main/java/com/seibel/lod/core/a7/world/DhClientWorld.java +++ b/src/main/java/com/seibel/lod/core/a7/world/DhClientWorld.java @@ -1,7 +1,7 @@ package com.seibel.lod.core.a7.world; -import com.seibel.lod.core.a7.WorldEnvironment; import com.seibel.lod.core.a7.level.DhClientLevel; +import com.seibel.lod.core.a7.level.DhClientServerLevel; import com.seibel.lod.core.a7.save.structure.ClientOnlySaveStructure; import com.seibel.lod.core.config.Config; import com.seibel.lod.core.util.DetailDistanceUtil; @@ -16,12 +16,10 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; public class DhClientWorld extends DhWorld implements IClientWorld { - private final HashMap levels; public final ClientOnlySaveStructure saveStructure; - public ExecutorService dhTickerThread = LodUtil.makeSingleThreadPool("DHTickerThread", 2); - public EventLoop eventLoop = new EventLoop(dhTickerThread, this::tick); + public EventLoop eventLoop = new EventLoop(dhTickerThread, this::_clientTick); public DhClientWorld() { super(WorldEnvironment.Client_Only); @@ -52,7 +50,7 @@ public class DhClientWorld extends DhWorld implements IClientWorld { } } - private void tick() { + private void _clientTick() { int newViewDistance = Config.Client.Graphics.Quality.lodChunkRenderDistance.get() * 16; Iterator iterator = levels.values().iterator(); while (iterator.hasNext()) { @@ -63,9 +61,10 @@ public class DhClientWorld extends DhWorld implements IClientWorld { } } DetailDistanceUtil.updateSettings(); + levels.values().forEach(DhClientLevel::clientTick); } - public void asyncTick() { + public void clientTick() { eventLoop.tick(); } diff --git a/src/main/java/com/seibel/lod/core/a7/world/DhServerWorld.java b/src/main/java/com/seibel/lod/core/a7/world/DhServerWorld.java index f7f18d6a9..624618d1c 100644 --- a/src/main/java/com/seibel/lod/core/a7/world/DhServerWorld.java +++ b/src/main/java/com/seibel/lod/core/a7/world/DhServerWorld.java @@ -1,6 +1,5 @@ package com.seibel.lod.core.a7.world; -import com.seibel.lod.core.a7.WorldEnvironment; import com.seibel.lod.core.a7.level.DhServerLevel; import com.seibel.lod.core.a7.save.structure.LocalSaveStructure; import com.seibel.lod.core.util.LodUtil; @@ -43,8 +42,8 @@ public class DhServerWorld extends DhWorld implements IServerWorld { } } - public void tick() { - levels.values().forEach(DhServerLevel::tick); + public void serverTick() { + levels.values().forEach(DhServerLevel::serverTick); } public void doWorldGen() { diff --git a/src/main/java/com/seibel/lod/core/a7/world/DhWorld.java b/src/main/java/com/seibel/lod/core/a7/world/DhWorld.java index 0a7a402b4..c879ae89f 100644 --- a/src/main/java/com/seibel/lod/core/a7/world/DhWorld.java +++ b/src/main/java/com/seibel/lod/core/a7/world/DhWorld.java @@ -1,7 +1,5 @@ package com.seibel.lod.core.a7.world; -import com.seibel.lod.core.a7.WorldEnvironment; -import com.seibel.lod.core.a7.level.DhClientServerLevel; import com.seibel.lod.core.a7.level.ILevel; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; @@ -24,4 +22,7 @@ public abstract class DhWorld implements Closeable { public abstract void unloadLevel(ILevelWrapper wrapper); public abstract CompletableFuture saveAndFlush(); + + @Override + public abstract void close(); } diff --git a/src/main/java/com/seibel/lod/core/a7/world/IClientWorld.java b/src/main/java/com/seibel/lod/core/a7/world/IClientWorld.java index 0377e7f38..8fedb7d38 100644 --- a/src/main/java/com/seibel/lod/core/a7/world/IClientWorld.java +++ b/src/main/java/com/seibel/lod/core/a7/world/IClientWorld.java @@ -1,4 +1,7 @@ package com.seibel.lod.core.a7.world; +import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; + public interface IClientWorld { + void clientTick(); } diff --git a/src/main/java/com/seibel/lod/core/a7/world/IServerWorld.java b/src/main/java/com/seibel/lod/core/a7/world/IServerWorld.java index 368c2da64..adc899dc6 100644 --- a/src/main/java/com/seibel/lod/core/a7/world/IServerWorld.java +++ b/src/main/java/com/seibel/lod/core/a7/world/IServerWorld.java @@ -1,5 +1,6 @@ package com.seibel.lod.core.a7.world; public interface IServerWorld { + void serverTick(); void doWorldGen(); } diff --git a/src/main/java/com/seibel/lod/core/a7/WorldEnvironment.java b/src/main/java/com/seibel/lod/core/a7/world/WorldEnvironment.java similarity index 69% rename from src/main/java/com/seibel/lod/core/a7/WorldEnvironment.java rename to src/main/java/com/seibel/lod/core/a7/world/WorldEnvironment.java index e027a7aa7..b595277d8 100644 --- a/src/main/java/com/seibel/lod/core/a7/WorldEnvironment.java +++ b/src/main/java/com/seibel/lod/core/a7/world/WorldEnvironment.java @@ -1,4 +1,4 @@ -package com.seibel.lod.core.a7; +package com.seibel.lod.core.a7.world; public enum WorldEnvironment { Client_Only, 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 f03ab1338..c4c9b5c5a 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 @@ -19,6 +19,8 @@ package com.seibel.lod.core.api.internal.a7; +import com.seibel.lod.core.a7.level.IClientLevel; +import com.seibel.lod.core.a7.world.*; import com.seibel.lod.core.config.Config; import com.seibel.lod.core.ModInfo; import com.seibel.lod.core.enums.rendering.EDebugMode; @@ -28,7 +30,6 @@ import com.seibel.lod.core.logging.ConfigBasedLogger; import com.seibel.lod.core.logging.ConfigBasedSpamLogger; import com.seibel.lod.core.logging.SpamReducedLogger; import com.seibel.lod.core.a7.level.DhClientServerLevel; -import com.seibel.lod.core.a7.world.DhWorld; import com.seibel.lod.core.a7.Server; import com.seibel.lod.core.objects.math.Mat4f; import com.seibel.lod.core.render.GLProxy; @@ -38,6 +39,7 @@ import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftRenderWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; +import net.fabricmc.api.Environment; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; @@ -80,12 +82,6 @@ public class ClientApi } } } - - /** - * there is some setup that should only happen once, - * once this is true that setup has completed - */ - private boolean firstTimeSetupComplete = false; private boolean configOverrideReminderPrinted = false; public boolean rendererDisabledBecauseOfExceptions = false; private ClientApi() @@ -114,42 +110,46 @@ public class ClientApi if (MC != null) MC.sendChatMessage(prefix + str); } - public void clientServerConnected() { - SharedApi.currentServer = new Server(false); - SharedApi.currentWorld = new DhWorld(enviroment); + public void onClientOnlyConnected() { + SharedApi.currentWorld = new DhClientWorld(); } - public void clientServerDisconnected() { + public void onClientOnlyDisconnected() { SharedApi.currentWorld.close(); SharedApi.currentWorld = null; - SharedApi.currentServer = null; } - public void clientChunkLoadEvent(IChunkWrapper chunk, ILevelWrapper world) + public void clientChunkLoadEvent(IChunkWrapper chunk, ILevelWrapper level) { - //TODO: Implement - } - public void clientChunkSaveEvent(IChunkWrapper chunk, ILevelWrapper world) - { - //TODO: Implement - } - - public void clientLevelUnloadEvent(ILevelWrapper world) - { - if (SharedApi.currentWorld != null) { - SharedApi.currentWorld.unloadLevel(world); + if (SharedApi.getEnvironment() == WorldEnvironment.Client_Only) { + //TODO: Implement } } - public void clientLevelLoadEvent(ILevelWrapper world) + public void clientChunkSaveEvent(IChunkWrapper chunk, ILevelWrapper level) { - //TODO: Maybe make DHLevel init no longer depend on needing player entity in single player - if (SharedApi.currentWorld != null) { - SharedApi.currentWorld.getOrLoadLevel(world); + if (SharedApi.getEnvironment() == WorldEnvironment.Client_Only) { + //TODO: Implement + } + } + + public void clientLevelUnloadEvent(ILevelWrapper level) + { + if (SharedApi.currentWorld instanceof DhClientServerWorld) { + ((DhClientServerWorld)SharedApi.currentWorld).disableRendering(level); + } else if (SharedApi.getEnvironment() == WorldEnvironment.Client_Only) { + SharedApi.currentWorld.unloadLevel(level); + } + } + public void clientLevelLoadEvent(ILevelWrapper level) + { + if (SharedApi.currentWorld instanceof DhClientServerWorld) { + ((DhClientServerWorld)SharedApi.currentWorld).enableRendering(level); + } else if (SharedApi.getEnvironment() == WorldEnvironment.Client_Only) { + SharedApi.currentWorld.getOrLoadLevel(level); //TODO: This may need to be delayed to after player enters the level } } private long lastFlush = 0; - public void rendererShutdownEvent() { IProfilerWrapper profiler = MC.getProfiler(); profiler.push("DH-RendererShutdown"); @@ -176,15 +176,8 @@ public class ClientApi ConfigBasedLogger.updateAll(); ConfigBasedSpamLogger.updateAll(doFlush); - if (SharedApi.currentWorld != null) { - if (ModInfo.IS_DEV_BUILD) { - // config overrides should only be used in the developer builds - applyDeveloperConfigOverrides(); - } - if (SharedApi.currentServer == null) { - // In single player. Do client-side ticking system. - SharedApi.currentWorld.asyncTick(); - } + if (SharedApi.currentWorld instanceof IClientWorld) { + ((IClientWorld) SharedApi.currentWorld).clientTick(); } profiler.pop(); } @@ -199,18 +192,13 @@ public class ClientApi if (world == null) return; DhWorld DhWorld = SharedApi.currentWorld; if (DhWorld == null) return; - DhClientServerLevel level = (SharedApi.currentServer == null) ? DhWorld.getOrLoadLevel(world) : DhWorld.getLevel(world); - if (level == null) return; + if (!(SharedApi.currentWorld instanceof IClientWorld)) return; + IClientLevel level = (IClientLevel)SharedApi.currentWorld; if (prefLoggerEnabled) { level.dumpRamUsage(); } - if (SharedApi.currentServer == null) { - // In multiplayer, without access to the server-side stuff. So we need to do some extra work. - level.asyncTick(); - } - if (Config.Client.Advanced.Debugging.rendererType.get() == ERendererType.DEFAULT) { if (MC_RENDER.playerHasBlindnessEffect()) { // if the player is blind, don't render LODs, diff --git a/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java b/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java index 730ba36ea..46eab6efd 100644 --- a/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java +++ b/src/main/java/com/seibel/lod/core/api/internal/a7/ServerApi.java @@ -19,6 +19,9 @@ package com.seibel.lod.core.api.internal.a7; +import com.seibel.lod.core.a7.world.DhClientServerWorld; +import com.seibel.lod.core.a7.world.DhServerWorld; +import com.seibel.lod.core.a7.world.IServerWorld; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.a7.world.DhWorld; @@ -44,8 +47,6 @@ public class ServerApi private static final Logger LOGGER = DhLoggerBuilder.getLogger(MethodHandles.lookup().lookupClass().getSimpleName()); private static final IVersionConstants VERSION_CONSTANTS = SingletonHandler.get(IVersionConstants.class); - private boolean isCurrentlyOnSinglePlayerServer = false; - private ServerApi() { } @@ -57,51 +58,51 @@ public class ServerApi private int lastWorldGenTickDelta = 0; public void serverTickEvent() { - lastWorldGenTickDelta--; - if (SharedApi.currentWorld != null && lastWorldGenTickDelta <= 0) { - lastWorldGenTickDelta = 20; - DhWorld DhWorld = SharedApi.currentWorld; - DhWorld.tick(); + if (SharedApi.currentWorld instanceof IServerWorld) { + IServerWorld serverWorld = (IServerWorld) SharedApi.currentWorld; + serverWorld.serverTick(); + lastWorldGenTickDelta--; + if (lastWorldGenTickDelta <= 0) { + serverWorld.doWorldGen(); + lastWorldGenTickDelta = 20; + } } } //TODO: rename to serverLoadEvent - public void serverWorldLoadEvent() { - SharedApi.currentServer = new Server(!SharedApi.inDedicatedEnvironment); - SharedApi.currentWorld = new DhWorld(enviroment); - //TODO: Setup the network handler + public void serverWorldLoadEvent(boolean isDedicatedEnvironment) { + if (isDedicatedEnvironment) { + SharedApi.currentWorld = new DhServerWorld(); + } else { + SharedApi.currentWorld = new DhClientServerWorld(); + } } //TODO: rename to serverUnloadEvent public void serverWorldUnloadEvent() { - //TODO: Close the network handler SharedApi.currentWorld.close(); SharedApi.currentWorld = null; - SharedApi.currentServer = null; } public void serverLevelLoadEvent(ILevelWrapper world) { - //TODO: Maybe make DHLevel init no longer depend on needing player entity in single player - if (SharedApi.currentServer.isSinglePlayer) return; - SharedApi.currentWorld.getOrLoadLevel(world); + if (SharedApi.currentWorld instanceof IServerWorld) + SharedApi.currentWorld.getOrLoadLevel(world); } public void serverLevelUnloadEvent(ILevelWrapper world) { - SharedApi.currentWorld.unloadLevel(world); + if (SharedApi.currentWorld instanceof IServerWorld) + SharedApi.currentWorld.unloadLevel(world); } @Deprecated public void serverSaveEvent() { - SharedApi.currentWorld.save(); - } - - - - public void chunkSaveEvent(IChunkWrapper chunk, ILevelWrapper world) { - //TODO + if (SharedApi.currentWorld instanceof IServerWorld) + SharedApi.currentWorld.saveAndFlush(); } public void serverChunkLoadEvent(IChunkWrapper chunk, ILevelWrapper world) { + //TODO } public void serverChunkSaveEvent(IChunkWrapper chunk, ILevelWrapper world) { + //TODO } } 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 ef78a8a80..db70acb58 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,15 +1,16 @@ package com.seibel.lod.core.api.internal.a7; +import com.seibel.lod.core.a7.world.WorldEnvironment; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.a7.world.DhWorld; -import com.seibel.lod.core.a7.Server; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftSharedWrapper; import org.apache.logging.log4j.Logger; public class SharedApi { public static DhWorld currentWorld; - public static Server currentServer; public static IMinecraftSharedWrapper MC; public static Logger LOGGER = DhLoggerBuilder.getLogger("DH Events"); - public static boolean inDedicatedEnvironment; + public static WorldEnvironment getEnvironment() { + return currentWorld==null ? null : currentWorld.environment; + } } diff --git a/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java index 873ba91aa..18f6a7c03 100644 --- a/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java +++ b/src/main/java/com/seibel/lod/core/builders/lodBuilding/bufferBuilding/CubicLodTemplate.java @@ -22,8 +22,8 @@ package com.seibel.lod.core.builders.lodBuilding.bufferBuilding; import com.seibel.lod.core.enums.rendering.EDebugMode; import com.seibel.lod.core.handlers.dependencyInjection.SingletonHandler; import com.seibel.lod.core.objects.LodDataView; -import com.seibel.lod.core.a7.datatype.column.ColumnArrayView; -import com.seibel.lod.core.a7.datatype.column.ColumnBox; +import com.seibel.lod.core.a7.datatype.column.accessor.ColumnArrayView; +import com.seibel.lod.core.a7.datatype.column.render.ColumnBox; import com.seibel.lod.core.objects.opengl.LodBox; import com.seibel.lod.core.util.ColorUtil; import com.seibel.lod.core.util.DataPointUtil;