Add interface and abstract prefixes to a few datatype objects
This commit is contained in:
+9
-9
@@ -8,21 +8,21 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class DataSourceLoader
|
||||
public abstract class AbstractDataSourceLoader
|
||||
{
|
||||
|
||||
public static final HashMultimap<Class<? extends LodDataSource>, DataSourceLoader> loaderRegistry = HashMultimap.create();
|
||||
public final Class<? extends LodDataSource> clazz;
|
||||
public static final HashMap<Long, Class<? extends LodDataSource>> datatypeIdRegistry = new HashMap<>();
|
||||
public static final HashMultimap<Class<? extends ILodDataSource>, AbstractDataSourceLoader> loaderRegistry = HashMultimap.create();
|
||||
public final Class<? extends ILodDataSource> clazz;
|
||||
public static final HashMap<Long, Class<? extends ILodDataSource>> datatypeIdRegistry = new HashMap<>();
|
||||
|
||||
public static DataSourceLoader getLoader(long dataTypeId, byte dataVersion)
|
||||
public static AbstractDataSourceLoader 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<? extends LodDataSource> clazz, byte dataVersion)
|
||||
public static AbstractDataSourceLoader getLoader(Class<? extends ILodDataSource> clazz, byte dataVersion)
|
||||
{
|
||||
return loaderRegistry.get(clazz).stream()
|
||||
.filter(l -> Arrays.binarySearch(l.loaderSupportedVersions, dataVersion) >= 0)
|
||||
@@ -32,7 +32,7 @@ public abstract class DataSourceLoader
|
||||
public final long datatypeId;
|
||||
public final byte[] loaderSupportedVersions;
|
||||
|
||||
public DataSourceLoader(Class<? extends LodDataSource> clazz, long datatypeId, byte[] loaderSupportedVersions)
|
||||
public AbstractDataSourceLoader(Class<? extends ILodDataSource> clazz, long datatypeId, byte[] loaderSupportedVersions)
|
||||
{
|
||||
this.datatypeId = datatypeId;
|
||||
this.loaderSupportedVersions = loaderSupportedVersions;
|
||||
@@ -43,7 +43,7 @@ public abstract class DataSourceLoader
|
||||
throw new IllegalArgumentException("Loader for datatypeId " + datatypeId + " already registered with different class: "
|
||||
+ datatypeIdRegistry.get(datatypeId) + " != " + clazz);
|
||||
}
|
||||
Set<DataSourceLoader> loaders = loaderRegistry.get(clazz);
|
||||
Set<AbstractDataSourceLoader> loaders = loaderRegistry.get(clazz);
|
||||
if (loaders.stream().anyMatch(other -> {
|
||||
// see if any loaderSupportsVersion conflicts with this one
|
||||
for (byte otherVer : other.loaderSupportedVersions)
|
||||
@@ -62,7 +62,7 @@ public abstract class DataSourceLoader
|
||||
}
|
||||
|
||||
// Can return null as meaning the requirement is not met
|
||||
public abstract LodDataSource loadData(DataMetaFile dataFile, InputStream data, IDhLevel level) throws IOException;
|
||||
public abstract ILodDataSource loadData(DataMetaFile dataFile, InputStream data, IDhLevel level) throws IOException;
|
||||
|
||||
|
||||
}
|
||||
+10
-10
@@ -9,31 +9,31 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.*;
|
||||
|
||||
public abstract class RenderSourceLoader
|
||||
public abstract class AbstractRenderSourceLoader
|
||||
{
|
||||
public static final HashMultimap<Class<? extends LodRenderSource>, RenderSourceLoader> loaderRegistry = HashMultimap.create();
|
||||
public static final HashMap<Long, Class<? extends LodRenderSource>> renderTypeIdRegistry = new HashMap<>();
|
||||
public static final HashMultimap<Class<? extends ILodRenderSource>, AbstractRenderSourceLoader> loaderRegistry = HashMultimap.create();
|
||||
public static final HashMap<Long, Class<? extends ILodRenderSource>> renderTypeIdRegistry = new HashMap<>();
|
||||
|
||||
public static RenderSourceLoader getLoader(long renderTypeId, byte loaderVersion)
|
||||
public static AbstractRenderSourceLoader 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<? extends LodRenderSource> clazz, byte loaderVersion)
|
||||
public static AbstractRenderSourceLoader getLoader(Class<? extends ILodRenderSource> clazz, byte loaderVersion)
|
||||
{
|
||||
return loaderRegistry.get(clazz).stream()
|
||||
.filter(l -> Arrays.binarySearch(l.loaderSupportedVersions, loaderVersion) >= 0)
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
public final Class<? extends LodRenderSource> clazz;
|
||||
public final Class<? extends ILodRenderSource> clazz;
|
||||
public final long renderTypeId;
|
||||
public final byte[] loaderSupportedVersions;
|
||||
public final byte detailOffset;
|
||||
|
||||
public RenderSourceLoader(Class<? extends LodRenderSource> clazz, long renderTypeId, byte[] loaderSupportedVersions, byte detailOffset)
|
||||
public AbstractRenderSourceLoader(Class<? extends ILodRenderSource> clazz, long renderTypeId, byte[] loaderSupportedVersions, byte detailOffset)
|
||||
{
|
||||
this.renderTypeId = renderTypeId;
|
||||
this.loaderSupportedVersions = loaderSupportedVersions;
|
||||
@@ -44,7 +44,7 @@ public abstract class RenderSourceLoader
|
||||
throw new IllegalArgumentException("Loader for renderTypeId " + renderTypeId + " already registered with different class: "
|
||||
+ renderTypeIdRegistry.get(renderTypeId) + " != " + clazz);
|
||||
}
|
||||
Set<RenderSourceLoader> loaders = loaderRegistry.get(clazz);
|
||||
Set<AbstractRenderSourceLoader> loaders = loaderRegistry.get(clazz);
|
||||
if (loaders.stream().anyMatch(other -> {
|
||||
// see if any loaderSupportsVersion conflicts with this one
|
||||
for (byte otherVer : other.loaderSupportedVersions)
|
||||
@@ -64,8 +64,8 @@ public abstract class RenderSourceLoader
|
||||
}
|
||||
|
||||
// Can return null as meaning the file is out of date or something
|
||||
public abstract LodRenderSource loadRender(RenderMetaFile renderFile, InputStream data, IDhLevel level) throws IOException;
|
||||
public abstract LodRenderSource createRender(LodDataSource dataSource, IDhClientLevel level);
|
||||
public abstract ILodRenderSource loadRender(RenderMetaFile renderFile, InputStream data, IDhLevel level) throws IOException;
|
||||
public abstract ILodRenderSource createRender(ILodDataSource dataSource, IDhClientLevel level);
|
||||
|
||||
|
||||
}
|
||||
+1
-1
@@ -8,7 +8,7 @@ import com.seibel.lod.core.file.datafile.DataMetaFile;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public interface LodDataSource
|
||||
public interface ILodDataSource
|
||||
{
|
||||
DhSectionPos getSectionPos();
|
||||
|
||||
+2
-2
@@ -11,7 +11,7 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public interface LodRenderSource
|
||||
public interface ILodRenderSource
|
||||
{
|
||||
DhSectionPos getSectionPos();
|
||||
|
||||
@@ -44,5 +44,5 @@ public interface LodRenderSource
|
||||
void fastWrite(ChunkSizedData chunkData, IDhClientLevel level);
|
||||
|
||||
/** Only override the data that has not been written directly using write(), and skip those that are empty */
|
||||
void weakWrite(LodRenderSource source);
|
||||
void weakWrite(ILodRenderSource source);
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class PlaceHolderRenderSource implements LodRenderSource
|
||||
public class PlaceHolderRenderSource implements ILodRenderSource
|
||||
{
|
||||
final DhSectionPos pos;
|
||||
boolean isValid = true;
|
||||
@@ -57,7 +57,7 @@ public class PlaceHolderRenderSource implements LodRenderSource
|
||||
public void fastWrite(ChunkSizedData chunkData, IDhClientLevel level) { /* TODO */ }
|
||||
|
||||
@Override
|
||||
public void weakWrite(LodRenderSource source) { /* TODO */ }
|
||||
public void weakWrite(ILodRenderSource source) { /* TODO */ }
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
package com.seibel.lod.core.datatype.column;
|
||||
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.datatype.full.FullDataSource;
|
||||
import com.seibel.lod.core.datatype.full.SparseDataSource;
|
||||
import com.seibel.lod.core.datatype.transform.FullToColumnTransformer;
|
||||
import com.seibel.lod.core.level.IDhClientLevel;
|
||||
import com.seibel.lod.core.datatype.LodRenderSource;
|
||||
import com.seibel.lod.core.datatype.RenderSourceLoader;
|
||||
import com.seibel.lod.core.datatype.ILodRenderSource;
|
||||
import com.seibel.lod.core.datatype.AbstractRenderSourceLoader;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
import com.seibel.lod.core.file.renderfile.RenderMetaFile;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
@@ -15,19 +15,20 @@ import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class ColumnRenderLoader extends RenderSourceLoader {
|
||||
public class ColumnRenderLoader extends AbstractRenderSourceLoader
|
||||
{
|
||||
public ColumnRenderLoader() {
|
||||
super(ColumnRenderSource.class, ColumnRenderSource.TYPE_ID, new byte[]{ColumnRenderSource.LATEST_VERSION}, ColumnRenderSource.SECTION_SIZE_OFFSET);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LodRenderSource loadRender(RenderMetaFile dataFile, InputStream data, IDhLevel level) throws IOException {
|
||||
public ILodRenderSource loadRender(RenderMetaFile 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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LodRenderSource createRender(LodDataSource dataSource, IDhClientLevel level) {
|
||||
public ILodRenderSource createRender(ILodDataSource dataSource, IDhClientLevel level) {
|
||||
if (dataSource instanceof FullDataSource) {
|
||||
return FullToColumnTransformer.transformFullDataToColumnData(level, (FullDataSource) dataSource);
|
||||
} else if (dataSource instanceof SparseDataSource) {
|
||||
|
||||
@@ -13,7 +13,7 @@ import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
import com.seibel.lod.core.render.LodQuadTree;
|
||||
import com.seibel.lod.core.render.LodRenderSection;
|
||||
import com.seibel.lod.core.datatype.LodRenderSource;
|
||||
import com.seibel.lod.core.datatype.ILodRenderSource;
|
||||
import com.seibel.lod.core.util.ColorUtil;
|
||||
import com.seibel.lod.core.util.objects.Reference;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
@@ -28,7 +28,7 @@ import java.nio.ByteOrder;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
public class ColumnRenderSource implements ILodRenderSource, IColumnDatatype {
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
public static final boolean DO_SAFETY_CHECKS = true;
|
||||
public static final byte SECTION_SIZE_OFFSET = 6;
|
||||
@@ -392,7 +392,7 @@ public class ColumnRenderSource implements LodRenderSource, IColumnDatatype {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void weakWrite(LodRenderSource source) {
|
||||
public void weakWrite(ILodRenderSource source) {
|
||||
LodUtil.assertTrue(source instanceof ColumnRenderSource);
|
||||
ColumnRenderSource src = (ColumnRenderSource) source;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.seibel.lod.core.datatype.full;
|
||||
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.datatype.full.accessor.SingleFullArrayView;
|
||||
import com.seibel.lod.core.pos.DhLodPos;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
@@ -14,21 +14,21 @@ import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class FullDataDownSampler {
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
public static CompletableFuture<LodDataSource> createDownSamplingFuture(DhSectionPos newTarget, IDataSourceProvider provider) {
|
||||
public static CompletableFuture<ILodDataSource> createDownSamplingFuture(DhSectionPos newTarget, IDataSourceProvider provider) {
|
||||
// TODO: Make this future somehow run with lowest priority (to ensure ram usage stays low)
|
||||
return createDownSamplingFuture(FullDataSource.createEmpty(newTarget), provider);
|
||||
}
|
||||
|
||||
public static CompletableFuture<LodDataSource> createDownSamplingFuture(FullDataSource target, IDataSourceProvider provider) {
|
||||
public static CompletableFuture<ILodDataSource> createDownSamplingFuture(FullDataSource target, IDataSourceProvider provider) {
|
||||
int sectionSizeNeeded = 1 << target.getDataDetail();
|
||||
|
||||
ArrayList<CompletableFuture<LodDataSource>> futures;
|
||||
ArrayList<CompletableFuture<ILodDataSource>> futures;
|
||||
DhLodPos basePos = target.getSectionPos().getSectionBBoxPos().getCorner(FullDataSource.SECTION_SIZE_OFFSET);
|
||||
if (sectionSizeNeeded <= FullDataSource.SECTION_SIZE_OFFSET) {
|
||||
futures = new ArrayList<>(sectionSizeNeeded * sectionSizeNeeded);
|
||||
for (int ox = 0; ox < sectionSizeNeeded; ox++) {
|
||||
for (int oz = 0; oz < sectionSizeNeeded; oz++) {
|
||||
CompletableFuture<LodDataSource> future = provider.read(new DhSectionPos(
|
||||
CompletableFuture<ILodDataSource> future = provider.read(new DhSectionPos(
|
||||
FullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox, basePos.z + oz));
|
||||
future = future.whenComplete((source, ex) -> {
|
||||
if (ex == null && source != null && source instanceof FullDataSource) {
|
||||
@@ -45,7 +45,7 @@ public class FullDataDownSampler {
|
||||
int multiplier = sectionSizeNeeded / FullDataSource.SECTION_SIZE;
|
||||
for (int ox = 0; ox < FullDataSource.SECTION_SIZE; ox++) {
|
||||
for (int oz = 0; oz < FullDataSource.SECTION_SIZE; oz++) {
|
||||
CompletableFuture<LodDataSource> future = provider.read(new DhSectionPos(
|
||||
CompletableFuture<ILodDataSource> future = provider.read(new DhSectionPos(
|
||||
FullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox * multiplier, basePos.z + oz * multiplier));
|
||||
future = future.whenComplete((source, ex) -> {
|
||||
if (ex == null && source != null && source instanceof FullDataSource) {
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
package com.seibel.lod.core.datatype.full;
|
||||
|
||||
import com.seibel.lod.core.datatype.DataSourceLoader;
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.AbstractDataSourceLoader;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
import com.seibel.lod.core.file.datafile.DataMetaFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class FullDataLoader extends DataSourceLoader {
|
||||
public class FullDataLoader extends AbstractDataSourceLoader
|
||||
{
|
||||
public FullDataLoader() {
|
||||
super(FullDataSource.class, FullDataSource.TYPE_ID, new byte[]{FullDataSource.LATEST_VERSION});
|
||||
}
|
||||
|
||||
@Override
|
||||
public LodDataSource loadData(DataMetaFile dataFile, InputStream data, IDhLevel level) throws IOException {
|
||||
public ILodDataSource loadData(DataMetaFile dataFile, InputStream data, IDhLevel level) throws IOException {
|
||||
//TODO: Add decompressor here
|
||||
return FullDataSource.loadData(dataFile, data, level);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import com.seibel.lod.core.level.IDhLevel;
|
||||
import com.seibel.lod.core.pos.DhBlockPos2D;
|
||||
import com.seibel.lod.core.pos.DhLodPos;
|
||||
import com.seibel.lod.core.file.datafile.DataMetaFile;
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
import com.seibel.lod.core.util.objects.UnclosableInputStream;
|
||||
import com.seibel.lod.core.logging.DhLoggerBuilder;
|
||||
@@ -15,7 +15,8 @@ import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.io.*;
|
||||
|
||||
public class FullDataSource extends FullArrayView implements LodDataSource { // 1 chunk
|
||||
public class FullDataSource extends FullArrayView implements ILodDataSource
|
||||
{ // 1 chunk
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
public static final byte SECTION_SIZE_OFFSET = 6;
|
||||
public static final int SECTION_SIZE = 1 << SECTION_SIZE_OFFSET;
|
||||
|
||||
@@ -1,20 +1,21 @@
|
||||
package com.seibel.lod.core.datatype.full;
|
||||
|
||||
import com.seibel.lod.core.datatype.DataSourceLoader;
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.AbstractDataSourceLoader;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
import com.seibel.lod.core.file.datafile.DataMetaFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class SparseDataLoader extends DataSourceLoader {
|
||||
public class SparseDataLoader extends AbstractDataSourceLoader
|
||||
{
|
||||
public SparseDataLoader() {
|
||||
super(SparseDataSource.class, SparseDataSource.TYPE_ID, new byte[]{SparseDataSource.LATEST_VERSION});
|
||||
}
|
||||
|
||||
@Override
|
||||
public LodDataSource loadData(DataMetaFile dataFile, InputStream data, IDhLevel level) throws IOException {
|
||||
public ILodDataSource loadData(DataMetaFile dataFile, InputStream data, IDhLevel level) throws IOException {
|
||||
return SparseDataSource.loadData(dataFile, data, level);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.seibel.lod.core.datatype.full;
|
||||
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.datatype.full.accessor.FullArrayView;
|
||||
import com.seibel.lod.core.datatype.full.accessor.SingleFullArrayView;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
@@ -14,7 +14,8 @@ import org.apache.logging.log4j.Logger;
|
||||
import java.io.*;
|
||||
import java.util.BitSet;
|
||||
|
||||
public class SparseDataSource implements LodDataSource {
|
||||
public class SparseDataSource implements ILodDataSource
|
||||
{
|
||||
private static final Logger LOGGER = DhLoggerBuilder.getLogger();
|
||||
public static final byte SPARSE_UNIT_DETAIL = 4;
|
||||
public static final byte SPARSE_UNIT_SIZE = 1 << SPARSE_UNIT_DETAIL;
|
||||
@@ -300,7 +301,7 @@ public class SparseDataSource implements LodDataSource {
|
||||
}
|
||||
|
||||
|
||||
public LodDataSource promote(LodDataSource generatedData) {
|
||||
public ILodDataSource promote(ILodDataSource generatedData) {
|
||||
if (!(generatedData instanceof FullDataSource) && !(generatedData instanceof SparseDataSource))
|
||||
throw new UnsupportedOperationException("Requires FullDataSource for the promotion!");
|
||||
if (generatedData instanceof FullDataSource) {
|
||||
@@ -312,7 +313,7 @@ public class SparseDataSource implements LodDataSource {
|
||||
}
|
||||
}
|
||||
|
||||
public LodDataSource trySelfPromote() {
|
||||
public ILodDataSource trySelfPromote() {
|
||||
if (isEmpty) return this;
|
||||
for (FullArrayView array : sparseData) {
|
||||
if (array == null) return this;
|
||||
|
||||
+5
-5
@@ -1,7 +1,7 @@
|
||||
package com.seibel.lod.core.datatype.transform;
|
||||
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.LodRenderSource;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.datatype.ILodRenderSource;
|
||||
import com.seibel.lod.core.datatype.column.ColumnRenderLoader;
|
||||
import com.seibel.lod.core.datatype.column.ColumnRenderSource;
|
||||
import com.seibel.lod.core.level.IDhClientLevel;
|
||||
@@ -15,15 +15,15 @@ public class DataRenderTransformer {
|
||||
public static final ExecutorService TRANSFORMER_THREADS
|
||||
= LodUtil.makeThreadPool(4, "Data/Render Transformer");
|
||||
|
||||
public static CompletableFuture<LodRenderSource> transformDataSource(LodDataSource data, IDhClientLevel level) {
|
||||
public static CompletableFuture<ILodRenderSource> transformDataSource(ILodDataSource data, IDhClientLevel level) {
|
||||
return CompletableFuture.supplyAsync(() -> transform(data, level), TRANSFORMER_THREADS);
|
||||
}
|
||||
|
||||
public static CompletableFuture<LodRenderSource> asyncTransformDataSource(CompletableFuture<LodDataSource> data, IDhClientLevel level) {
|
||||
public static CompletableFuture<ILodRenderSource> asyncTransformDataSource(CompletableFuture<ILodDataSource> data, IDhClientLevel level) {
|
||||
return data.thenApplyAsync((d) -> transform(d, level), TRANSFORMER_THREADS);
|
||||
}
|
||||
|
||||
private static LodRenderSource transform(LodDataSource dataSource, IDhClientLevel level) {
|
||||
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);
|
||||
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
package com.seibel.lod.core.datatype.transform;
|
||||
|
||||
import com.seibel.lod.core.datatype.LodRenderSource;
|
||||
import com.seibel.lod.core.datatype.ILodRenderSource;
|
||||
import com.seibel.lod.core.datatype.column.accessor.ColumnFormat;
|
||||
import com.seibel.lod.core.datatype.column.ColumnRenderSource;
|
||||
import com.seibel.lod.core.datatype.column.accessor.ColumnArrayView;
|
||||
@@ -66,7 +66,7 @@ public class FullToColumnTransformer {
|
||||
return columnSource;
|
||||
}
|
||||
|
||||
public static LodRenderSource transformSparseDataToColumnData(IDhClientLevel level, SparseDataSource data) {
|
||||
public static ILodRenderSource transformSparseDataToColumnData(IDhClientLevel level, SparseDataSource data) {
|
||||
final DhSectionPos pos = data.getSectionPos();
|
||||
final byte dataDetail = data.getDataDetail();
|
||||
final int vertSize = Config.Client.Graphics.Quality.verticalQuality.get().calculateMaxVerticalData(data.getDataDetail());
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.seibel.lod.core.file.datafile;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.datatype.full.ChunkSizedData;
|
||||
import com.seibel.lod.core.datatype.full.FullDataSource;
|
||||
import com.seibel.lod.core.datatype.full.SparseDataSource;
|
||||
@@ -215,7 +215,7 @@ public class DataFileHandler implements IDataSourceProvider {
|
||||
* This call is concurrent. I.e. it supports multiple threads calling this method at the same time.
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<LodDataSource> read(DhSectionPos pos) {
|
||||
public CompletableFuture<ILodDataSource> read(DhSectionPos pos) {
|
||||
topDetailLevel.updateAndGet(v -> Math.max(v, pos.sectionDetail));
|
||||
DataMetaFile metaFile = atomicGetOrMakeFile(pos);
|
||||
if (metaFile == null) return CompletableFuture.completedFuture(null);
|
||||
@@ -262,7 +262,7 @@ public class DataFileHandler implements IDataSourceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<LodDataSource> onCreateDataFile(DataMetaFile file) {
|
||||
public CompletableFuture<ILodDataSource> onCreateDataFile(DataMetaFile file) {
|
||||
DhSectionPos pos = file.pos;
|
||||
ArrayList<DataMetaFile> existFiles = new ArrayList<>();
|
||||
ArrayList<DhSectionPos> missing = new ArrayList<>();
|
||||
@@ -301,12 +301,12 @@ public class DataFileHandler implements IDataSourceProvider {
|
||||
}
|
||||
|
||||
@Override
|
||||
public LodDataSource onDataFileLoaded(LodDataSource source, MetaFile.MetaData metaData,
|
||||
Consumer<LodDataSource> onUpdated, Function<LodDataSource, Boolean> updater) {
|
||||
public ILodDataSource onDataFileLoaded(ILodDataSource source, MetaFile.MetaData metaData,
|
||||
Consumer<ILodDataSource> onUpdated, Function<ILodDataSource, Boolean> updater) {
|
||||
boolean changed = updater.apply(source);
|
||||
if (changed) metaData.dataVersion.incrementAndGet();
|
||||
if (source instanceof SparseDataSource) {
|
||||
LodDataSource newSource = ((SparseDataSource) source).trySelfPromote();
|
||||
ILodDataSource newSource = ((SparseDataSource) source).trySelfPromote();
|
||||
changed |= newSource != source;
|
||||
source = newSource;
|
||||
}
|
||||
@@ -314,12 +314,12 @@ public class DataFileHandler implements IDataSourceProvider {
|
||||
return source;
|
||||
}
|
||||
@Override
|
||||
public CompletableFuture<LodDataSource> onDataFileRefresh(LodDataSource source, Function<LodDataSource, Boolean> updater, Consumer<LodDataSource> onUpdated) {
|
||||
public CompletableFuture<ILodDataSource> onDataFileRefresh(ILodDataSource source, Function<ILodDataSource, Boolean> updater, Consumer<ILodDataSource> onUpdated) {
|
||||
return CompletableFuture.supplyAsync(() -> {
|
||||
LodDataSource sourceLocal = source;
|
||||
ILodDataSource sourceLocal = source;
|
||||
boolean changed = updater.apply(sourceLocal);
|
||||
if (sourceLocal instanceof SparseDataSource) {
|
||||
LodDataSource newSource = ((SparseDataSource) sourceLocal).trySelfPromote();
|
||||
ILodDataSource newSource = ((SparseDataSource) sourceLocal).trySelfPromote();
|
||||
changed |= newSource != sourceLocal;
|
||||
sourceLocal = newSource;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,8 @@ import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock;
|
||||
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.DataSourceLoader;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.datatype.AbstractDataSourceLoader;
|
||||
import com.seibel.lod.core.datatype.full.ChunkSizedData;
|
||||
import com.seibel.lod.core.pos.DhLodPos;
|
||||
import com.seibel.lod.core.file.MetaFile;
|
||||
@@ -28,8 +28,8 @@ public class DataMetaFile extends MetaFile
|
||||
private final IDataSourceProvider handler;
|
||||
private boolean doesFileExist;
|
||||
|
||||
public DataSourceLoader loader;
|
||||
public Class<? extends LodDataSource> dataType;
|
||||
public AbstractDataSourceLoader loader;
|
||||
public Class<? extends ILodDataSource> dataType;
|
||||
// The '?' type should either be:
|
||||
// SoftReference<LodDataSource>, or - Non-dirty file that can be GCed
|
||||
// CompletableFuture<LodDataSource>, or - File that is being loaded. No guarantee that the type is promotable or not
|
||||
@@ -51,11 +51,11 @@ public class DataMetaFile extends MetaFile
|
||||
private final AtomicBoolean inCacheWriteAccessAsserter = new AtomicBoolean(false);
|
||||
|
||||
// ===Object lifetime stuff===
|
||||
private static final ReferenceQueue<LodDataSource> lifeCycleDebugQueue = new ReferenceQueue<>();
|
||||
private static final ReferenceQueue<ILodDataSource> lifeCycleDebugQueue = new ReferenceQueue<>();
|
||||
private static final Set<DataObjTracker> lifeCycleDebugSet = ConcurrentHashMap.newKeySet();
|
||||
private static class DataObjTracker extends PhantomReference<LodDataSource> implements Closeable {
|
||||
private static class DataObjTracker extends PhantomReference<ILodDataSource> implements Closeable {
|
||||
private final DhSectionPos pos;
|
||||
DataObjTracker(LodDataSource data) {
|
||||
DataObjTracker(ILodDataSource data) {
|
||||
super(data, lifeCycleDebugQueue);
|
||||
//LOGGER.info("Phantom created on {}! count: {}", data.getSectionPos(), lifeCycleDebugSet.size());
|
||||
lifeCycleDebugSet.add(this);
|
||||
@@ -86,7 +86,7 @@ public class DataMetaFile extends MetaFile
|
||||
this.handler = handler;
|
||||
this.level = level;
|
||||
LodUtil.assertTrue(metaData != null);
|
||||
loader = DataSourceLoader.getLoader(metaData.dataTypeId, metaData.loaderVersion);
|
||||
loader = AbstractDataSourceLoader.getLoader(metaData.dataTypeId, metaData.loaderVersion);
|
||||
if (loader == null) {
|
||||
throw new IOException("Invalid file: Data type loader not found: "
|
||||
+ metaData.dataTypeId + "(v" + metaData.loaderVersion + ")");
|
||||
@@ -131,14 +131,14 @@ public class DataMetaFile extends MetaFile
|
||||
|
||||
// Cause: Generic Type runtime casting cannot safety check it.
|
||||
// However, the Union type ensures the 'data' should only contain the listed type.
|
||||
public CompletableFuture<LodDataSource> loadOrGetCached() {
|
||||
public CompletableFuture<ILodDataSource> loadOrGetCached() {
|
||||
debugCheck();
|
||||
Object obj = data.get();
|
||||
|
||||
CompletableFuture<LodDataSource> cached = _readCached(obj);
|
||||
CompletableFuture<ILodDataSource> cached = _readCached(obj);
|
||||
if (cached != null) return cached;
|
||||
|
||||
CompletableFuture<LodDataSource> future = new CompletableFuture<>();
|
||||
CompletableFuture<ILodDataSource> future = new CompletableFuture<>();
|
||||
|
||||
// Would use faster and non-nesting Compare and exchange. But java 8 doesn't have it! :(
|
||||
boolean worked = data.compareAndSet(obj, future);
|
||||
@@ -168,7 +168,7 @@ public class DataMetaFile extends MetaFile
|
||||
if (metaData == null)
|
||||
throw new IllegalStateException("Meta data not loaded!");
|
||||
// Load the file.
|
||||
LodDataSource data;
|
||||
ILodDataSource data;
|
||||
try (FileInputStream fio = getDataContent()){
|
||||
data = loader.loadData(this, fio, level);
|
||||
} catch (IOException e) {
|
||||
@@ -199,8 +199,8 @@ public class DataMetaFile extends MetaFile
|
||||
return future;
|
||||
}
|
||||
|
||||
private static MetaData makeMetaData(LodDataSource data) {
|
||||
DataSourceLoader loader = DataSourceLoader.getLoader(data.getClass(), data.getDataVersion());
|
||||
private static MetaData makeMetaData(ILodDataSource data) {
|
||||
AbstractDataSourceLoader loader = AbstractDataSourceLoader.getLoader(data.getClass(), data.getDataVersion());
|
||||
return new MetaData(data.getSectionPos(), -1, 1,
|
||||
data.getDataDetail(), loader == null ? 0 : loader.datatypeId, data.getDataVersion());
|
||||
}
|
||||
@@ -208,12 +208,12 @@ public class DataMetaFile extends MetaFile
|
||||
// "unchecked": Suppress casting of CompletableFuture<?> to CompletableFuture<LodDataSource>
|
||||
// "PointlessBooleanExpression": Suppress explicit (boolean == false) check for more understandable CAS operation code.
|
||||
@SuppressWarnings({"unchecked", "PointlessBooleanExpression"})
|
||||
private CompletableFuture<LodDataSource> _readCached(Object obj) {
|
||||
private CompletableFuture<ILodDataSource> _readCached(Object obj) {
|
||||
// Has file cached in RAM and not freed yet.
|
||||
if ((obj instanceof SoftReference<?>)) {
|
||||
Object inner = ((SoftReference<?>)obj).get();
|
||||
if (inner != null) {
|
||||
LodUtil.assertTrue(inner instanceof LodDataSource);
|
||||
LodUtil.assertTrue(inner instanceof ILodDataSource);
|
||||
boolean isEmpty = writeQueue.get().queue.isEmpty();
|
||||
// If the queue is empty, and the CAS on inCacheWriteLock succeeds, then we are the thread
|
||||
// that will be applying the changes to the cache.
|
||||
@@ -227,7 +227,7 @@ public class DataMetaFile extends MetaFile
|
||||
// For now, I'll go for the latter option and just hope nothing goes wrong...
|
||||
if (inCacheWriteAccessAsserter.getAndSet(true) == false) {
|
||||
try {
|
||||
return handler.onDataFileRefresh((LodDataSource) inner, this::applyWriteQueue, this::saveChanges);
|
||||
return handler.onDataFileRefresh((ILodDataSource) inner, this::applyWriteQueue, this::saveChanges);
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Error while applying changes to LodDataSource at {}: ", pos, e);
|
||||
} finally {
|
||||
@@ -235,11 +235,11 @@ public class DataMetaFile extends MetaFile
|
||||
}
|
||||
} else {
|
||||
// or, return the cached data. FIXME: See above.
|
||||
return CompletableFuture.completedFuture((LodDataSource) inner);
|
||||
return CompletableFuture.completedFuture((ILodDataSource) inner);
|
||||
}
|
||||
} else {
|
||||
// or, return the cached data.
|
||||
return CompletableFuture.completedFuture((LodDataSource) inner);
|
||||
return CompletableFuture.completedFuture((ILodDataSource) inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -247,7 +247,7 @@ public class DataMetaFile extends MetaFile
|
||||
//==== Cached file out of scrope. ====
|
||||
// Someone is already trying to complete it. so just return the obj.
|
||||
if ((obj instanceof CompletableFuture<?>)) {
|
||||
return (CompletableFuture<LodDataSource>)obj;
|
||||
return (CompletableFuture<ILodDataSource>)obj;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -265,7 +265,7 @@ public class DataMetaFile extends MetaFile
|
||||
_backQueue = queue;
|
||||
}
|
||||
|
||||
private void saveChanges(LodDataSource data) {
|
||||
private void saveChanges(ILodDataSource data) {
|
||||
if (data.isEmpty()) {
|
||||
if (path.exists()) if (!path.delete()) LOGGER.warn("Failed to delete data file at {}", path);
|
||||
doesFileExist = false;
|
||||
@@ -274,7 +274,7 @@ public class DataMetaFile extends MetaFile
|
||||
// Write/Update data
|
||||
LodUtil.assertTrue(metaData != null);
|
||||
metaData.dataLevel = data.getDataDetail();
|
||||
loader = DataSourceLoader.getLoader(data.getClass(), data.getDataVersion());
|
||||
loader = AbstractDataSourceLoader.getLoader(data.getClass(), data.getDataVersion());
|
||||
LodUtil.assertTrue(loader != null, "No loader for {} (v{})", data.getClass(), data.getDataVersion());
|
||||
dataType = data.getClass();
|
||||
metaData.dataTypeId = loader == null ? 0 : loader.datatypeId;
|
||||
@@ -288,7 +288,7 @@ public class DataMetaFile extends MetaFile
|
||||
}
|
||||
|
||||
// Return whether any write has happened to the data
|
||||
private boolean applyWriteQueue(LodDataSource data) {
|
||||
private boolean applyWriteQueue(ILodDataSource data) {
|
||||
// Poll the write queue
|
||||
// First check if write queue is empty, then swap the write queue.
|
||||
// Must be done in this order to ensure isValid work properly. See isValid() for details.
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
package com.seibel.lod.core.file.datafile;
|
||||
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.datatype.full.ChunkSizedData;
|
||||
import com.seibel.lod.core.datatype.full.FullDataSource;
|
||||
import com.seibel.lod.core.datatype.full.SparseDataSource;
|
||||
@@ -23,13 +23,13 @@ public class GeneratedDataFileHandler extends DataFileHandler {
|
||||
|
||||
AtomicReference<GenerationQueue> queue = new AtomicReference<>(null);
|
||||
// TODO: Should I include a lib that impl weak concurrent hash map?
|
||||
final Map<LodDataSource, GenTask> genQueue = Collections.synchronizedMap(new WeakHashMap<>());
|
||||
final Map<ILodDataSource, GenTask> genQueue = Collections.synchronizedMap(new WeakHashMap<>());
|
||||
|
||||
class GenTask extends GenerationQueue.GenTaskTracker {
|
||||
final DhSectionPos pos;
|
||||
WeakReference<LodDataSource> targetData;
|
||||
LodDataSource loadedTargetData = null;
|
||||
GenTask(DhSectionPos pos, WeakReference<LodDataSource> targetData) {
|
||||
WeakReference<ILodDataSource> targetData;
|
||||
ILodDataSource loadedTargetData = null;
|
||||
GenTask(DhSectionPos pos, WeakReference<ILodDataSource> targetData) {
|
||||
this.pos = pos;
|
||||
this.targetData = targetData;
|
||||
}
|
||||
@@ -63,15 +63,15 @@ public class GeneratedDataFileHandler extends DataFileHandler {
|
||||
boolean worked = queue.compareAndSet(null, newQueue);
|
||||
LodUtil.assertTrue(worked, "previous queue is still here!");
|
||||
synchronized (genQueue) {
|
||||
for (Map.Entry<LodDataSource, GenTask> entry : genQueue.entrySet()) {
|
||||
LodDataSource source = entry.getKey();
|
||||
for (Map.Entry<ILodDataSource, GenTask> entry : genQueue.entrySet()) {
|
||||
ILodDataSource source = entry.getKey();
|
||||
DhSectionPos pos = source.getSectionPos();
|
||||
GenTask task = entry.getValue();
|
||||
queue.get().submitGenTask(pos.getSectionBBoxPos(), source.getDataDetail(), task)
|
||||
.whenComplete(
|
||||
(b, ex) -> {
|
||||
if (ex != null) LOGGER.error("Uncaught Gen Task Exception at {}:", pos, ex);
|
||||
LodDataSource data = task.targetData.get();
|
||||
ILodDataSource data = task.targetData.get();
|
||||
if (ex == null && b) {
|
||||
files.get(task.pos).metaData.dataVersion.incrementAndGet();
|
||||
genQueue.remove(data, task);
|
||||
@@ -91,7 +91,7 @@ public class GeneratedDataFileHandler extends DataFileHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<LodDataSource> onCreateDataFile(DataMetaFile file) {
|
||||
public CompletableFuture<ILodDataSource> onCreateDataFile(DataMetaFile file) {
|
||||
DhSectionPos pos = file.pos;
|
||||
ArrayList<DataMetaFile> existFiles = new ArrayList<>();
|
||||
ArrayList<DhSectionPos> missing = new ArrayList<>();
|
||||
@@ -109,7 +109,7 @@ public class GeneratedDataFileHandler extends DataFileHandler {
|
||||
.whenComplete(
|
||||
(b, ex) -> {
|
||||
if (ex != null) LOGGER.error("Uncaught Gen Task Exception at {}:", pos, ex);
|
||||
LodDataSource data = task.targetData.get();
|
||||
ILodDataSource data = task.targetData.get();
|
||||
if (ex == null && b) {
|
||||
files.get(task.pos).metaData.dataVersion.incrementAndGet();
|
||||
genQueue.remove(data, task);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.seibel.lod.core.file.datafile;
|
||||
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.datatype.full.ChunkSizedData;
|
||||
import com.seibel.lod.core.file.MetaFile;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
@@ -15,15 +15,15 @@ import java.util.function.Function;
|
||||
public interface IDataSourceProvider extends AutoCloseable {
|
||||
void addScannedFile(Collection<File> detectedFiles);
|
||||
|
||||
CompletableFuture<LodDataSource> read(DhSectionPos pos);
|
||||
CompletableFuture<ILodDataSource> read(DhSectionPos pos);
|
||||
void write(DhSectionPos sectionPos, ChunkSizedData chunkData);
|
||||
CompletableFuture<Void> flushAndSave();
|
||||
|
||||
long getLatestCacheVersion(DhSectionPos sectionPos);
|
||||
|
||||
CompletableFuture<LodDataSource> onCreateDataFile(DataMetaFile file);
|
||||
LodDataSource onDataFileLoaded(LodDataSource source, MetaFile.MetaData metaData, Consumer<LodDataSource> onUpdated, Function<LodDataSource, Boolean> updater);
|
||||
CompletableFuture<LodDataSource> onDataFileRefresh(LodDataSource source, Function<LodDataSource, Boolean> updater, Consumer<LodDataSource> onUpdated);
|
||||
CompletableFuture<ILodDataSource> onCreateDataFile(DataMetaFile file);
|
||||
ILodDataSource onDataFileLoaded(ILodDataSource source, MetaFile.MetaData metaData, Consumer<ILodDataSource> onUpdated, Function<ILodDataSource, Boolean> updater);
|
||||
CompletableFuture<ILodDataSource> onDataFileRefresh(ILodDataSource source, Function<ILodDataSource, Boolean> updater, Consumer<ILodDataSource> onUpdated);
|
||||
File computeDataFilePath(DhSectionPos pos);
|
||||
Executor getIOExecutor();
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package com.seibel.lod.core.file.renderfile;
|
||||
|
||||
import com.seibel.lod.core.datatype.LodRenderSource;
|
||||
import com.seibel.lod.core.datatype.ILodRenderSource;
|
||||
import com.seibel.lod.core.datatype.full.ChunkSizedData;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
|
||||
@@ -9,9 +9,9 @@ import java.util.Collection;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public interface IRenderSourceProvider extends AutoCloseable {
|
||||
CompletableFuture<LodRenderSource> read(DhSectionPos pos);
|
||||
CompletableFuture<ILodRenderSource> read(DhSectionPos pos);
|
||||
void addScannedFile(Collection<File> detectedFiles);
|
||||
void write(DhSectionPos sectionPos, ChunkSizedData chunkData);
|
||||
CompletableFuture<Void> flushAndSave();
|
||||
boolean refreshRenderSource(LodRenderSource source);
|
||||
boolean refreshRenderSource(ILodRenderSource source);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
package com.seibel.lod.core.file.renderfile;
|
||||
|
||||
import com.google.common.collect.HashMultimap;
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.datatype.PlaceHolderRenderSource;
|
||||
import com.seibel.lod.core.datatype.LodRenderSource;
|
||||
import com.seibel.lod.core.datatype.RenderSourceLoader;
|
||||
import com.seibel.lod.core.datatype.ILodRenderSource;
|
||||
import com.seibel.lod.core.datatype.AbstractRenderSourceLoader;
|
||||
import com.seibel.lod.core.datatype.column.ColumnRenderSource;
|
||||
import com.seibel.lod.core.datatype.full.ChunkSizedData;
|
||||
import com.seibel.lod.core.datatype.transform.DataRenderTransformer;
|
||||
@@ -111,7 +111,7 @@ public class RenderFileHandler implements IRenderSourceProvider {
|
||||
* This call is concurrent. I.e. it supports multiple threads calling this method at the same time.
|
||||
*/
|
||||
@Override
|
||||
public CompletableFuture<LodRenderSource> read(DhSectionPos pos) {
|
||||
public CompletableFuture<ILodRenderSource> read(DhSectionPos pos) {
|
||||
RenderMetaFile metaFile = files.get(pos);
|
||||
if (metaFile == null) {
|
||||
RenderMetaFile newMetaFile;
|
||||
@@ -191,7 +191,7 @@ public class RenderFileHandler implements IRenderSourceProvider {
|
||||
return new File(saveDir, pos.serialize() + ".lod");
|
||||
}
|
||||
|
||||
public CompletableFuture<LodRenderSource> onCreateRenderFile(RenderMetaFile file) {
|
||||
public CompletableFuture<ILodRenderSource> onCreateRenderFile(RenderMetaFile file) {
|
||||
final int vertSize = Config.Client.Graphics.Quality.verticalQuality
|
||||
.get().calculateMaxVerticalData((byte) (file.pos.sectionDetail - ColumnRenderSource.SECTION_SIZE_OFFSET));
|
||||
return CompletableFuture.completedFuture(
|
||||
@@ -200,10 +200,10 @@ public class RenderFileHandler implements IRenderSourceProvider {
|
||||
|
||||
private final ConcurrentHashMap<DhSectionPos, Object> cacheRecreationGuards = new ConcurrentHashMap<>();
|
||||
|
||||
private void updateCache(LodRenderSource data, RenderMetaFile file) {
|
||||
private void updateCache(ILodRenderSource data, RenderMetaFile file) {
|
||||
if (cacheRecreationGuards.putIfAbsent(file.pos, new Object()) != null) return;
|
||||
final WeakReference<LodRenderSource> dataRef = new WeakReference<>(data);
|
||||
CompletableFuture<LodDataSource> dataFuture = dataSourceProvider.read(data.getSectionPos());
|
||||
final WeakReference<ILodRenderSource> dataRef = new WeakReference<>(data);
|
||||
CompletableFuture<ILodDataSource> dataFuture = dataSourceProvider.read(data.getSectionPos());
|
||||
final long version = dataSourceProvider.getLatestCacheVersion(data.getSectionPos());
|
||||
DataRenderTransformer.asyncTransformDataSource(
|
||||
dataFuture.thenApply((d) -> {
|
||||
@@ -225,7 +225,7 @@ public class RenderFileHandler implements IRenderSourceProvider {
|
||||
|
||||
}
|
||||
|
||||
public LodRenderSource onRenderFileLoaded(LodRenderSource data, RenderMetaFile file) {
|
||||
public ILodRenderSource onRenderFileLoaded(ILodRenderSource data, RenderMetaFile file) {
|
||||
long newCacheVersion = dataSourceProvider.getLatestCacheVersion(file.pos);
|
||||
//NOTE: Do this instead of direct compare so values that wrapped around still works correctly.
|
||||
if (newCacheVersion - file.metaData.dataVersion.get() <= 0)
|
||||
@@ -234,32 +234,32 @@ public class RenderFileHandler implements IRenderSourceProvider {
|
||||
return data;
|
||||
}
|
||||
|
||||
public LodRenderSource onLoadingRenderFile(RenderMetaFile file) {
|
||||
public ILodRenderSource onLoadingRenderFile(RenderMetaFile file) {
|
||||
return null; //Default behaviour
|
||||
}
|
||||
|
||||
private void write(LodRenderSource target, RenderMetaFile file,
|
||||
LodRenderSource newData, long newDataVersion) {
|
||||
private void write(ILodRenderSource target, RenderMetaFile file,
|
||||
ILodRenderSource newData, long newDataVersion) {
|
||||
if (target == null) return;
|
||||
if (newData == null) return;
|
||||
target.weakWrite(newData);
|
||||
file.metaData.dataVersion.set(newDataVersion);
|
||||
file.metaData.dataLevel = target.getDataDetail();
|
||||
file.loader = RenderSourceLoader.getLoader(target.getClass(), target.getRenderVersion());
|
||||
file.loader = AbstractRenderSourceLoader.getLoader(target.getClass(), target.getRenderVersion());
|
||||
file.dataType = target.getClass();
|
||||
file.metaData.dataTypeId = file.loader.renderTypeId;
|
||||
file.metaData.loaderVersion = target.getRenderVersion();
|
||||
file.save(target, level);
|
||||
}
|
||||
|
||||
public void onReadRenderSourceFromCache(RenderMetaFile file, LodRenderSource data) {
|
||||
public void onReadRenderSourceFromCache(RenderMetaFile file, ILodRenderSource data) {
|
||||
long newCacheVersion = dataSourceProvider.getLatestCacheVersion(file.pos);
|
||||
//NOTE: Do this instead of direct compare so values that wrapped around still works correctly.
|
||||
if (newCacheVersion - file.metaData.dataVersion.get() > 0)
|
||||
updateCache(data, file);
|
||||
}
|
||||
|
||||
public boolean refreshRenderSource(LodRenderSource source) {
|
||||
public boolean refreshRenderSource(ILodRenderSource source) {
|
||||
RenderMetaFile file = files.get(source.getSectionPos());
|
||||
if (source instanceof PlaceHolderRenderSource) {
|
||||
if (file == null || file.metaData == null) {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package com.seibel.lod.core.file.renderfile;
|
||||
|
||||
import com.seibel.lod.core.datatype.LodDataSource;
|
||||
import com.seibel.lod.core.datatype.LodRenderSource;
|
||||
import com.seibel.lod.core.datatype.RenderSourceLoader;
|
||||
import com.seibel.lod.core.datatype.ILodDataSource;
|
||||
import com.seibel.lod.core.datatype.ILodRenderSource;
|
||||
import com.seibel.lod.core.datatype.AbstractRenderSourceLoader;
|
||||
import com.seibel.lod.core.datatype.full.ChunkSizedData;
|
||||
import com.seibel.lod.core.level.IDhClientLevel;
|
||||
import com.seibel.lod.core.level.IDhLevel;
|
||||
@@ -26,8 +26,8 @@ public class RenderMetaFile extends MetaFile
|
||||
|
||||
//private final IClientLevel level;
|
||||
|
||||
public RenderSourceLoader loader;
|
||||
public Class<? extends LodRenderSource> dataType;
|
||||
public AbstractRenderSourceLoader loader;
|
||||
public Class<? extends ILodRenderSource> dataType;
|
||||
|
||||
// The '?' type should either be:
|
||||
// SoftReference<LodRenderSource>, or - File that may still be loaded
|
||||
@@ -41,14 +41,14 @@ public class RenderMetaFile extends MetaFile
|
||||
DhLodPos chunkPos = new DhLodPos((byte) (chunkData.dataDetail + 4), chunkData.x, chunkData.z);
|
||||
LodUtil.assertTrue(pos.getSectionBBoxPos().overlaps(chunkPos), "Chunk pos {} doesn't overlap with section {}", chunkPos, pos);
|
||||
|
||||
CompletableFuture<LodRenderSource> source = _readCached(data.get());
|
||||
CompletableFuture<ILodRenderSource> source = _readCached(data.get());
|
||||
if (source == null) return;
|
||||
source.thenAccept((renderSource) -> renderSource.fastWrite(chunkData, level));
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> flushAndSave(ExecutorService renderCacheThread) {
|
||||
if (!path.exists()) return CompletableFuture.completedFuture(null); // No need to save if the file doesn't exist.
|
||||
CompletableFuture<LodRenderSource> source = _readCached(data.get());
|
||||
CompletableFuture<ILodRenderSource> source = _readCached(data.get());
|
||||
if (source == null) return CompletableFuture.completedFuture(null); // If there is no cached data, there is no need to save.
|
||||
return source.thenAccept((a)->{}); // Otherwise, wait for the data to be read (which also flushes changes to the file).
|
||||
}
|
||||
@@ -59,7 +59,7 @@ public class RenderMetaFile extends MetaFile
|
||||
}
|
||||
@FunctionalInterface
|
||||
public interface CacheSourceProducer {
|
||||
CompletableFuture<LodDataSource> getSourceFuture(DhSectionPos sectionPos);
|
||||
CompletableFuture<ILodDataSource> getSourceFuture(DhSectionPos sectionPos);
|
||||
}
|
||||
CacheValidator validator;
|
||||
CacheSourceProducer source;
|
||||
@@ -79,7 +79,7 @@ public class RenderMetaFile extends MetaFile
|
||||
super(path);
|
||||
this.handler = handler;
|
||||
LodUtil.assertTrue(metaData != null);
|
||||
loader = RenderSourceLoader.getLoader(metaData.dataTypeId, metaData.loaderVersion);
|
||||
loader = AbstractRenderSourceLoader.getLoader(metaData.dataTypeId, metaData.loaderVersion);
|
||||
if (loader == null) {
|
||||
throw new IOException("Invalid file: Data type loader not found: "
|
||||
+ metaData.dataTypeId + "(v" + metaData.loaderVersion + ")");
|
||||
@@ -90,37 +90,37 @@ public class RenderMetaFile extends MetaFile
|
||||
|
||||
// Suppress casting of CompletableFuture<?> to CompletableFuture<LodRenderSource>
|
||||
@SuppressWarnings("unchecked")
|
||||
private CompletableFuture<LodRenderSource> _readCached(Object obj) {
|
||||
private CompletableFuture<ILodRenderSource> _readCached(Object obj) {
|
||||
// Has file cached in RAM and not freed yet.
|
||||
if ((obj instanceof SoftReference<?>)) {
|
||||
Object inner = ((SoftReference<?>)obj).get();
|
||||
if (inner != null) {
|
||||
LodUtil.assertTrue(inner instanceof LodRenderSource);
|
||||
handler.onReadRenderSourceFromCache(this, (LodRenderSource) inner);
|
||||
return CompletableFuture.completedFuture((LodRenderSource)inner);
|
||||
LodUtil.assertTrue(inner instanceof ILodRenderSource);
|
||||
handler.onReadRenderSourceFromCache(this, (ILodRenderSource) inner);
|
||||
return CompletableFuture.completedFuture((ILodRenderSource)inner);
|
||||
}
|
||||
}
|
||||
|
||||
//==== Cached file out of scope. ====
|
||||
// Someone is already trying to complete it. so just return the obj.
|
||||
if ((obj instanceof CompletableFuture<?>)) {
|
||||
return (CompletableFuture<LodRenderSource>)obj;
|
||||
return (CompletableFuture<ILodRenderSource>)obj;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Cause: Generic Type runtime casting cannot safety check it.
|
||||
// However, the Union type ensures the 'data' should only contain the listed type.
|
||||
public CompletableFuture<LodRenderSource> loadOrGetCached(Executor fileReaderThreads, IDhLevel level) {
|
||||
public CompletableFuture<ILodRenderSource> loadOrGetCached(Executor fileReaderThreads, IDhLevel level) {
|
||||
Object obj = data.get();
|
||||
|
||||
CompletableFuture<LodRenderSource> cached = _readCached(obj);
|
||||
CompletableFuture<ILodRenderSource> cached = _readCached(obj);
|
||||
if (cached != null) return cached;
|
||||
|
||||
// Create an empty and non-completed future.
|
||||
// Note: I do this before actually filling in the future so that I can ensure only
|
||||
// one task is submitted to the thread pool.
|
||||
CompletableFuture<LodRenderSource> future = new CompletableFuture<>();
|
||||
CompletableFuture<ILodRenderSource> future = new CompletableFuture<>();
|
||||
|
||||
// Would use faster and non-nesting Compare and exchange. But java 8 doesn't have it! :(
|
||||
boolean worked = data.compareAndSet(obj, future);
|
||||
@@ -153,7 +153,7 @@ public class RenderMetaFile extends MetaFile
|
||||
if (metaData == null)
|
||||
throw new IllegalStateException("Meta data not loaded!");
|
||||
// Load the file.
|
||||
LodRenderSource data;
|
||||
ILodRenderSource data;
|
||||
data = handler.onLoadingRenderFile(this);
|
||||
if (data == null) {
|
||||
try (FileInputStream fio = getDataContent()) {
|
||||
@@ -179,8 +179,8 @@ public class RenderMetaFile extends MetaFile
|
||||
return future;
|
||||
}
|
||||
|
||||
private static MetaData makeMetaData(LodRenderSource data) {
|
||||
RenderSourceLoader loader = RenderSourceLoader.getLoader(data.getClass(), data.getRenderVersion());
|
||||
private static MetaData makeMetaData(ILodRenderSource data) {
|
||||
AbstractRenderSourceLoader loader = AbstractRenderSourceLoader.getLoader(data.getClass(), data.getRenderVersion());
|
||||
return new MetaData(data.getSectionPos(), -1, -1,
|
||||
data.getDataDetail(), loader == null ? 0 : loader.renderTypeId, data.getRenderVersion());
|
||||
}
|
||||
@@ -201,7 +201,7 @@ public class RenderMetaFile extends MetaFile
|
||||
return fin;
|
||||
}
|
||||
|
||||
public void save(LodRenderSource data, IDhClientLevel level) {
|
||||
public void save(ILodRenderSource data, IDhClientLevel level) {
|
||||
if (data.isEmpty()) {
|
||||
if (path.exists()) if (!path.delete()) LOGGER.warn("Failed to delete render file at {}", path);
|
||||
doesFileExist = false;
|
||||
|
||||
@@ -2,7 +2,7 @@ package com.seibel.lod.core.render;
|
||||
|
||||
import com.seibel.lod.core.level.IDhClientLevel;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
import com.seibel.lod.core.datatype.LodRenderSource;
|
||||
import com.seibel.lod.core.datatype.ILodRenderSource;
|
||||
import com.seibel.lod.core.file.renderfile.IRenderSourceProvider;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -16,8 +16,8 @@ public class LodRenderSection {
|
||||
public byte childCount = 0;
|
||||
|
||||
// TODO: Should I provide a way to change the render source?
|
||||
private LodRenderSource lodRenderSource;
|
||||
private CompletableFuture<LodRenderSource> loadFuture;
|
||||
private ILodRenderSource lodRenderSource;
|
||||
private CompletableFuture<ILodRenderSource> loadFuture;
|
||||
private boolean isRenderEnabled = false;
|
||||
private IRenderSourceProvider provider = null;
|
||||
|
||||
@@ -102,7 +102,7 @@ public class LodRenderSection {
|
||||
return lodRenderSource != null && !lodRenderSource.isValid();
|
||||
}
|
||||
|
||||
public LodRenderSource getRenderSource() {
|
||||
public ILodRenderSource getRenderSource() {
|
||||
return lodRenderSource;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,20 +1,16 @@
|
||||
package com.seibel.lod.core.render;
|
||||
|
||||
import com.seibel.lod.core.datatype.LodRenderSource;
|
||||
import com.seibel.lod.core.datatype.ILodRenderSource;
|
||||
import com.seibel.lod.core.enums.ELodDirection;
|
||||
import com.seibel.lod.core.pos.Pos2D;
|
||||
import com.seibel.lod.core.pos.DhSectionPos;
|
||||
import com.seibel.lod.core.render.renderer.LodRenderer;
|
||||
import com.seibel.lod.core.util.LodUtil;
|
||||
import com.seibel.lod.core.util.gridList.MovableGridRingList;
|
||||
import com.seibel.lod.core.util.math.Mat4f;
|
||||
import com.seibel.lod.core.util.math.Vec3f;
|
||||
import com.seibel.lod.core.util.objects.SortedArraySet;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Vector;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class RenderBufferHandler {
|
||||
@@ -136,7 +132,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);
|
||||
LodRenderSource container = section.getRenderSource();
|
||||
ILodRenderSource container = section.getRenderSource();
|
||||
|
||||
// Update self's render buffer state
|
||||
boolean shouldRender = section.canRender();
|
||||
|
||||
Reference in New Issue
Block a user