From 7ea614f25775147156769bbfa9c04af7e15bcb18 Mon Sep 17 00:00:00 2001 From: James Seibel Date: Fri, 13 Jan 2023 07:09:16 -0600 Subject: [PATCH] reformat render source files --- .../datatype/AbstractRenderSourceLoader.java | 86 +++++++++++++------ .../datatype/column/ColumnRenderLoader.java | 44 ++++++---- .../datatype/column/ColumnRenderSource.java | 39 +++++---- .../transform/DataRenderTransformer.java | 4 +- .../file/renderfile/RenderMetaDataFile.java | 4 +- .../lod/core/render/LodRenderSection.java | 40 ++++++--- 6 files changed, 137 insertions(+), 80 deletions(-) diff --git a/core/src/main/java/com/seibel/lod/core/datatype/AbstractRenderSourceLoader.java b/core/src/main/java/com/seibel/lod/core/datatype/AbstractRenderSourceLoader.java index 940f7f75a..dd96472a9 100644 --- a/core/src/main/java/com/seibel/lod/core/datatype/AbstractRenderSourceLoader.java +++ b/core/src/main/java/com/seibel/lod/core/datatype/AbstractRenderSourceLoader.java @@ -9,63 +9,93 @@ import java.io.IOException; import java.io.InputStream; import java.util.*; +/** + * Abstract for loading and creating {@link ILodRenderSource} objects + * from {@link RenderMetaDataFile}'s and {@link ILodDataSource}'s.

+ * + * Also holds all {@link AbstractRenderSourceLoader}'s + * that have been created to allow for migrating old render data formats. + */ public abstract class AbstractRenderSourceLoader { - public static final HashMultimap, AbstractRenderSourceLoader> loaderRegistry = HashMultimap.create(); - public static final HashMap> renderTypeIdRegistry = new HashMap<>(); + public static final HashMultimap, AbstractRenderSourceLoader> LOADER_BY_SOURCE_TYPE = HashMultimap.create(); + public static final HashMap> SOURCE_TYPE_BY_METADATA_VERSION = new HashMap<>(); public static AbstractRenderSourceLoader getLoader(long renderTypeId, byte loaderVersion) { - return loaderRegistry.get(renderTypeIdRegistry.get(renderTypeId)).stream() - .filter(l -> Arrays.binarySearch(l.loaderSupportedVersions, loaderVersion) >= 0) + return LOADER_BY_SOURCE_TYPE.get(SOURCE_TYPE_BY_METADATA_VERSION.get(renderTypeId)).stream() + .filter(loader -> Arrays.binarySearch(loader.loaderSupportedRenderDataVersions, loaderVersion) >= 0) .findFirst().orElse(null); } public static AbstractRenderSourceLoader getLoader(Class clazz, byte loaderVersion) { - return loaderRegistry.get(clazz).stream() - .filter(l -> Arrays.binarySearch(l.loaderSupportedVersions, loaderVersion) >= 0) + return LOADER_BY_SOURCE_TYPE.get(clazz).stream() + .filter(l -> Arrays.binarySearch(l.loaderSupportedRenderDataVersions, loaderVersion) >= 0) .findFirst().orElse(null); } - public final Class clazz; + + + public final Class renderSourceClass; public final long renderTypeId; - public final byte[] loaderSupportedVersions; + public final byte[] loaderSupportedRenderDataVersions; public final byte detailOffset; - public AbstractRenderSourceLoader(Class clazz, long renderTypeId, byte[] loaderSupportedVersions, byte detailOffset) + + + /** + * Will automatically add the new render source to the + * {@link AbstractRenderSourceLoader#LOADER_BY_SOURCE_TYPE} + * + * @throws IllegalArgumentException if another render source already exists for the given renderTypeId or supported render data versions + */ + public AbstractRenderSourceLoader(Class renderSourceClass, long renderTypeId, byte[] loaderSupportedRenderDataVersions, byte detailOffset) throws IllegalArgumentException { 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) + this.loaderSupportedRenderDataVersions = loaderSupportedRenderDataVersions; + Arrays.sort(loaderSupportedRenderDataVersions); // sort to allow fast access + this.renderSourceClass = renderSourceClass; + this.detailOffset = detailOffset; + + + // register the loader // + + // validate there isn't another loader for the given renderTypeId + if (SOURCE_TYPE_BY_METADATA_VERSION.containsKey(renderTypeId) + && SOURCE_TYPE_BY_METADATA_VERSION.get(renderTypeId) != renderSourceClass) { throw new IllegalArgumentException("Loader for renderTypeId " + renderTypeId + " already registered with different class: " - + renderTypeIdRegistry.get(renderTypeId) + " != " + clazz); + + SOURCE_TYPE_BY_METADATA_VERSION.get(renderTypeId) + " != " + renderSourceClass); } - Set loaders = loaderRegistry.get(clazz); - if (loaders.stream().anyMatch(other -> { - // see if any loaderSupportsVersion conflicts with this one - for (byte otherVer : other.loaderSupportedVersions) + Set loaders = LOADER_BY_SOURCE_TYPE.get(renderSourceClass); + + // validate there isn't another loader that supports the same render data version(s) + boolean loaderAlreadyExistsForDataVersion = loaders.stream().anyMatch(other -> + { + for (byte otherVer : other.loaderSupportedRenderDataVersions) { - if (Arrays.binarySearch(loaderSupportedVersions, otherVer) >= 0) + if (Arrays.binarySearch(loaderSupportedRenderDataVersions, otherVer) >= 0) + { return true; + } } return false; - })) + }); + if (loaderAlreadyExistsForDataVersion) { - throw new IllegalArgumentException("Loader for class " + clazz + " that supports one of the version in " - + Arrays.toString(loaderSupportedVersions) + " already registered!"); + throw new IllegalArgumentException("Loader for class " + renderSourceClass + " that supports one of the render data versions in " + + Arrays.toString(loaderSupportedRenderDataVersions) + " already registered!"); } - renderTypeIdRegistry.put(renderTypeId, clazz); - loaderRegistry.put(clazz, this); - this.detailOffset = detailOffset; + + // register the loader + SOURCE_TYPE_BY_METADATA_VERSION.put(renderTypeId, renderSourceClass); + LOADER_BY_SOURCE_TYPE.put(renderSourceClass, this); } /** Can return null if the file is out of date or something */ - public abstract ILodRenderSource loadRender(RenderMetaDataFile renderFile, InputStream data, IDhLevel level) throws IOException; - public abstract ILodRenderSource createRender(ILodDataSource dataSource, IDhClientLevel level); - + public abstract ILodRenderSource loadRenderSource(RenderMetaDataFile renderFile, InputStream data, IDhLevel level) throws IOException; + /** Should not return null */ + public abstract ILodRenderSource createRenderSource(ILodDataSource dataSource, IDhClientLevel level); } diff --git a/core/src/main/java/com/seibel/lod/core/datatype/column/ColumnRenderLoader.java b/core/src/main/java/com/seibel/lod/core/datatype/column/ColumnRenderLoader.java index 119bc1d77..222ab2b58 100644 --- a/core/src/main/java/com/seibel/lod/core/datatype/column/ColumnRenderLoader.java +++ b/core/src/main/java/com/seibel/lod/core/datatype/column/ColumnRenderLoader.java @@ -15,28 +15,38 @@ import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; +/** + * Can load {@link ColumnRenderSource}'s for the {@link ColumnRenderSource#LATEST_VERSION} + */ public class ColumnRenderLoader extends AbstractRenderSourceLoader { - public ColumnRenderLoader() { - super(ColumnRenderSource.class, ColumnRenderSource.TYPE_ID, new byte[]{ColumnRenderSource.LATEST_VERSION}, ColumnRenderSource.SECTION_SIZE_OFFSET); + public ColumnRenderLoader() + { + super(ColumnRenderSource.class, ColumnRenderSource.TYPE_ID, new byte[]{ ColumnRenderSource.LATEST_VERSION }, ColumnRenderSource.SECTION_SIZE_OFFSET); } - + + + @Override - public ILodRenderSource loadRender(RenderMetaDataFile dataFile, InputStream data, IDhLevel level) throws IOException { - DataInputStream dis = new DataInputStream(data); // DO NOT CLOSE - return new ColumnRenderSource(dataFile.pos, dis, dataFile.metaData.loaderVersion, level); + public ILodRenderSource loadRenderSource(RenderMetaDataFile dataFile, InputStream data, IDhLevel level) throws IOException + { + DataInputStream inputStream = new DataInputStream(data); // DO NOT CLOSE + return new ColumnRenderSource(dataFile.pos, inputStream, dataFile.metaData.loaderVersion, level); } - + @Override - public ILodRenderSource createRender(ILodDataSource dataSource, IDhClientLevel level) { - if (dataSource instanceof FullDataSource) { - return FullToColumnTransformer.transformFullDataToColumnData(level, (FullDataSource) dataSource); - } else if (dataSource instanceof IIncompleteDataSource) { - return FullToColumnTransformer.transformIncompleteDataToColumnData(level, (IIncompleteDataSource) dataSource); - } - LodUtil.assertNotReach(); - return null; + public ILodRenderSource createRenderSource(ILodDataSource dataSource, IDhClientLevel level) + { + if (dataSource instanceof FullDataSource) // TODO replace with Java 7 method + { + return FullToColumnTransformer.transformFullDataToColumnData(level, (FullDataSource) dataSource); + } + else if (dataSource instanceof IIncompleteDataSource) + { + return FullToColumnTransformer.transformIncompleteDataToColumnData(level, (IIncompleteDataSource) dataSource); + } + LodUtil.assertNotReach(); + return null; } - - + } diff --git a/core/src/main/java/com/seibel/lod/core/datatype/column/ColumnRenderSource.java b/core/src/main/java/com/seibel/lod/core/datatype/column/ColumnRenderSource.java index 9fbf1e7c8..2f034e55f 100644 --- a/core/src/main/java/com/seibel/lod/core/datatype/column/ColumnRenderSource.java +++ b/core/src/main/java/com/seibel/lod/core/datatype/column/ColumnRenderSource.java @@ -29,6 +29,8 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; /** + * Stores the color data used when generating OpenGL buffers. + * * @author Leetom * @version 2022-10-5 */ @@ -77,10 +79,10 @@ public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype */ 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]; - debugSourceFlags = new DebugSourceFlag[SECTION_SIZE * SECTION_SIZE]; + this.verticalSize = maxVerticalSize; + this.dataContainer = new long[SECTION_SIZE * SECTION_SIZE * verticalSize]; + this.airDataContainer = new int[AIR_SECTION_SIZE * AIR_SECTION_SIZE * verticalSize]; + this.debugSourceFlags = new DebugSourceFlag[SECTION_SIZE * SECTION_SIZE]; this.sectionPos = sectionPos; this.yOffset = yOffset; } @@ -116,7 +118,8 @@ public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype //========================// /** - * Attempts to parse and load the given DataInputStream. + * Attempts to parse and load the given DataInputStream based on its + * render data version * * @throws IOException if the version isn't supported */ @@ -125,13 +128,13 @@ public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype switch (version) { case 1: - return readDataV1(inputData, verticalSize); + return this.readDataV1(inputData, verticalSize); default: throw new IOException("Invalid Data: The data version [" + version + "] is not supported"); } } - private long[] readDataV1(DataInputStream inputData, int tempMaxVerticalData) throws IOException + private static long[] readDataV1(DataInputStream inputData, int tempMaxVerticalData) throws IOException { int maxNumberOfDataPoints = SECTION_SIZE * SECTION_SIZE * tempMaxVerticalData; @@ -246,10 +249,10 @@ public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype /** @return true if this object had data written in every column */ boolean writeData(DataOutputStream outputStream) throws IOException { - outputStream.writeByte(getDataDetail()); + outputStream.writeByte(this.getDataDetail()); outputStream.writeByte((byte) this.verticalSize); - if (isEmpty) + if (this.isEmpty) { outputStream.writeByte(Short.MAX_VALUE & 0xFF); outputStream.writeByte((Short.MAX_VALUE >> 8) & 0xFF); @@ -266,9 +269,9 @@ public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype boolean allGenerated = true; for (int x = 0; x < SECTION_SIZE * SECTION_SIZE; x++) { - for (int z = 0; z < verticalSize; z++) + for (int z = 0; z < this.verticalSize; z++) { - long currentDatapoint = dataContainer[x * verticalSize + z]; + long currentDatapoint = this.dataContainer[x * this.verticalSize + z]; if (ColumnFormat.doesDataPointExist(currentDatapoint)) { // TODO: the "1" is a placeholder debug line @@ -277,7 +280,7 @@ public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype outputStream.writeLong(Long.reverseBytes(currentDatapoint)); } - if (!ColumnFormat.doesDataPointExist(dataContainer[x])) + if (!ColumnFormat.doesDataPointExist(this.dataContainer[x])) { allGenerated = false; } @@ -453,7 +456,7 @@ public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype public void saveRender(IDhClientLevel level, RenderMetaDataFile file, OutputStream dataStream) throws IOException { DataOutputStream dos = new DataOutputStream(dataStream); // DO NOT CLOSE - writeData(dos); + this.writeData(dos); } @Override @@ -479,7 +482,7 @@ public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype { for (int z = startZ; z < startZ + height; z++) { - debugSourceFlags[x * SECTION_SIZE + z] = flag; + this.debugSourceFlags[x * SECTION_SIZE + z] = flag; } } } @@ -500,19 +503,19 @@ public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype String SUBDATA_DELIMITER = ","; StringBuilder stringBuilder = new StringBuilder(); - stringBuilder.append(sectionPos); + stringBuilder.append(this.sectionPos); stringBuilder.append(LINE_DELIMITER); - int size = sectionPos.getWidth().numberOfLodSectionsWide; + int size = this.sectionPos.getWidth().numberOfLodSectionsWide; for (int z = 0; z < size; z++) { for (int x = 0; x < size; x++) { - for (int y = 0; y < verticalSize; y++) + for (int y = 0; y < this.verticalSize; y++) { //Converting the dataToHex stringBuilder.append(Long.toHexString(getDataPoint(x, z, y))); - if (y != verticalSize - 1) + if (y != this.verticalSize - 1) stringBuilder.append(SUBDATA_DELIMITER); } diff --git a/core/src/main/java/com/seibel/lod/core/datatype/transform/DataRenderTransformer.java b/core/src/main/java/com/seibel/lod/core/datatype/transform/DataRenderTransformer.java index bfac956f4..f91bc5a72 100644 --- a/core/src/main/java/com/seibel/lod/core/datatype/transform/DataRenderTransformer.java +++ b/core/src/main/java/com/seibel/lod/core/datatype/transform/DataRenderTransformer.java @@ -29,8 +29,8 @@ public class DataRenderTransformer private static ILodRenderSource transform(ILodDataSource dataSource, IDhClientLevel level) { if (dataSource == null) return null; - return ColumnRenderLoader.loaderRegistry.get(ColumnRenderSource.class) - .stream().findFirst().get().createRender(dataSource, level); + return ColumnRenderLoader.LOADER_BY_SOURCE_TYPE.get(ColumnRenderSource.class) + .stream().findFirst().get().createRenderSource(dataSource, level); } } diff --git a/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderMetaDataFile.java b/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderMetaDataFile.java index d3e48b797..5e36f2d5f 100644 --- a/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderMetaDataFile.java +++ b/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderMetaDataFile.java @@ -71,7 +71,7 @@ public class RenderMetaDataFile extends AbstractMetaDataFile throw new IOException("Invalid file: Data type loader not found: " + this.metaData.dataTypeId + "(v" + this.metaData.loaderVersion + ")"); } - this.dataType = this.loader.clazz; + this.dataType = this.loader.renderSourceClass; this.doesFileExist = true; } @@ -203,7 +203,7 @@ public class RenderMetaDataFile extends AbstractMetaDataFile { try (FileInputStream fio = getDataContent()) { - data = this.loader.loadRender(this, fio, level); + data = this.loader.loadRenderSource(this, fio, level); } catch (IOException e) { diff --git a/core/src/main/java/com/seibel/lod/core/render/LodRenderSection.java b/core/src/main/java/com/seibel/lod/core/render/LodRenderSection.java index 51f5f12bb..9d67b0427 100644 --- a/core/src/main/java/com/seibel/lod/core/render/LodRenderSection.java +++ b/core/src/main/java/com/seibel/lod/core/render/LodRenderSection.java @@ -1,5 +1,7 @@ package com.seibel.lod.core.render; +import com.seibel.lod.api.enums.config.EVerticalQuality; +import com.seibel.lod.core.config.Config; import com.seibel.lod.core.level.IDhClientLevel; import com.seibel.lod.core.pos.DhSectionPos; import com.seibel.lod.core.datatype.ILodRenderSource; @@ -7,7 +9,8 @@ import com.seibel.lod.core.file.renderfile.IRenderSourceProvider; import java.util.concurrent.CompletableFuture; -public class LodRenderSection { +public class LodRenderSection +{ public final DhSectionPos pos; /* Following used for LodQuadTree tick() method, and ONLY for that method! */ @@ -45,8 +48,10 @@ public class LodRenderSection { isRenderEnabled = false; } - public void load(IRenderSourceProvider renderDataProvider) { + public void load(IRenderSourceProvider renderDataProvider) + { provider = renderDataProvider; + this.previousQualitySetting = Config.Client.Graphics.Quality.verticalQuality.get(); } public void reload(IRenderSourceProvider renderDataProvider) { if (loadFuture != null) { @@ -58,18 +63,24 @@ public class LodRenderSection { lodRenderSource = null; } loadFuture = renderDataProvider.read(pos); + this.previousQualitySetting = Config.Client.Graphics.Quality.verticalQuality.get(); } - public void tick(LodQuadTree quadTree, IDhClientLevel level) { - if (loadFuture != null && loadFuture.isDone()) { - lodRenderSource = loadFuture.join(); - loadFuture = null; - if (isRenderEnabled) { - lodRenderSource.enableRender(level, quadTree); + public void tick(LodQuadTree quadTree, IDhClientLevel level) + { + if (this.loadFuture != null && this.loadFuture.isDone()) + { + this.lodRenderSource = this.loadFuture.join(); + this.loadFuture = null; + if (this.isRenderEnabled) + { + this.lodRenderSource.enableRender(level, quadTree); } } - if (lodRenderSource != null) { - provider.refreshRenderSource(lodRenderSource); + + if (this.lodRenderSource != null) + { + this.provider.refreshRenderSource(this.lodRenderSource); } } @@ -97,9 +108,12 @@ public class LodRenderSection { public boolean isLoading() { return false; } - - public boolean isOutdated() { - return lodRenderSource != null && !lodRenderSource.isValid(); + + private EVerticalQuality previousQualitySetting = null; + + public boolean isOutdated() + { + return this.previousQualitySetting != Config.Client.Graphics.Quality.verticalQuality.get() || (lodRenderSource != null && !lodRenderSource.isValid()); } public ILodRenderSource getRenderSource() {