Move ColumnRenderSource file parsing into ColumnRenderLoader
This commit is contained in:
@@ -93,7 +93,12 @@ public abstract class AbstractRenderSourceLoader
|
||||
LOADER_BY_SOURCE_TYPE.put(renderSourceClass, this);
|
||||
}
|
||||
|
||||
/** Can return null if the file is out of date or something */
|
||||
/**
|
||||
* Can return null if the file is out of date.
|
||||
*
|
||||
* @throws IOException if the file uses a unsupported data version
|
||||
* or there was an issue reading the file
|
||||
*/
|
||||
public abstract ILodRenderSource loadRenderSource(RenderMetaDataFile renderFile, InputStream data, IDhLevel level) throws IOException;
|
||||
/** Should not return null */
|
||||
public abstract ILodRenderSource createRenderSource(ILodDataSource dataSource, IDhClientLevel level);
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.seibel.lod.core.datatype.column;
|
||||
|
||||
import com.seibel.lod.core.datatype.IIncompleteDataSource;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.datatype.column.accessor.ColumnFormat;
|
||||
import com.seibel.lod.core.datatype.full.FullDataSource;
|
||||
import com.seibel.lod.core.datatype.transform.FullToColumnTransformer;
|
||||
import com.seibel.lod.core.level.IDhClientLevel;
|
||||
@@ -14,9 +15,14 @@ import com.seibel.lod.core.util.LodUtil;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
/**
|
||||
* Can load {@link ColumnRenderSource}'s for the {@link ColumnRenderSource#LATEST_VERSION}
|
||||
* Handles loading and parsing {@link RenderMetaDataFile}s to create {@link ColumnRenderSource}s. <br><br>
|
||||
*
|
||||
* Please see the {@link ColumnRenderLoader#loadRenderSource} method to see what
|
||||
* file versions this class can handle.
|
||||
*/
|
||||
public class ColumnRenderLoader extends AbstractRenderSourceLoader
|
||||
{
|
||||
@@ -30,8 +36,16 @@ public class ColumnRenderLoader extends AbstractRenderSourceLoader
|
||||
@Override
|
||||
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);
|
||||
DataInputStream inputStream = new DataInputStream(data); // DO NOT CLOSE
|
||||
int dataFileVersion = dataFile.metaData.loaderVersion;
|
||||
|
||||
switch (dataFileVersion)
|
||||
{
|
||||
case 1:
|
||||
return new ColumnRenderSource(dataFile.pos, readDataV1(inputStream, level.getMinY()), level);
|
||||
default:
|
||||
throw new IOException("Invalid Data: The data version [" + dataFileVersion + "] is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -49,4 +63,66 @@ public class ColumnRenderLoader extends AbstractRenderSourceLoader
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//========================//
|
||||
// versioned file parsing //
|
||||
//========================//
|
||||
|
||||
/**
|
||||
* @param inputData Expected format: 1st byte: detail level, 2nd byte: vertical size, 3rd byte on: column data
|
||||
*
|
||||
* @throws IOException if there was an issue reading the stream
|
||||
*/
|
||||
private static ParsedColumnData readDataV1(DataInputStream inputData, int yOffset) throws IOException
|
||||
{
|
||||
byte detailLevel = inputData.readByte();
|
||||
int verticalDataCount = inputData.readByte() & 0b01111111;
|
||||
|
||||
int maxNumberOfDataPoints = ColumnRenderSource.SECTION_SIZE * ColumnRenderSource.SECTION_SIZE * verticalDataCount;
|
||||
|
||||
|
||||
//FIXME: Temp hack flag for marking a empty section
|
||||
short tempMinHeight = Short.reverseBytes(inputData.readShort());
|
||||
if (tempMinHeight == Short.MAX_VALUE)
|
||||
{
|
||||
return new ParsedColumnData(detailLevel, verticalDataCount, new long[maxNumberOfDataPoints], true);
|
||||
}
|
||||
|
||||
|
||||
// isEmpty = false
|
||||
byte[] data = new byte[maxNumberOfDataPoints * Long.BYTES];
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
|
||||
inputData.readFully(data);
|
||||
|
||||
long[] dataPoints = new long[maxNumberOfDataPoints];
|
||||
byteBuffer.asLongBuffer().get(dataPoints);
|
||||
if (tempMinHeight != yOffset)
|
||||
{
|
||||
for (int i = 0; i < dataPoints.length; i++)
|
||||
{
|
||||
dataPoints[i] = ColumnFormat.shiftHeightAndDepth(dataPoints[i], (short) (tempMinHeight - yOffset));
|
||||
}
|
||||
}
|
||||
|
||||
return new ParsedColumnData(detailLevel, verticalDataCount, dataPoints, false);
|
||||
}
|
||||
|
||||
public static class ParsedColumnData
|
||||
{
|
||||
byte detailLevel;
|
||||
int verticalSize;
|
||||
long[] dataContainer;
|
||||
boolean isEmpty;
|
||||
|
||||
public ParsedColumnData(byte detailLevel, int verticalSize, long[] dataContainer, boolean isEmpty)
|
||||
{
|
||||
this.detailLevel = detailLevel;
|
||||
this.verticalSize = verticalSize;
|
||||
this.dataContainer = dataContainer;
|
||||
this.isEmpty = isEmpty;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -19,12 +19,9 @@ import com.seibel.lod.core.util.objects.Reference;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
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;
|
||||
|
||||
@@ -88,23 +85,21 @@ public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new ColumnRenderSource with data from the given DataInputStream.
|
||||
* Creates a new ColumnRenderSource from the parsedColumnData.
|
||||
*
|
||||
* @param inputData Expected format: 1st byte: detail level, 2nd byte: vertical size, 3rd byte on: column data
|
||||
* @throws IOException if the DataInputStream's detail level isn't what was expected
|
||||
*/
|
||||
public ColumnRenderSource(DhSectionPos sectionPos, DataInputStream inputData, int version, IDhLevel level) throws IOException
|
||||
public ColumnRenderSource(DhSectionPos sectionPos, ColumnRenderLoader.ParsedColumnData parsedColumnData, IDhLevel level) throws IOException
|
||||
{
|
||||
byte detailLevel = inputData.readByte();
|
||||
if (sectionPos.sectionDetail - SECTION_SIZE_OFFSET != detailLevel)
|
||||
if (sectionPos.sectionDetail - SECTION_SIZE_OFFSET != parsedColumnData.detailLevel)
|
||||
{
|
||||
throw new IOException("Invalid data: detail level does not match");
|
||||
}
|
||||
|
||||
this.sectionPos = sectionPos;
|
||||
this.yOffset = level.getMinY();
|
||||
this.verticalSize = inputData.readByte() & 0b01111111;
|
||||
this.dataContainer = this.loadData(inputData, version, this.verticalSize);
|
||||
this.verticalSize = parsedColumnData.verticalSize;
|
||||
this.dataContainer = parsedColumnData.dataContainer;
|
||||
this.airDataContainer = new int[AIR_SECTION_SIZE * AIR_SECTION_SIZE * this.verticalSize];
|
||||
|
||||
this.debugSourceFlags = new DebugSourceFlag[SECTION_SIZE * SECTION_SIZE];
|
||||
@@ -117,50 +112,6 @@ public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype
|
||||
// datapoint manipulation //
|
||||
//========================//
|
||||
|
||||
/**
|
||||
* Attempts to parse and load the given DataInputStream based on its
|
||||
* render data version
|
||||
*
|
||||
* @throws IOException if the version isn't supported
|
||||
*/
|
||||
private long[] loadData(DataInputStream inputData, int version, int verticalSize) throws IOException
|
||||
{
|
||||
switch (version)
|
||||
{
|
||||
case 1:
|
||||
return this.readDataV1(inputData, verticalSize);
|
||||
default:
|
||||
throw new IOException("Invalid Data: The data version [" + version + "] is not supported");
|
||||
}
|
||||
}
|
||||
|
||||
private static long[] readDataV1(DataInputStream inputData, int tempMaxVerticalData) throws IOException
|
||||
{
|
||||
int maxNumberOfDataPoints = SECTION_SIZE * SECTION_SIZE * tempMaxVerticalData;
|
||||
|
||||
short tempMinHeight = Short.reverseBytes(inputData.readShort());
|
||||
if (tempMinHeight == Short.MAX_VALUE)
|
||||
{ //FIXME: Temp hack flag for marking a empty section
|
||||
return new long[maxNumberOfDataPoints];
|
||||
}
|
||||
|
||||
this.isEmpty = false;
|
||||
byte[] data = new byte[maxNumberOfDataPoints * Long.BYTES];
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN);
|
||||
inputData.readFully(data);
|
||||
|
||||
long[] result = new long[maxNumberOfDataPoints];
|
||||
byteBuffer.asLongBuffer().get(result);
|
||||
if (tempMinHeight != this.yOffset)
|
||||
{
|
||||
for (int i = 0; i < result.length; i++)
|
||||
{
|
||||
result[i] = ColumnFormat.shiftHeightAndDepth(result[i], (short) (tempMinHeight - this.yOffset));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearDataPoint(int posX, int posZ)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user