Add interface and abstract prefixes to a few datatype objects

This commit is contained in:
James Seibel
2022-09-29 22:38:23 -05:00
parent 58be4da5ca
commit 8b1cb258b4
23 changed files with 157 additions and 156 deletions
@@ -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;
}
@@ -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);
}
@@ -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();
@@ -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;
@@ -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);
@@ -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.
@@ -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();