diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/FullDataDownSampler.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/FullDataDownSampler.java index d6567933c..440e8c505 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/FullDataDownSampler.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/FullDataDownSampler.java @@ -1,7 +1,7 @@ package com.seibel.lod.core.dataObjects.fullData; import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView; -import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource; +import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource; import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; import com.seibel.lod.core.file.fullDatafile.IFullDataSourceProvider; import com.seibel.lod.core.pos.DhLodPos; @@ -17,23 +17,23 @@ public class FullDataDownSampler { private static final Logger LOGGER = DhLoggerBuilder.getLogger(); public static CompletableFuture createDownSamplingFuture(DhSectionPos newTarget, IFullDataSourceProvider provider) { // TODO: Make this future somehow run with lowest priority (to ensure ram usage stays low) - return createDownSamplingFuture(FullDataSource.createEmpty(newTarget), provider); + return createDownSamplingFuture(CompleteFullDataSource.createEmpty(newTarget), provider); } - public static CompletableFuture createDownSamplingFuture(FullDataSource target, IFullDataSourceProvider provider) { - int sectionSizeNeeded = 1 << target.getDataDetail(); + public static CompletableFuture createDownSamplingFuture(CompleteFullDataSource target, IFullDataSourceProvider provider) { + int sectionSizeNeeded = 1 << target.getDataDetailLevel(); ArrayList> futures; - DhLodPos basePos = target.getSectionPos().getSectionBBoxPos().getCornerLodPos(FullDataSource.SECTION_SIZE_OFFSET); - if (sectionSizeNeeded <= FullDataSource.SECTION_SIZE_OFFSET) { + DhLodPos basePos = target.getSectionPos().getSectionBBoxPos().getCornerLodPos(CompleteFullDataSource.SECTION_SIZE_OFFSET); + if (sectionSizeNeeded <= CompleteFullDataSource.SECTION_SIZE_OFFSET) { futures = new ArrayList<>(sectionSizeNeeded * sectionSizeNeeded); for (int ox = 0; ox < sectionSizeNeeded; ox++) { for (int oz = 0; oz < sectionSizeNeeded; oz++) { CompletableFuture future = provider.read(new DhSectionPos( - FullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox, basePos.z + oz)); + CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox, basePos.z + oz)); future = future.whenComplete((source, ex) -> { - if (ex == null && source != null && source instanceof FullDataSource) { - downSample(target, (FullDataSource) source); + if (ex == null && source != null && source instanceof CompleteFullDataSource) { + downSample(target, (CompleteFullDataSource) source); } else if (ex != null) { LOGGER.error("Error while down sampling", ex); } @@ -42,15 +42,15 @@ public class FullDataDownSampler { } } } else { - futures = new ArrayList<>(FullDataSource.SECTION_SIZE * FullDataSource.SECTION_SIZE); - int multiplier = sectionSizeNeeded / FullDataSource.SECTION_SIZE; - for (int ox = 0; ox < FullDataSource.SECTION_SIZE; ox++) { - for (int oz = 0; oz < FullDataSource.SECTION_SIZE; oz++) { + futures = new ArrayList<>(CompleteFullDataSource.SECTION_SIZE * CompleteFullDataSource.SECTION_SIZE); + int multiplier = sectionSizeNeeded / CompleteFullDataSource.SECTION_SIZE; + for (int ox = 0; ox < CompleteFullDataSource.SECTION_SIZE; ox++) { + for (int oz = 0; oz < CompleteFullDataSource.SECTION_SIZE; oz++) { CompletableFuture future = provider.read(new DhSectionPos( - FullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox * multiplier, basePos.z + oz * multiplier)); + CompleteFullDataSource.SECTION_SIZE_OFFSET, basePos.x + ox * multiplier, basePos.z + oz * multiplier)); future = future.whenComplete((source, ex) -> { - if (ex == null && source != null && source instanceof FullDataSource) { - downSample(target, (FullDataSource) source); + if (ex == null && source != null && source instanceof CompleteFullDataSource) { + downSample(target, (CompleteFullDataSource) source); } else if (ex != null) { LOGGER.error("Error while down sampling", ex); } @@ -62,41 +62,41 @@ public class FullDataDownSampler { return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).thenApply(v -> target); } - public static void downSample(FullDataSource target, FullDataSource source) { + public static void downSample(CompleteFullDataSource target, CompleteFullDataSource source) { LodUtil.assertTrue(target.getSectionPos().overlaps(source.getSectionPos())); - LodUtil.assertTrue(target.getDataDetail() > source.getDataDetail()); + LodUtil.assertTrue(target.getDataDetailLevel() > source.getDataDetailLevel()); - byte detailDiff = (byte) (target.getDataDetail() - source.getDataDetail()); + byte detailDiff = (byte) (target.getDataDetailLevel() - source.getDataDetailLevel()); DhSectionPos trgPos = target.getSectionPos(); DhSectionPos srcPos = source.getSectionPos(); - if (detailDiff >= FullDataSource.SECTION_SIZE_OFFSET) { + if (detailDiff >= CompleteFullDataSource.SECTION_SIZE_OFFSET) { // The source occupies only 1 datapoint in the target // FIXME: TEMP method for down-sampling: take only the corner column - int sourceSectionPerTargetData = 1 << (detailDiff - FullDataSource.SECTION_SIZE_OFFSET); + int sourceSectionPerTargetData = 1 << (detailDiff - CompleteFullDataSource.SECTION_SIZE_OFFSET); if (srcPos.sectionX % sourceSectionPerTargetData != 0 || srcPos.sectionZ % sourceSectionPerTargetData != 0) { return; } - DhLodPos trgOffset = trgPos.getCorner(target.getDataDetail()); - DhLodPos srcOffset = srcPos.getSectionBBoxPos().convertToDetailLevel(target.getDataDetail()); + DhLodPos trgOffset = trgPos.getCorner(target.getDataDetailLevel()); + DhLodPos srcOffset = srcPos.getSectionBBoxPos().convertToDetailLevel(target.getDataDetailLevel()); int offsetX = trgOffset.x - srcOffset.x; int offsetZ = trgOffset.z - srcOffset.z; - LodUtil.assertTrue(offsetX >= 0 && offsetX < FullDataSource.SECTION_SIZE - && offsetZ >= 0 && offsetZ < FullDataSource.SECTION_SIZE); + LodUtil.assertTrue(offsetX >= 0 && offsetX < CompleteFullDataSource.SECTION_SIZE + && offsetZ >= 0 && offsetZ < CompleteFullDataSource.SECTION_SIZE); target.markNotEmpty(); source.get(0,0).deepCopyTo(target.get(offsetX, offsetZ)); } else if (detailDiff > 0) { // The source occupies multiple data-points in the target int srcDataPerTrgData = 1 << detailDiff; - int overlappedTrgDataSize = FullDataSource.SECTION_SIZE / srcDataPerTrgData; + int overlappedTrgDataSize = CompleteFullDataSource.SECTION_SIZE / srcDataPerTrgData; - DhLodPos trgOffset = trgPos.getCorner(target.getDataDetail()); - DhLodPos srcOffset = srcPos.getSectionBBoxPos().getCornerLodPos(target.getDataDetail()); + DhLodPos trgOffset = trgPos.getCorner(target.getDataDetailLevel()); + DhLodPos srcOffset = srcPos.getSectionBBoxPos().getCornerLodPos(target.getDataDetailLevel()); int offsetX = trgOffset.x - srcOffset.x; int offsetZ = trgOffset.z - srcOffset.z; - LodUtil.assertTrue(offsetX >= 0 && offsetX < FullDataSource.SECTION_SIZE - && offsetZ >= 0 && offsetZ < FullDataSource.SECTION_SIZE); + LodUtil.assertTrue(offsetX >= 0 && offsetX < CompleteFullDataSource.SECTION_SIZE + && offsetZ >= 0 && offsetZ < CompleteFullDataSource.SECTION_SIZE); target.markNotEmpty(); for (int ox = 0; ox < overlappedTrgDataSize; ox++) { diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/ChunkSizedFullDataView.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/ChunkSizedFullDataView.java new file mode 100644 index 000000000..e94ce99e3 --- /dev/null +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/ChunkSizedFullDataView.java @@ -0,0 +1,52 @@ +package com.seibel.lod.core.dataObjects.fullData.accessor; + +import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap; +import com.seibel.lod.core.pos.DhChunkPos; +import com.seibel.lod.core.pos.DhLodPos; +import com.seibel.lod.core.util.LodUtil; + +/** + * Contains the Full Data for a single chunk. + */ +public class ChunkSizedFullDataView extends FullDataArrayView +{ + public final DhChunkPos pos; + // TODO replace this var with LodUtil.BLOCK_DETAIL_LEVEL + public final byte detailLevel = LodUtil.BLOCK_DETAIL_LEVEL; + + + + public ChunkSizedFullDataView(DhChunkPos pos) + { + super(new FullDataPointIdMap(), + new long[LodUtil.CHUNK_WIDTH * LodUtil.CHUNK_WIDTH][0], + LodUtil.CHUNK_WIDTH); + + this.pos = pos; + } + + + + public void setSingleColumn(long[] data, int x, int z) + { + dataArrays[x * LodUtil.CHUNK_WIDTH + z] = data; + } + + public long nonEmptyCount() + { + long count = 0; + for (long[] data : dataArrays) + { + if (data.length != 0) + { + count += 1; + } + } + return count; + } + + public long emptyCount() { return LodUtil.CHUNK_WIDTH * LodUtil.CHUNK_WIDTH - nonEmptyCount(); } + + public DhLodPos getLodPos() { return new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, pos.x, pos.z); } + +} \ No newline at end of file diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/FullArrayView.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/FullArrayView.java deleted file mode 100644 index 664352fa4..000000000 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/FullArrayView.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.seibel.lod.core.dataObjects.fullData.accessor; - -import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap; -import com.seibel.lod.core.util.FullDataPointUtil; -import com.seibel.lod.core.util.LodUtil; - -public class FullArrayView implements IFullDataView -{ - protected final long[][] dataArrays; - protected final int offset; - protected final int size; - protected final int dataSize; - protected final FullDataPointIdMap mapping; - - - - public FullArrayView(FullDataPointIdMap mapping, long[][] dataArrays, int size) - { - if (dataArrays.length != size * size) - { - throw new IllegalArgumentException("tried constructing dataArrayView with invalid input!"); - } - - this.dataArrays = dataArrays; - this.size = size; - this.dataSize = size; - this.mapping = mapping; - this.offset = 0; - } - - public FullArrayView(FullArrayView source, int size, int offsetX, int offsetZ) - { - if (source.size < size || source.size < size + offsetX || source.size < size + offsetZ) - { - throw new IllegalArgumentException("tried constructing dataArrayView subview with invalid input!"); - } - - this.dataArrays = source.dataArrays; - this.size = size; - this.dataSize = source.dataSize; - this.mapping = source.mapping; - this.offset = source.offset + offsetX * this.dataSize + offsetZ; - } - - - - @Override - public FullDataPointIdMap getMapping() { return this.mapping; } - - @Override - public SingleFullArrayView get(int index) { return this.get(index / this.size, index % this.size); } - - @Override - public SingleFullArrayView get(int x, int z) { return new SingleFullArrayView(this.mapping, this.dataArrays, x * this.size + z + this.offset); } - - @Override - public int width() { return this.size; } - - @Override - public FullArrayView subView(int size, int xOffset, int zOffset) { return new FullArrayView(this, size, xOffset, zOffset); } - - /** WARNING: This will potentially share the underlying array object! */ - public void shadowCopyTo(FullArrayView target) - { - if (target.size != this.size) - { - throw new IllegalArgumentException("Target view must have same size as this view"); - } - - if (target.mapping.equals(this.mapping)) - { - for (int x = 0; x < this.size; x++) - { - System.arraycopy(this.dataArrays, this.offset + x * this.dataSize, - target.dataArrays, target.offset + x * target.dataSize, this.size); - } - } - else - { - int[] remappedIds = target.mapping.mergeAndReturnRemappedEntityIds(this.mapping); - for (int x = 0; x < this.size; x++) - { - for (int o = 0; o < this.size; o++) - { - long[] sourceData = this.dataArrays[this.offset + x * this.dataSize + o]; - long[] newData = new long[sourceData.length]; - for (int i = 0; i < newData.length; i++) - { - newData[i] = FullDataPointUtil.remap(remappedIds, sourceData[i]); - } - - target.dataArrays[target.offset + x * target.dataSize + o] = newData; - } - } - } - } - - public void downsampleFrom(FullArrayView source) - { - LodUtil.assertTrue(source.size > this.size && source.size % this.size == 0); - int dataPerUnit = source.size / this.size; - for (int xOffset = 0; xOffset < this.size; xOffset++) - { - for (int zOffset = 0; zOffset < this.size; zOffset++) - { - SingleFullArrayView column = this.get(xOffset, zOffset); - column.downsampleFrom(source.subView(dataPerUnit, xOffset * dataPerUnit, zOffset * dataPerUnit)); - } - } - } - -} diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/FullDataArrayView.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/FullDataArrayView.java new file mode 100644 index 000000000..3ea709a35 --- /dev/null +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/FullDataArrayView.java @@ -0,0 +1,134 @@ +package com.seibel.lod.core.dataObjects.fullData.accessor; + +import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap; +import com.seibel.lod.core.util.FullDataPointUtil; +import com.seibel.lod.core.util.LodUtil; + +/** + * + */ +public class FullDataArrayView implements IFullDataView +{ + protected final FullDataPointIdMap mapping; + protected final long[][] dataArrays; + + /** measured in data points */ + protected final int width; + /** measured in data points */ + protected final int dataWidth; + + protected final int offset; + + + + //==============// + // constructors // + //==============// + + public FullDataArrayView(FullDataPointIdMap mapping, long[][] dataArrays, int width) + { + if (dataArrays.length != width * width) + { + throw new IllegalArgumentException("tried constructing dataArrayView with invalid input!"); + } + + this.dataArrays = dataArrays; + this.width = width; + this.dataWidth = width; + this.mapping = mapping; + this.offset = 0; + } + + public FullDataArrayView(FullDataArrayView source, int width, int offsetX, int offsetZ) + { + if (source.width < width || source.width < width + offsetX || source.width < width + offsetZ) + { + throw new IllegalArgumentException("tried constructing dataArrayView subview with invalid input!"); + } + + this.dataArrays = source.dataArrays; + this.width = width; + this.dataWidth = source.dataWidth; + this.mapping = source.mapping; + this.offset = source.offset + offsetX * this.dataWidth + offsetZ; + } + + + + //=========// + // methods // + //=========// + + @Override + public FullDataArrayView subView(int size, int xOffset, int zOffset) { return new FullDataArrayView(this, size, xOffset, zOffset); } + + /** WARNING: This will potentially share the underlying array object! */ + public void shadowCopyTo(FullDataArrayView target) + { + if (target.width != this.width) + { + throw new IllegalArgumentException("Target view must have same size as this view"); + } + + + if (target.mapping.equals(this.mapping)) + { + for (int x = 0; x < this.width; x++) + { + System.arraycopy(this.dataArrays, this.offset + x * this.dataWidth, + target.dataArrays, target.offset + x * target.dataWidth, this.width); + } + } + else + { + int[] remappedIds = target.mapping.mergeAndReturnRemappedEntityIds(this.mapping); + for (int x = 0; x < this.width; x++) + { + for (int z = 0; z < this.width; z++) + { + long[] sourceData = this.dataArrays[this.offset + x * this.dataWidth + z]; + long[] newData = new long[sourceData.length]; + for (int dataPointIndex = 0; dataPointIndex < newData.length; dataPointIndex++) + { + newData[dataPointIndex] = FullDataPointUtil.remap(remappedIds, sourceData[dataPointIndex]); + } + + target.dataArrays[target.offset + x * target.dataWidth + z] = newData; + } + } + } + } + + public void downsampleFrom(FullDataArrayView arrayView) + { + LodUtil.assertTrue(arrayView.width > this.width && arrayView.width % this.width == 0); + + int dataPerUnit = arrayView.width / this.width; + for (int xOffset = 0; xOffset < this.width; xOffset++) + { + for (int zOffset = 0; zOffset < this.width; zOffset++) + { + SingleFullArrayView column = this.get(xOffset, zOffset); + column.downsampleFrom(arrayView.subView(dataPerUnit, xOffset * dataPerUnit, zOffset * dataPerUnit)); + } + } + } + + + + //=========// + // getters // + //=========// + + @Override + public FullDataPointIdMap getMapping() { return this.mapping; } + + @Override + public SingleFullArrayView get(int index) { return this.get(index / this.width, index % this.width); } + @Override + public SingleFullArrayView get(int relativeX, int relativeZ) { return new SingleFullArrayView(this.mapping, this.dataArrays, relativeX * this.width + relativeZ + this.offset); } + + @Override + public int width() { return this.width; } + +} diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/IFullDataView.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/IFullDataView.java index ef2c57c6f..9befd8135 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/IFullDataView.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/IFullDataView.java @@ -9,11 +9,18 @@ public interface IFullDataView { FullDataPointIdMap getMapping(); + /** generally used for iterating through the whole data set */ SingleFullArrayView get(int index); - SingleFullArrayView get(int x, int z); + SingleFullArrayView get(int relativeX, int relativeZ); + /** measured in full data points */ int width(); + IFullDataView subView(int size, int xOffset, int zOffset); + + + + /** Returns an iterator that goes over each data column */ default Iterator iterator() { @@ -34,6 +41,4 @@ public interface IFullDataView }; } - IFullDataView subView(int size, int xOffset, int zOffset); - } diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/SingleFullArrayView.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/SingleFullArrayView.java index 0a7cb4096..f358878d0 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/SingleFullArrayView.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/accessor/SingleFullArrayView.java @@ -37,9 +37,9 @@ public class SingleFullArrayView implements IFullDataView } @Override - public SingleFullArrayView get(int x, int z) + public SingleFullArrayView get(int relativeX, int relativeZ) { - if (x != 0 || z != 0) + if (relativeX != 0 || relativeZ != 0) { throw new IllegalArgumentException("Only contains 1 column of full data!"); } diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/loader/FullDataLoader.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/loader/FullDataLoader.java index 637c61a26..37f13b5c3 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/loader/FullDataLoader.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/loader/FullDataLoader.java @@ -1,7 +1,7 @@ package com.seibel.lod.core.dataObjects.fullData.loader; import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource; +import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource; import com.seibel.lod.core.file.fullDatafile.FullDataMetaFile; import com.seibel.lod.core.level.IDhLevel; @@ -12,14 +12,14 @@ public class FullDataLoader extends AbstractFullDataSourceLoader { public FullDataLoader() { - super(FullDataSource.class, FullDataSource.TYPE_ID, new byte[]{FullDataSource.LATEST_VERSION}); + super(CompleteFullDataSource.class, CompleteFullDataSource.TYPE_ID, new byte[]{ CompleteFullDataSource.LATEST_VERSION}); } @Override public IFullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException { //TODO: Add decompressor here - return FullDataSource.loadData(dataFile, bufferedInputStream, level); + return CompleteFullDataSource.loadData(dataFile, bufferedInputStream, level); } } diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/loader/SingleChunkFullDataLoader.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/loader/SingleChunkFullDataLoader.java index c3c7d167c..f9c3e7559 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/loader/SingleChunkFullDataLoader.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/loader/SingleChunkFullDataLoader.java @@ -1,7 +1,7 @@ package com.seibel.lod.core.dataObjects.fullData.loader; import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.SingleChunkFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.sources.SpottyFullDataSource; import com.seibel.lod.core.file.fullDatafile.FullDataMetaFile; import com.seibel.lod.core.level.IDhLevel; @@ -11,12 +11,12 @@ import java.io.IOException; public class SingleChunkFullDataLoader extends AbstractFullDataSourceLoader { public SingleChunkFullDataLoader() { - super(SingleChunkFullDataSource.class, SingleChunkFullDataSource.TYPE_ID, new byte[]{ SingleChunkFullDataSource.LATEST_VERSION}); + super(SpottyFullDataSource.class, SpottyFullDataSource.TYPE_ID, new byte[]{ SpottyFullDataSource.LATEST_VERSION}); } @Override public IFullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException { - return SingleChunkFullDataSource.loadData(dataFile, bufferedInputStream, level); + return SpottyFullDataSource.loadData(dataFile, bufferedInputStream, level); } } diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/ChunkSizedFullDataSource.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/ChunkSizedFullDataSource.java deleted file mode 100644 index b42e6fa90..000000000 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/ChunkSizedFullDataSource.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.seibel.lod.core.dataObjects.fullData.sources; - -import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap; -import com.seibel.lod.core.dataObjects.fullData.accessor.FullArrayView; -import com.seibel.lod.core.pos.DhLodPos; - -public class ChunkSizedFullDataSource extends FullArrayView -{ - public final byte dataDetail; - public final int x; - public final int z; - - - - public ChunkSizedFullDataSource(byte dataDetail, int x, int z) - { - super(new FullDataPointIdMap(), new long[16 * 16][0], 16); - this.dataDetail = dataDetail; - this.x = x; - this.z = z; - } - - - - public void setSingleColumn(long[] data, int x, int z) - { - dataArrays[x * 16 + z] = data; - } - - public long nonEmptyCount() - { - long count = 0; - for (long[] data : dataArrays) - { - if (data.length != 0) - count += 1; - } - return count; - } - - public long emptyCount() { return 16 * 16 - nonEmptyCount(); } - - public DhLodPos getBBoxLodPos() { return new DhLodPos((byte) (dataDetail + 4), x, z); } - -} \ No newline at end of file diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/FullDataSource.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/CompleteFullDataSource.java similarity index 78% rename from core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/FullDataSource.java rename to core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/CompleteFullDataSource.java index 98e5b9cb6..ff326798e 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/FullDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/CompleteFullDataSource.java @@ -2,7 +2,8 @@ package com.seibel.lod.core.dataObjects.fullData.sources; import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenerationStep; import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap; -import com.seibel.lod.core.dataObjects.fullData.accessor.FullArrayView; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; +import com.seibel.lod.core.dataObjects.fullData.accessor.FullDataArrayView; import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView; import com.seibel.lod.core.level.IDhLevel; import com.seibel.lod.core.pos.DhBlockPos2D; @@ -19,13 +20,13 @@ import java.io.*; /** * */ -public class FullDataSource extends FullArrayView implements IFullDataSource +public class CompleteFullDataSource extends FullDataArrayView implements IFullDataSource { 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; public static final byte LATEST_VERSION = 0; - public static final long TYPE_ID = "FullDataSource".hashCode(); + public static final long TYPE_ID = "CompleteFullDataSource".hashCode(); private final DhSectionPos sectionPos; private boolean isEmpty = true; @@ -33,13 +34,13 @@ public class FullDataSource extends FullArrayView implements IFullDataSource // TODO why is this protected? - protected FullDataSource(DhSectionPos sectionPos) + protected CompleteFullDataSource(DhSectionPos sectionPos) { super(new FullDataPointIdMap(), new long[SECTION_SIZE*SECTION_SIZE][0], SECTION_SIZE); this.sectionPos = sectionPos; } - public FullDataSource(DhSectionPos pos, FullDataPointIdMap mapping, long[][] data) + public CompleteFullDataSource(DhSectionPos pos, FullDataPointIdMap mapping, long[][] data) { super(mapping, data, SECTION_SIZE); LodUtil.assertTrue(data.length == SECTION_SIZE * SECTION_SIZE); @@ -52,7 +53,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource @Override public DhSectionPos getSectionPos() { return this.sectionPos; } @Override - public byte getDataDetail() { return (byte) (this.sectionPos.sectionDetailLevel -SECTION_SIZE_OFFSET); } + public byte getDataDetailLevel() { return (byte) (this.sectionPos.sectionDetailLevel -SECTION_SIZE_OFFSET); } @Override public byte getDataVersion() { return LATEST_VERSION; } @@ -62,19 +63,19 @@ public class FullDataSource extends FullArrayView implements IFullDataSource public EDhApiWorldGenerationStep getWorldGenStep() { return EDhApiWorldGenerationStep.EMPTY; } @Override - public SingleFullArrayView tryGet(int x, int z) { return this.get(x, z); } + public SingleFullArrayView tryGet(int relativeX, int relativeZ) { return this.get(relativeX, relativeZ); } @Override - public void update(ChunkSizedFullDataSource data) + public void update(ChunkSizedFullDataView chunkDataView) { - LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(data.getBBoxLodPos())); - if (data.dataDetail == 0 && this.getDataDetail() == 0) + LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(chunkDataView.getLodPos())); + if (this.getDataDetailLevel() == 0) { - DhBlockPos2D chunkBlockPos = new DhBlockPos2D(data.x * 16, data.z * 16); + DhBlockPos2D chunkBlockPos = new DhBlockPos2D(chunkDataView.pos.x * 16, chunkDataView.pos.z * 16); DhBlockPos2D blockOffset = chunkBlockPos.subtract(this.sectionPos.getCorner().getCornerBlockPos()); LodUtil.assertTrue(blockOffset.x >= 0 && blockOffset.x < SECTION_SIZE && blockOffset.z >= 0 && blockOffset.z < SECTION_SIZE); this.isEmpty = false; - data.shadowCopyTo(this.subView(16, blockOffset.x, blockOffset.z)); + chunkDataView.shadowCopyTo(this.subView(16, blockOffset.x, blockOffset.z)); { // DEBUG ASSERTION for (int x = 0; x < 16; x++) { @@ -86,12 +87,12 @@ public class FullDataSource extends FullArrayView implements IFullDataSource } } } - else if (data.dataDetail == 0 && this.getDataDetail() < 4) + else if (this.getDataDetailLevel() < 4) { - int dataPerFull = 1 << this.getDataDetail(); + int dataPerFull = 1 << this.getDataDetailLevel(); int fullSize = 16 / dataPerFull; - DhLodPos dataOffset = data.getBBoxLodPos().getCornerLodPos(this.getDataDetail()); - DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetail()); + DhLodPos dataOffset = chunkDataView.getLodPos().getCornerLodPos(this.getDataDetailLevel()); + DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetailLevel()); int offsetX = dataOffset.x - baseOffset.x; int offsetZ = dataOffset.z - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE); @@ -101,26 +102,26 @@ public class FullDataSource extends FullArrayView implements IFullDataSource for (int oz = 0; oz < fullSize; oz++) { SingleFullArrayView column = this.get(ox + offsetX, oz + offsetZ); - column.downsampleFrom(data.subView(dataPerFull, ox * dataPerFull, oz * dataPerFull)); + column.downsampleFrom(chunkDataView.subView(dataPerFull, ox * dataPerFull, oz * dataPerFull)); } } } - else if (data.dataDetail == 0 && this.getDataDetail() >= 4) + else if (this.getDataDetailLevel() >= 4) { //FIXME: TEMPORARY - int chunkPerFull = 1 << (this.getDataDetail() - 4); - if (data.x % chunkPerFull != 0 || data.z % chunkPerFull != 0) + int chunkPerFull = 1 << (this.getDataDetailLevel() - 4); + if (chunkDataView.pos.x % chunkPerFull != 0 || chunkDataView.pos.z % chunkPerFull != 0) { return; } - DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetail()); - DhLodPos dataOffset = data.getBBoxLodPos().convertToDetailLevel(this.getDataDetail()); + DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetailLevel()); + DhLodPos dataOffset = chunkDataView.getLodPos().convertToDetailLevel(this.getDataDetailLevel()); int offsetX = dataOffset.x - baseOffset.x; int offsetZ = dataOffset.z - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE); this.isEmpty = false; - data.get(0, 0).deepCopyTo(this.get(offsetX, offsetZ)); + chunkDataView.get(0, 0).deepCopyTo(this.get(offsetX, offsetZ)); } else { @@ -136,7 +137,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource - public static FullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException + public static CompleteFullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException { DataInputStream dataInputStream = new DataInputStream(bufferedInputStream); // DO NOT CLOSE @@ -164,7 +165,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource if (end == IFullDataSource.NO_DATA_FLAG_BYTE) { // Section is empty - return new FullDataSource(dataFile.pos); + return new CompleteFullDataSource(dataFile.pos); } // Non-empty section if (end != IFullDataSource.DATA_GUARD_BYTE) @@ -211,7 +212,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource throw new IOException("invalid id mapping end guard"); } - return new FullDataSource(dataFile.pos, mapping, data); + return new CompleteFullDataSource(dataFile.pos, mapping, data); } @Override @@ -220,8 +221,8 @@ public class FullDataSource extends FullArrayView implements IFullDataSource DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream); // DO NOT CLOSE - dataOutputStream.writeInt(this.getDataDetail()); - dataOutputStream.writeInt(this.size); + dataOutputStream.writeInt(this.getDataDetailLevel()); + dataOutputStream.writeInt(this.width); dataOutputStream.writeInt(level.getMinY()); if (this.isEmpty) { @@ -231,9 +232,9 @@ public class FullDataSource extends FullArrayView implements IFullDataSource dataOutputStream.writeInt(0xFFFFFFFF); // Data array length - for (int x = 0; x < this.size; x++) + for (int x = 0; x < this.width; x++) { - for (int z = 0; z < this.size; z++) + for (int z = 0; z < this.width; z++) { dataOutputStream.writeInt(this.get(x, z).getSingleLength()); } @@ -241,9 +242,9 @@ public class FullDataSource extends FullArrayView implements IFullDataSource // Data array content (only on non-empty columns) dataOutputStream.writeInt(0xFFFFFFFF); - for (int x = 0; x < this.size; x++) + for (int x = 0; x < this.width; x++) { - for (int z = 0; z < this.size; z++) + for (int z = 0; z < this.width; z++) { SingleFullArrayView column = this.get(x, z); if (!column.doesItExist()) @@ -264,7 +265,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource } - public static FullDataSource createEmpty(DhSectionPos pos) { return new FullDataSource(pos); } + public static CompleteFullDataSource createEmpty(DhSectionPos pos) { return new CompleteFullDataSource(pos); } /** Returns whether data at the given posToWrite can effect the target region file at posToTest. */ public static boolean firstDataPosCanAffectSecond(DhSectionPos posToWrite, DhSectionPos posToTest) @@ -298,7 +299,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource } } - public void writeFromLower(FullDataSource subData) + public void writeFromLower(CompleteFullDataSource subData) { LodUtil.assertTrue(this.sectionPos.overlaps(subData.sectionPos)); LodUtil.assertTrue(subData.sectionPos.sectionDetailLevel < this.sectionPos.sectionDetailLevel); @@ -306,7 +307,7 @@ public class FullDataSource extends FullArrayView implements IFullDataSource return; DhSectionPos lowerSectPos = subData.sectionPos; byte detailDiff = (byte) (this.sectionPos.sectionDetailLevel - subData.sectionPos.sectionDetailLevel); - byte targetDataDetail = this.getDataDetail(); + byte targetDataDetail = this.getDataDetailLevel(); DhLodPos minDataPos = this.sectionPos.getCorner(targetDataDetail); if (detailDiff <= SECTION_SIZE_OFFSET) { diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IFullDataSource.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IFullDataSource.java index dde594749..76eff9dc9 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IFullDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IFullDataSource.java @@ -2,8 +2,8 @@ package com.seibel.lod.core.dataObjects.fullData.sources; import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenerationStep; import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; import com.seibel.lod.core.file.fullDatafile.FullDataMetaFile; import com.seibel.lod.core.level.IDhLevel; import com.seibel.lod.core.pos.DhSectionPos; @@ -13,7 +13,7 @@ import java.io.IOException; // TODO make into an abstract class so the read(stream) method can be used as a constructor // TODO validate how we know which file to use when (probably, TYPE_ID) -// TODO merge with FullArrayView and IFullDataView +// TODO merge with FullDataArrayView and IFullDataView public interface IFullDataSource { /** @@ -28,11 +28,11 @@ public interface IFullDataSource public abstract DhSectionPos getSectionPos(); - public abstract byte getDataDetail(); + public abstract byte getDataDetailLevel(); public abstract byte getDataVersion(); public abstract EDhApiWorldGenerationStep getWorldGenStep(); - public abstract void update(ChunkSizedFullDataSource data); + public abstract void update(ChunkSizedFullDataView data); public abstract boolean isEmpty(); @@ -69,7 +69,7 @@ public interface IFullDataSource * Attempts to get the data column for the given relative x and z position. * @return null if the data doesn't exist */ - public abstract SingleFullArrayView tryGet(int x, int z); + public abstract SingleFullArrayView tryGet(int relativeX, int relativeZ); public abstract FullDataPointIdMap getMapping(); diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IIncompleteFullDataSource.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IIncompleteFullDataSource.java index cc5954a11..9ce3af168 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IIncompleteFullDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/IIncompleteFullDataSource.java @@ -4,6 +4,11 @@ public interface IIncompleteFullDataSource extends IFullDataSource { void sampleFrom(IFullDataSource fullDataSource); - IFullDataSource trySelfPromote(); + /** + * Attempts to convert this {@link IIncompleteFullDataSource} into a {@link CompleteFullDataSource}. + * + * @return this if the promotion failed, a new {@link CompleteFullDataSource} if successful. + */ + IFullDataSource tryPromotingToCompleteDataSource(); } diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SparseFullDataSource.java b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SparseFullDataSource.java index 79cdc1493..bab5c5556 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SparseFullDataSource.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/fullData/sources/SparseFullDataSource.java @@ -2,7 +2,8 @@ package com.seibel.lod.core.dataObjects.fullData.sources; import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenerationStep; import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap; -import com.seibel.lod.core.dataObjects.fullData.accessor.FullArrayView; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; +import com.seibel.lod.core.dataObjects.fullData.accessor.FullDataArrayView; import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView; import com.seibel.lod.core.file.fullDatafile.FullDataMetaFile; import com.seibel.lod.core.level.IDhLevel; @@ -18,7 +19,7 @@ import java.util.BitSet; /** * Handles full data with the detail level {@link SparseFullDataSource#SPARSE_UNIT_DETAIL}. - * In other words, this is the middle ground between {@link SingleChunkFullDataSource} and {@link FullDataSource} + * In other words, this is the middle ground between {@link SpottyFullDataSource} and {@link CompleteFullDataSource} */ public class SparseFullDataSource implements IIncompleteFullDataSource { @@ -42,7 +43,7 @@ public class SparseFullDataSource implements IIncompleteFullDataSource protected final FullDataPointIdMap mapping; private final DhSectionPos sectionPos; - private final FullArrayView[] sparseData; + private final FullDataArrayView[] sparseData; private final DhLodPos chunkPos; public final int chunks; @@ -63,12 +64,12 @@ public class SparseFullDataSource implements IIncompleteFullDataSource this.sectionPos = sectionPos; this.chunks = 1 << (byte) (sectionPos.sectionDetailLevel - SPARSE_UNIT_DETAIL); this.dataPerChunk = SECTION_SIZE / this.chunks; - this.sparseData = new FullArrayView[this.chunks * this.chunks]; + this.sparseData = new FullDataArrayView[this.chunks * this.chunks]; this.chunkPos = sectionPos.getCorner(SPARSE_UNIT_DETAIL); this.mapping = new FullDataPointIdMap(); } - protected SparseFullDataSource(DhSectionPos sectionPos, FullDataPointIdMap mapping, FullArrayView[] data) + protected SparseFullDataSource(DhSectionPos sectionPos, FullDataPointIdMap mapping, FullDataArrayView[] data) { LodUtil.assertTrue(sectionPos.sectionDetailLevel > SPARSE_UNIT_DETAIL); LodUtil.assertTrue(sectionPos.sectionDetailLevel <= MAX_SECTION_DETAIL); @@ -91,7 +92,7 @@ public class SparseFullDataSource implements IIncompleteFullDataSource @Override public DhSectionPos getSectionPos() { return this.sectionPos; } @Override - public byte getDataDetail() { return (byte) (this.sectionPos.sectionDetailLevel -SECTION_SIZE_OFFSET); } + public byte getDataDetailLevel() { return (byte) (this.sectionPos.sectionDetailLevel - SECTION_SIZE_OFFSET); } @Override public byte getDataVersion() { return LATEST_VERSION; } @@ -113,19 +114,13 @@ public class SparseFullDataSource implements IIncompleteFullDataSource @Override - public void update(ChunkSizedFullDataSource data) + public void update(ChunkSizedFullDataView chunkDataView) { - if (data.dataDetail != 0) + int arrayOffset = this.calculateOffset(chunkDataView.pos.x, chunkDataView.pos.z); + FullDataArrayView newArray = new FullDataArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); + if (this.getDataDetailLevel() == chunkDataView.detailLevel) { - //TODO: Disable the throw and instead just ignore the data. - throw new IllegalArgumentException("SparseFullDataSource only supports dataDetail 0!"); - } - - int arrayOffset = this.calculateOffset(data.x, data.z); - FullArrayView newArray = new FullArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); - if (this.getDataDetail() == data.dataDetail) - { - data.shadowCopyTo(newArray); + chunkDataView.shadowCopyTo(newArray); } else { @@ -137,10 +132,11 @@ public class SparseFullDataSource implements IIncompleteFullDataSource for (int zOffset = 0; zOffset < count; zOffset++) { SingleFullArrayView column = newArray.get(xOffset, zOffset); - column.downsampleFrom(data.subView(dataPerCount, xOffset * dataPerCount, zOffset * dataPerCount)); + column.downsampleFrom(chunkDataView.subView(dataPerCount, xOffset * dataPerCount, zOffset * dataPerCount)); } } } + this.isEmpty = false; this.sparseData[arrayOffset] = newArray; } @@ -165,9 +161,9 @@ public class SparseFullDataSource implements IIncompleteFullDataSource { this.sampleFrom((SparseFullDataSource) source); } - else if (source instanceof FullDataSource) + else if (source instanceof CompleteFullDataSource) { - this.sampleFrom((FullDataSource) source); + this.sampleFrom((CompleteFullDataSource) source); } else { @@ -190,17 +186,17 @@ public class SparseFullDataSource implements IIncompleteFullDataSource { for (int zOffset = 0; zOffset < sparseSource.chunks; zOffset++) { - FullArrayView sourceChunk = sparseSource.sparseData[xOffset * sparseSource.chunks + zOffset]; + FullDataArrayView sourceChunk = sparseSource.sparseData[xOffset * sparseSource.chunks + zOffset]; if (sourceChunk != null) { - FullArrayView buff = new FullArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); + FullDataArrayView buff = new FullDataArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); buff.downsampleFrom(sourceChunk); this.sparseData[(xOffset + offsetX) * this.chunks + (zOffset + offsetZ)] = buff; } } } } - private void sampleFrom(FullDataSource fullSource) + private void sampleFrom(CompleteFullDataSource fullSource) { DhSectionPos pos = fullSource.getSectionPos(); this.isEmpty = false; @@ -208,8 +204,8 @@ public class SparseFullDataSource implements IIncompleteFullDataSource DhLodPos basePos = this.sectionPos.getCorner(SPARSE_UNIT_DETAIL); DhLodPos dataPos = pos.getCorner(SPARSE_UNIT_DETAIL); int coveredChunks = pos.getWidth(SPARSE_UNIT_DETAIL).numberOfLodSectionsWide; - int sourceDataPerChunk = SPARSE_UNIT_SIZE >>> fullSource.getDataDetail(); - LodUtil.assertTrue(coveredChunks*sourceDataPerChunk == FullDataSource.SECTION_SIZE); + int sourceDataPerChunk = SPARSE_UNIT_SIZE >>> fullSource.getDataDetailLevel(); + LodUtil.assertTrue(coveredChunks*sourceDataPerChunk == CompleteFullDataSource.SECTION_SIZE); int offsetX = dataPos.x-basePos.x; int offsetZ = dataPos.z-basePos.z; LodUtil.assertTrue(offsetX >=0 && offsetX < this.chunks && offsetZ >=0 && offsetZ < this.chunks); @@ -218,8 +214,8 @@ public class SparseFullDataSource implements IIncompleteFullDataSource { for (int zOffset = 0; zOffset < coveredChunks; zOffset++) { - FullArrayView sourceChunk = fullSource.subView(sourceDataPerChunk, xOffset * sourceDataPerChunk, zOffset * sourceDataPerChunk); - FullArrayView buff = new FullArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); + FullDataArrayView sourceChunk = fullSource.subView(sourceDataPerChunk, xOffset * sourceDataPerChunk, zOffset * sourceDataPerChunk); + FullDataArrayView buff = new FullDataArrayView(this.mapping, new long[this.dataPerChunk * this.dataPerChunk][], this.dataPerChunk); buff.downsampleFrom(sourceChunk); this.sparseData[(xOffset + offsetX) * this.chunks + (zOffset + offsetZ)] = buff; } @@ -238,7 +234,7 @@ public class SparseFullDataSource implements IIncompleteFullDataSource DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream); - dataOutputStream.writeShort(this.getDataDetail()); + dataOutputStream.writeShort(this.getDataDetailLevel()); dataOutputStream.writeShort(SPARSE_UNIT_DETAIL); dataOutputStream.writeInt(SECTION_SIZE); dataOutputStream.writeInt(level.getMinY()); @@ -266,7 +262,7 @@ public class SparseFullDataSource implements IIncompleteFullDataSource i = dataArrayIndexHasData.nextSetBit(i+1)) { // column data length - FullArrayView array = this.sparseData[i]; + FullDataArrayView array = this.sparseData[i]; LodUtil.assertTrue(array != null); for (int x = 0; x < array.width(); x++) { @@ -451,12 +447,12 @@ public class SparseFullDataSource implements IIncompleteFullDataSource throw new IOException("invalid id mapping end guard"); } - FullArrayView[] fullDataArrays = new FullArrayView[chunks * chunks]; + FullDataArrayView[] fullDataArrays = new FullDataArrayView[chunks * chunks]; for (int i = 0; i < rawFullDataArrays.length; i++) { if (rawFullDataArrays[i] != null) { - fullDataArrays[i] = new FullArrayView(mapping, rawFullDataArrays[i], dataPointsPerChunk); + fullDataArrays[i] = new FullDataArrayView(mapping, rawFullDataArrays[i], dataPointsPerChunk); } } @@ -466,53 +462,58 @@ public class SparseFullDataSource implements IIncompleteFullDataSource - private void applyToFullDataSource(FullDataSource dataSource) + private void applyToFullDataSource(CompleteFullDataSource dataSource) { LodUtil.assertTrue(dataSource.getSectionPos().equals(this.sectionPos)); - LodUtil.assertTrue(dataSource.getDataDetail() == this.getDataDetail()); + LodUtil.assertTrue(dataSource.getDataDetailLevel() == this.getDataDetailLevel()); for (int x = 0; x < this.chunks; x++) { for (int z = 0; z < this.chunks; z++) { - FullArrayView array = this.sparseData[x * this.chunks + z]; + FullDataArrayView array = this.sparseData[x * this.chunks + z]; if (array == null) continue; // Otherwise, apply data to dataSource dataSource.markNotEmpty(); - FullArrayView view = dataSource.subView(this.dataPerChunk, x * this.dataPerChunk, z * this.dataPerChunk); + FullDataArrayView view = dataSource.subView(this.dataPerChunk, x * this.dataPerChunk, z * this.dataPerChunk); array.shadowCopyTo(view); } } } - public IFullDataSource trySelfPromote() + public IFullDataSource tryPromotingToCompleteDataSource() { if (this.isEmpty) { return this; } - for (FullArrayView array : this.sparseData) + // promotion can only succeed if every data column is present + for (FullDataArrayView array : this.sparseData) { - if (array == null) return this; - } - FullDataSource newSource = FullDataSource.createEmpty(this.sectionPos); - this.applyToFullDataSource(newSource); - return newSource; + if (array == null) + { + return this; + } + } + + CompleteFullDataSource fullDataSource = CompleteFullDataSource.createEmpty(this.sectionPos); + this.applyToFullDataSource(fullDataSource); + return fullDataSource; } - public SingleFullArrayView tryGet(int x, int z) + public SingleFullArrayView tryGet(int relativeX, int relativeZ) { - LodUtil.assertTrue(x>=0 && x=0 && z=0 && relativeX =0 && relativeZ SparseFullDataSource.MAX_SECTION_DETAIL); @@ -48,7 +50,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl this.worldGenStep = EDhApiWorldGenerationStep.EMPTY; } - private SingleChunkFullDataSource(DhSectionPos pos, FullDataPointIdMap mapping, EDhApiWorldGenerationStep worldGenStep, BitSet isColumnNotEmpty, long[][] data) + private SpottyFullDataSource(DhSectionPos pos, FullDataPointIdMap mapping, EDhApiWorldGenerationStep worldGenStep, BitSet isColumnNotEmpty, long[][] data) { super(mapping, data, SECTION_SIZE); LodUtil.assertTrue(data.length == SECTION_SIZE*SECTION_SIZE); @@ -59,7 +61,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl this.isEmpty = false; } - public static SingleChunkFullDataSource createEmpty(DhSectionPos pos) { return new SingleChunkFullDataSource(pos); } + public static SpottyFullDataSource createEmpty(DhSectionPos pos) { return new SpottyFullDataSource(pos); } @@ -67,7 +69,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl // file handling // //===============// - public static SingleChunkFullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException + public static SpottyFullDataSource loadData(FullDataMetaFile dataFile, BufferedInputStream bufferedInputStream, IDhLevel level) throws IOException, InterruptedException { DataInputStream dataInputStream = new DataInputStream(bufferedInputStream); // DO NOT CLOSE @@ -91,7 +93,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl if (end == IFullDataSource.NO_DATA_FLAG_BYTE) { // Section is empty - return new SingleChunkFullDataSource(dataFile.pos); + return new SpottyFullDataSource(dataFile.pos); } @@ -160,7 +162,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl - return new SingleChunkFullDataSource(dataFile.pos, mapping, worldGenStep, isColumnNotEmpty, data); + return new SpottyFullDataSource(dataFile.pos, mapping, worldGenStep, isColumnNotEmpty, data); } @Override @@ -169,8 +171,8 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream); // DO NOT CLOSE - dataOutputStream.writeInt(this.getDataDetail()); - dataOutputStream.writeInt(this.size); + dataOutputStream.writeInt(this.getDataDetailLevel()); + dataOutputStream.writeInt(this.width); dataOutputStream.writeInt(level.getMinY()); if (this.isEmpty) { @@ -216,18 +218,21 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl //===============// @Override - public void update(ChunkSizedFullDataSource data) + public void update(ChunkSizedFullDataView data) { - LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(data.getBBoxLodPos())); + LodUtil.assertTrue(this.sectionPos.getSectionBBoxPos().overlapsExactly(data.getLodPos())); - if (data.dataDetail == 0 && this.getDataDetail() >= 4) + if (this.getDataDetailLevel() >= 4) { //FIXME: TEMPORARY - int chunkPerFull = 1 << (this.getDataDetail() - 4); - if (data.x % chunkPerFull != 0 || data.z % chunkPerFull != 0) + int chunkPerFull = 1 << (this.getDataDetailLevel() - 4); + if (data.pos.x % chunkPerFull != 0 || data.pos.z % chunkPerFull != 0) + { return; - DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetail()); - DhLodPos dataOffset = data.getBBoxLodPos().convertToDetailLevel(this.getDataDetail()); + } + + DhLodPos baseOffset = this.sectionPos.getCorner(this.getDataDetailLevel()); + DhLodPos dataOffset = data.getLodPos().convertToDetailLevel(this.getDataDetailLevel()); int offsetX = dataOffset.x - baseOffset.x; int offsetZ = dataOffset.z - baseOffset.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE); @@ -255,9 +260,9 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl { this.sampleFrom((SparseFullDataSource) source); } - else if (source instanceof FullDataSource) + else if (source instanceof CompleteFullDataSource) { - this.sampleFrom((FullDataSource) source); + this.sampleFrom((CompleteFullDataSource) source); } else { @@ -270,15 +275,15 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl DhSectionPos pos = sparseSource.getSectionPos(); this.isEmpty = false; - if (this.getDataDetail() > this.sectionPos.sectionDetailLevel) + if (this.getDataDetailLevel() > this.sectionPos.sectionDetailLevel) { - DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail()); - DhLodPos dataPos = pos.getCorner(this.getDataDetail()); + DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetailLevel()); + DhLodPos dataPos = pos.getCorner(this.getDataDetailLevel()); int offsetX = dataPos.x - basePos.x; int offsetZ = dataPos.z - basePos.z; LodUtil.assertTrue(offsetX >= 0 && offsetX < SECTION_SIZE && offsetZ >= 0 && offsetZ < SECTION_SIZE); - int chunksPerData = 1 << (this.getDataDetail() - SparseFullDataSource.SPARSE_UNIT_DETAIL); - int dataSpan = this.sectionPos.getWidth(this.getDataDetail()).numberOfLodSectionsWide; + int chunksPerData = 1 << (this.getDataDetailLevel() - SparseFullDataSource.SPARSE_UNIT_DETAIL); + int dataSpan = this.sectionPos.getWidth(this.getDataDetailLevel()).numberOfLodSectionsWide; for (int xOffset = 0; xOffset < dataSpan; xOffset++) { @@ -302,8 +307,8 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl int lowerSectionsPerData = this.sectionPos.getWidth(dataPos.detailLevel).numberOfLodSectionsWide; if (dataPos.x % lowerSectionsPerData != 0 || dataPos.z % lowerSectionsPerData != 0) return; - DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail()); - dataPos = dataPos.convertToDetailLevel(this.getDataDetail()); + DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetailLevel()); + dataPos = dataPos.convertToDetailLevel(this.getDataDetailLevel()); int offsetX = dataPos.x - basePos.x; int offsetZ = dataPos.z - basePos.z; SingleFullArrayView column = sparseSource.tryGet(0, 0); @@ -314,19 +319,19 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl } } - private void sampleFrom(FullDataSource fullSource) + private void sampleFrom(CompleteFullDataSource fullSource) { DhSectionPos pos = fullSource.getSectionPos(); this.isEmpty = false; this.downsampleFrom(fullSource); - if (this.getDataDetail() > this.sectionPos.sectionDetailLevel) + if (this.getDataDetailLevel() > this.sectionPos.sectionDetailLevel) { - DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail()); - DhLodPos dataPos = pos.getCorner(this.getDataDetail()); + DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetailLevel()); + DhLodPos dataPos = pos.getCorner(this.getDataDetailLevel()); int offsetX = dataPos.x - basePos.x; int offsetZ = dataPos.z - basePos.z; - int dataSpan = this.sectionPos.getWidth(this.getDataDetail()).numberOfLodSectionsWide; + int dataSpan = this.sectionPos.getWidth(this.getDataDetailLevel()).numberOfLodSectionsWide; for (int xOffset = 0; xOffset < dataSpan; xOffset++) { @@ -345,8 +350,8 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl return; } - DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetail()); - dataPos = dataPos.convertToDetailLevel(this.getDataDetail()); + DhLodPos basePos = this.sectionPos.getCorner(this.getDataDetailLevel()); + dataPos = dataPos.convertToDetailLevel(this.getDataDetailLevel()); int offsetX = dataPos.x - basePos.x; int offsetZ = dataPos.z - basePos.z; this.isColumnNotEmpty.set(offsetX * SECTION_SIZE + offsetZ, true); @@ -355,19 +360,19 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl } @Override - public IFullDataSource trySelfPromote() + public IFullDataSource tryPromotingToCompleteDataSource() { + // promotion can only be completed if every column has data if (this.isEmpty) { return this; } - - if (this.isColumnNotEmpty.cardinality() != SECTION_SIZE * SECTION_SIZE) + else if (this.isColumnNotEmpty.cardinality() != SECTION_SIZE * SECTION_SIZE) { return this; } - return new FullDataSource(this.sectionPos, this.mapping, this.dataArrays); + return new CompleteFullDataSource(this.sectionPos, this.mapping, this.dataArrays); } @@ -377,7 +382,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl // @Override - public SingleFullArrayView tryGet(int x, int z) { return this.isColumnNotEmpty.get(x * SECTION_SIZE + z) ? this.get(x, z) : null; } + public SingleFullArrayView tryGet(int relativeX, int relativeZ) { return this.isColumnNotEmpty.get(relativeX * SECTION_SIZE + relativeZ) ? this.get(relativeX, relativeZ) : null; } @@ -388,7 +393,7 @@ public class SingleChunkFullDataSource extends FullArrayView implements IIncompl @Override public DhSectionPos getSectionPos() { return this.sectionPos; } @Override - public byte getDataDetail() { return (byte) (this.sectionPos.sectionDetailLevel -SECTION_SIZE_OFFSET); } + public byte getDataDetailLevel() { return (byte) (this.sectionPos.sectionDetailLevel -SECTION_SIZE_OFFSET); } @Override public byte getDataVersion() { return LATEST_VERSION; } diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/render/ColumnRenderLoader.java b/core/src/main/java/com/seibel/lod/core/dataObjects/render/ColumnRenderLoader.java index 01612f143..2a18fd600 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/render/ColumnRenderLoader.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/render/ColumnRenderLoader.java @@ -1,9 +1,9 @@ package com.seibel.lod.core.dataObjects.render; import com.seibel.lod.api.enums.worldGeneration.EDhApiWorldGenerationStep; +import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource; import com.seibel.lod.core.dataObjects.fullData.sources.IIncompleteFullDataSource; import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource; import com.seibel.lod.core.dataObjects.transformers.FullToColumnTransformer; import com.seibel.lod.core.level.IDhClientLevel; import com.seibel.lod.core.level.IDhLevel; @@ -58,16 +58,16 @@ public class ColumnRenderLoader } } - /** @throws InterruptedException see {@link FullToColumnTransformer#transformFullDataToColumnData(IDhClientLevel, FullDataSource) FullToColumnTransformer#transformFullDataToColumnData} for documentation */ - public ColumnRenderSource createRenderSource(IFullDataSource dataSource, IDhClientLevel level) throws InterruptedException + /** @throws InterruptedException see {@link FullToColumnTransformer#transformFullDataToColumnData(IDhClientLevel, CompleteFullDataSource) FullToColumnTransformer#transformFullDataToColumnData} for documentation */ + public ColumnRenderSource createRenderSource(IFullDataSource fullDataSource, IDhClientLevel level) throws InterruptedException { - if (dataSource instanceof FullDataSource) + if (fullDataSource instanceof CompleteFullDataSource) { - return FullToColumnTransformer.transformFullDataToColumnData(level, (FullDataSource) dataSource); + return FullToColumnTransformer.transformFullDataToColumnData(level, (CompleteFullDataSource) fullDataSource); } - else if (dataSource instanceof IIncompleteFullDataSource) + else if (fullDataSource instanceof IIncompleteFullDataSource) { - return FullToColumnTransformer.transformIncompleteDataToColumnData(level, (IIncompleteFullDataSource) dataSource); + return FullToColumnTransformer.transformIncompleteDataToColumnData(level, (IIncompleteFullDataSource) fullDataSource); } LodUtil.assertNotReach(); diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/render/ColumnRenderSource.java b/core/src/main/java/com/seibel/lod/core/dataObjects/render/ColumnRenderSource.java index a0c3de42f..a27cf7613 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/render/ColumnRenderSource.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/render/ColumnRenderSource.java @@ -6,7 +6,7 @@ import com.seibel.lod.core.dataObjects.render.columnViews.ColumnArrayView; import com.seibel.lod.core.dataObjects.render.columnViews.ColumnQuadView; import com.seibel.lod.core.dataObjects.render.columnViews.IColumnDataView; import com.seibel.lod.core.dataObjects.render.bufferBuilding.ColumnRenderBuffer; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.dataObjects.transformers.FullToColumnTransformer; import com.seibel.lod.core.level.IDhClientLevel; import com.seibel.lod.core.pos.DhSectionPos; @@ -296,7 +296,7 @@ public class ColumnRenderSource } } - public void fastWrite(ChunkSizedFullDataSource chunkData, IDhClientLevel level) + public void fastWrite(ChunkSizedFullDataView chunkData, IDhClientLevel level) { try { diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/ChunkToLodBuilder.java b/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/ChunkToLodBuilder.java index 34f76f242..928c1dfe7 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/ChunkToLodBuilder.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/ChunkToLodBuilder.java @@ -3,7 +3,7 @@ package com.seibel.lod.core.dataObjects.transformers; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.config.Config; import com.seibel.lod.core.logging.ConfigBasedLogger; import com.seibel.lod.core.pos.DhChunkPos; @@ -25,9 +25,9 @@ public class ChunkToLodBuilder private static class Task { final DhChunkPos chunkPos; - final CompletableFuture future; + final CompletableFuture future; - Task(DhChunkPos chunkPos, CompletableFuture future) + Task(DhChunkPos chunkPos, CompletableFuture future) { this.chunkPos = chunkPos; this.future = future; @@ -44,14 +44,14 @@ public class ChunkToLodBuilder - public CompletableFuture tryGenerateData(IChunkWrapper chunk) + public CompletableFuture tryGenerateData(IChunkWrapper chunkWrapper) { - if (chunk == null) + if (chunkWrapper == null) { throw new NullPointerException("ChunkWrapper cannot be null!"); } - IChunkWrapper oldChunk = this.latestChunkToBuild.put(chunk.getChunkPos(), chunk); // an Exchange operation + IChunkWrapper oldChunk = this.latestChunkToBuild.put(chunkWrapper.getChunkPos(), chunkWrapper); // an Exchange operation // If there's old chunk, that means we just replaced an unprocessed old request on generating data on this pos. // if so, we can just return null to signal this, as the old request's future will instead be the proper one // that will return the latest generated data. @@ -61,8 +61,8 @@ public class ChunkToLodBuilder } // Otherwise, it means we're the first to do so. Let's submit our task to this entry. - CompletableFuture future = new CompletableFuture<>(); - this.taskToBuild.addLast(new Task(chunk.getChunkPos(), future)); + CompletableFuture future = new CompletableFuture<>(); + this.taskToBuild.addLast(new Task(chunkWrapper.getChunkPos(), future)); return future; } @@ -135,7 +135,7 @@ public class ChunkToLodBuilder { if (LodDataBuilder.canGenerateLodFromChunk(latestChunk)) { - ChunkSizedFullDataSource data = LodDataBuilder.createChunkData(latestChunk); + ChunkSizedFullDataView data = LodDataBuilder.createChunkData(latestChunk); if (data != null) { task.future.complete(data); diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/FullToColumnTransformer.java b/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/FullToColumnTransformer.java index 809ac4a4b..3ca58a169 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/FullToColumnTransformer.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/FullToColumnTransformer.java @@ -1,14 +1,14 @@ package com.seibel.lod.core.dataObjects.transformers; import com.seibel.lod.core.dataObjects.fullData.FullDataPointIdMap; +import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource; import com.seibel.lod.core.dataObjects.fullData.sources.IIncompleteFullDataSource; import com.seibel.lod.core.util.RenderDataPointUtil; import com.seibel.lod.core.dataObjects.render.ColumnRenderSource; import com.seibel.lod.core.dataObjects.render.columnViews.ColumnArrayView; import com.seibel.lod.core.dataObjects.render.columnViews.ColumnQuadView; import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.level.IDhClientLevel; import com.seibel.lod.core.pos.DhSectionPos; import com.seibel.lod.core.config.Config; @@ -50,13 +50,13 @@ public class FullToColumnTransformer * @throws InterruptedException Can be caused by interrupting the thread upstream. * Generally thrown if the method is running after the client leaves the current world. */ - public static ColumnRenderSource transformFullDataToColumnData(IDhClientLevel level, FullDataSource data) throws InterruptedException + public static ColumnRenderSource transformFullDataToColumnData(IDhClientLevel level, CompleteFullDataSource fullDataSource) throws InterruptedException { - final DhSectionPos pos = data.getSectionPos(); - final byte dataDetail = data.getDataDetail(); - final int vertSize = Config.Client.Graphics.Quality.verticalQuality.get().calculateMaxVerticalData(data.getDataDetail()); + final DhSectionPos pos = fullDataSource.getSectionPos(); + final byte dataDetail = fullDataSource.getDataDetailLevel(); + final int vertSize = Config.Client.Graphics.Quality.verticalQuality.get().calculateMaxVerticalData(fullDataSource.getDataDetailLevel()); final ColumnRenderSource columnSource = new ColumnRenderSource(pos, vertSize, level.getMinY()); - if (data.isEmpty()) + if (fullDataSource.isEmpty()) { return columnSource; } @@ -75,7 +75,7 @@ public class FullToColumnTransformer throwIfThreadInterrupted(); ColumnArrayView columnArrayView = columnSource.getVerticalDataPointView(x, z); - SingleFullArrayView fullArrayView = data.get(x, z); + SingleFullArrayView fullArrayView = fullDataSource.get(x, z); convertColumnData(level, baseX + x, baseZ + z, columnArrayView, fullArrayView, 1); if (fullArrayView.doesItExist()) @@ -116,8 +116,8 @@ public class FullToColumnTransformer public static ColumnRenderSource transformIncompleteDataToColumnData(IDhClientLevel level, IIncompleteFullDataSource data) throws InterruptedException { final DhSectionPos pos = data.getSectionPos(); - final byte dataDetail = data.getDataDetail(); - final int vertSize = Config.Client.Graphics.Quality.verticalQuality.get().calculateMaxVerticalData(data.getDataDetail()); + final byte dataDetail = data.getDataDetailLevel(); + final int vertSize = Config.Client.Graphics.Quality.verticalQuality.get().calculateMaxVerticalData(data.getDataDetailLevel()); final ColumnRenderSource columnSource = new ColumnRenderSource(pos, vertSize, level.getMinY()); if (data.isEmpty()) { @@ -162,37 +162,33 @@ public class FullToColumnTransformer * @throws InterruptedException Can be caused by interrupting the thread upstream. * Generally thrown if the method is running after the client leaves the current world. */ - public static void writeFullDataChunkToColumnData(ColumnRenderSource render, IDhClientLevel level, ChunkSizedFullDataSource data) throws InterruptedException + public static void writeFullDataChunkToColumnData(ColumnRenderSource render, IDhClientLevel level, ChunkSizedFullDataView chunkDataView) throws InterruptedException { - if (data.dataDetail != 0) - { - throw new UnsupportedOperationException("To be implemented"); - } - final DhSectionPos pos = render.getSectionPos(); - final int renderOffsetX = (data.x * 16) - pos.getCorner().getCornerBlockPos().x; - final int renderOffsetZ = (data.z * 16) - pos.getCorner().getCornerBlockPos().z; + final int renderOffsetX = (chunkDataView.pos.x * LodUtil.CHUNK_WIDTH) - pos.getCorner().getCornerBlockPos().x; + final int renderOffsetZ = (chunkDataView.pos.z * LodUtil.CHUNK_WIDTH) - pos.getCorner().getCornerBlockPos().z; final int blockX = pos.getCorner().getCornerBlockPos().x; final int blockZ = pos.getCorner().getCornerBlockPos().z; final int perRenderWidth = 1 << render.getDataDetail(); - final int perDataWidth = 1 << data.dataDetail; + final int perDataWidth = 1 << chunkDataView.detailLevel; render.markNotEmpty(); - if (data.dataDetail == render.getDataDetail()) + + if (chunkDataView.detailLevel == render.getDataDetail()) { - if (renderOffsetX < 0 || renderOffsetX + 16 > render.getDataSize() || renderOffsetZ < 0 || renderOffsetZ + 16 > render.getDataSize()) + if (renderOffsetX < 0 || renderOffsetX + LodUtil.CHUNK_WIDTH > render.getDataSize() || renderOffsetZ < 0 || renderOffsetZ + LodUtil.CHUNK_WIDTH > render.getDataSize()) { throw new IllegalArgumentException("Data offset is out of bounds"); } - for (int x = 0; x < 16; x++) + for (int x = 0; x < LodUtil.CHUNK_WIDTH; x++) { - for (int z = 0; z < 16; z++) + for (int z = 0; z < LodUtil.CHUNK_WIDTH; z++) { throwIfThreadInterrupted(); ColumnArrayView columnArrayView = render.getVerticalDataPointView(renderOffsetX + x, renderOffsetZ + z); - SingleFullArrayView fullArrayView = data.get(x, z); + SingleFullArrayView fullArrayView = chunkDataView.get(x, z); convertColumnData(level, blockX + perRenderWidth * (renderOffsetX + x), blockZ + perRenderWidth * (renderOffsetZ + z), columnArrayView, fullArrayView, 2); @@ -203,12 +199,12 @@ public class FullToColumnTransformer } } } - render.fillDebugFlag(renderOffsetX, renderOffsetZ, 16, 16, ColumnRenderSource.DebugSourceFlag.DIRECT); + render.fillDebugFlag(renderOffsetX, renderOffsetZ, LodUtil.CHUNK_WIDTH, LodUtil.CHUNK_WIDTH, ColumnRenderSource.DebugSourceFlag.DIRECT); } else { - final int dataPerRender = 1 << (render.getDataDetail() - data.dataDetail); - final int dataSize = 16 / dataPerRender; + final int dataPerRender = 1 << (render.getDataDetail() - chunkDataView.detailLevel); + final int dataSize = LodUtil.CHUNK_WIDTH / dataPerRender; final int vertSize = render.getVerticalSize(); long[] tempRender = new long[dataPerRender * dataPerRender * vertSize]; if (renderOffsetX < 0 || renderOffsetX + dataSize > render.getDataSize() || renderOffsetZ < 0 || renderOffsetZ + dataSize > render.getDataSize()) @@ -230,7 +226,7 @@ public class FullToColumnTransformer ColumnArrayView columnArrayView = tempQuadView.get(ox, oz); - SingleFullArrayView fullArrayView = data.get(x * dataPerRender + ox, z * dataPerRender + oz); + SingleFullArrayView fullArrayView = chunkDataView.get(x * dataPerRender + ox, z * dataPerRender + oz); convertColumnData(level, blockX + perRenderWidth * (renderOffsetX + x) + perDataWidth * ox, blockZ + perRenderWidth * (renderOffsetZ + z) + perDataWidth * oz, columnArrayView, fullArrayView, 2); diff --git a/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/LodDataBuilder.java b/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/LodDataBuilder.java index 0b4649310..c67350e1e 100644 --- a/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/LodDataBuilder.java +++ b/core/src/main/java/com/seibel/lod/core/dataObjects/transformers/LodDataBuilder.java @@ -1,6 +1,6 @@ package com.seibel.lod.core.dataObjects.transformers; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.util.FullDataPointUtil; import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.util.LodUtil; @@ -12,29 +12,29 @@ import it.unimi.dsi.fastutil.longs.LongArrayList; public class LodDataBuilder { private static final IBlockStateWrapper AIR = SingletonInjector.INSTANCE.get(IWrapperFactory.class).getAirBlockStateWrapper(); - public static ChunkSizedFullDataSource createChunkData(IChunkWrapper chunk) { - if (!canGenerateLodFromChunk(chunk)) return null; + public static ChunkSizedFullDataView createChunkData(IChunkWrapper chunkWrapper) { + if (!canGenerateLodFromChunk(chunkWrapper)) return null; - ChunkSizedFullDataSource chunkData = new ChunkSizedFullDataSource((byte)0, chunk.getChunkPos().x, chunk.getChunkPos().z); + ChunkSizedFullDataView chunkData = new ChunkSizedFullDataView(chunkWrapper.getChunkPos()); for (int x=0; x<16; x++) { for (int z=0; z<16; z++) { - LongArrayList longs = new LongArrayList(chunk.getHeight()/4); - int lastY = chunk.getMaxBuildHeight(); - IBiomeWrapper biome = chunk.getBiome(x, lastY, z); + LongArrayList longs = new LongArrayList(chunkWrapper.getHeight()/4); + int lastY = chunkWrapper.getMaxBuildHeight(); + IBiomeWrapper biome = chunkWrapper.getBiome(x, lastY, z); IBlockStateWrapper blockState = AIR; int mappedId = chunkData.getMapping().addIfNotPresentAndGetId(biome, blockState); // FIXME: The +1 offset to reproduce the old behavior. Remove this when we get per-face lighting - byte light = (byte) ((chunk.getBlockLight(x,lastY+1,z) << 4) + chunk.getSkyLight(x,lastY+1,z)); - int y=chunk.getMaxY(x, z); + byte light = (byte) ((chunkWrapper.getBlockLight(x,lastY+1,z) << 4) + chunkWrapper.getSkyLight(x,lastY+1,z)); + int y=chunkWrapper.getMaxY(x, z); - for (; y>=chunk.getMinBuildHeight(); y--) { - IBiomeWrapper newBiome = chunk.getBiome(x, y, z); - IBlockStateWrapper newBlockState = chunk.getBlockState(x, y, z); - byte newLight = (byte) ((chunk.getBlockLight(x,y+1,z) << 4) + chunk.getSkyLight(x,y+1,z)); + for (; y>=chunkWrapper.getMinBuildHeight(); y--) { + IBiomeWrapper newBiome = chunkWrapper.getBiome(x, y, z); + IBlockStateWrapper newBlockState = chunkWrapper.getBlockState(x, y, z); + byte newLight = (byte) ((chunkWrapper.getBlockLight(x,y+1,z) << 4) + chunkWrapper.getSkyLight(x,y+1,z)); if (!newBiome.equals(biome) || !newBlockState.equals(blockState)) { - longs.add(FullDataPointUtil.encode(mappedId, lastY-y, y+1 - chunk.getMinBuildHeight(), light)); + longs.add(FullDataPointUtil.encode(mappedId, lastY-y, y+1 - chunkWrapper.getMinBuildHeight(), light)); biome = newBiome; blockState = newBlockState; mappedId = chunkData.getMapping().addIfNotPresentAndGetId(biome, blockState); @@ -47,7 +47,7 @@ public class LodDataBuilder { // lastY = y; // } } - longs.add(FullDataPointUtil.encode(mappedId, lastY-y, y+1 - chunk.getMinBuildHeight(), light)); + longs.add(FullDataPointUtil.encode(mappedId, lastY-y, y+1 - chunkWrapper.getMinBuildHeight(), light)); chunkData.setSingleColumn(longs.toArray(new long[0]), x, z); } diff --git a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java index e760f82ba..a5e432617 100644 --- a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java +++ b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataFileHandler.java @@ -1,12 +1,9 @@ package com.seibel.lod.core.file.fullDatafile; import com.google.common.collect.HashMultimap; -import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.IIncompleteFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.SingleChunkFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.SparseFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; +import com.seibel.lod.core.dataObjects.fullData.sources.*; +import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource; import com.seibel.lod.core.util.FileUtil; import com.seibel.lod.core.file.metaData.BaseMetaData; import com.seibel.lod.core.level.IDhLevel; @@ -37,7 +34,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider final IDhLevel level; final File saveDir; AtomicInteger topDetailLevel = new AtomicInteger(-1); - final int minDetailLevel = FullDataSource.SECTION_SIZE_OFFSET; + final int minDetailLevel = CompleteFullDataSource.SECTION_SIZE_OFFSET; @@ -185,7 +182,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider //TODO: The following check is temporary as we only sample corner points, which means // on a very different level, we may not need the entire section at all. - if (!FullDataSource.firstDataPosCanAffectSecond(basePos, subPos)) + if (!CompleteFullDataSource.firstDataPosCanAffectSecond(basePos, subPos)) { continue; } @@ -217,7 +214,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider private void recursiveGetDataFilesForPosition(int childIndex, DhSectionPos basePos, DhSectionPos pos, ArrayList preexistingFiles, ArrayList missingFilePositions) { DhSectionPos childPos = pos.getChildByIndex(childIndex); - if (FullDataSource.firstDataPosCanAffectSecond(basePos, childPos)) + if (CompleteFullDataSource.firstDataPosCanAffectSecond(basePos, childPos)) { FullDataMetaFile metaFile = this.files.get(childPos); if (metaFile != null) @@ -276,15 +273,15 @@ public class FullDataFileHandler implements IFullDataSourceProvider /** This call is concurrent. I.e. it supports being called by multiple threads at the same time. */ @Override - public void write(DhSectionPos sectionPos, ChunkSizedFullDataSource chunkData) + public void write(DhSectionPos sectionPos, ChunkSizedFullDataView chunkDataView) { - DhLodPos chunkPos = new DhLodPos((byte) (chunkData.dataDetail+4), chunkData.x, chunkData.z); + DhLodPos chunkPos = chunkDataView.getLodPos(); LodUtil.assertTrue(chunkPos.overlapsExactly(sectionPos.getSectionBBoxPos()), "Chunk "+chunkPos+" does not overlap section "+sectionPos); chunkPos = chunkPos.convertToDetailLevel((byte) this.minDetailLevel); - this.writeChunkDataToMetaFile(new DhSectionPos(chunkPos.detailLevel, chunkPos.x, chunkPos.z), chunkData); + this.writeChunkDataToMetaFile(new DhSectionPos(chunkPos.detailLevel, chunkPos.x, chunkPos.z), chunkDataView); } - private void writeChunkDataToMetaFile(DhSectionPos sectionPos, ChunkSizedFullDataSource chunkData) + private void writeChunkDataToMetaFile(DhSectionPos sectionPos, ChunkSizedFullDataView chunkData) { FullDataMetaFile metaFile = this.files.get(sectionPos); if (metaFile != null) @@ -346,7 +343,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider { // None exist. IIncompleteFullDataSource incompleteDataSource = pos.sectionDetailLevel <= SparseFullDataSource.MAX_SECTION_DETAIL ? - SparseFullDataSource.createEmpty(pos) : SingleChunkFullDataSource.createEmpty(pos); + SparseFullDataSource.createEmpty(pos) : SpottyFullDataSource.createEmpty(pos); return CompletableFuture.completedFuture(incompleteDataSource); } else @@ -362,7 +359,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider final ArrayList> futures = new ArrayList<>(existFiles.size()); final IIncompleteFullDataSource dataSource = pos.sectionDetailLevel <= SparseFullDataSource.MAX_SECTION_DETAIL ? SparseFullDataSource.createEmpty(pos) : - SingleChunkFullDataSource.createEmpty(pos); + SpottyFullDataSource.createEmpty(pos); for (FullDataMetaFile metaFile : existFiles) { @@ -383,7 +380,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider ); } return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])) - .thenApply((v) -> dataSource.trySelfPromote()); + .thenApply((v) -> dataSource.tryPromotingToCompleteDataSource()); } } @@ -410,7 +407,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider if (source instanceof IIncompleteFullDataSource) { - IFullDataSource newSource = ((IIncompleteFullDataSource) source).trySelfPromote(); + IFullDataSource newSource = ((IIncompleteFullDataSource) source).tryPromotingToCompleteDataSource(); changed |= newSource != source; source = newSource; } @@ -437,7 +434,7 @@ public class FullDataFileHandler implements IFullDataSourceProvider if (sourceLocal instanceof IIncompleteFullDataSource) { - IFullDataSource newSource = ((IIncompleteFullDataSource) sourceLocal).trySelfPromote(); + IFullDataSource newSource = ((IIncompleteFullDataSource) sourceLocal).tryPromotingToCompleteDataSource(); changed |= newSource != sourceLocal; sourceLocal = newSource; } diff --git a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataMetaFile.java b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataMetaFile.java index de987226f..82ce04e5f 100644 --- a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataMetaFile.java +++ b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/FullDataMetaFile.java @@ -11,7 +11,7 @@ import java.util.concurrent.locks.ReentrantReadWriteLock; import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; import com.seibel.lod.core.dataObjects.fullData.loader.AbstractFullDataSourceLoader; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.file.metaData.BaseMetaData; import com.seibel.lod.core.pos.DhLodPos; @@ -47,7 +47,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile //TODO: use ConcurrentAppendSingleSwapContainer instead of below: private static class GuardedMultiAppendQueue { ReentrantReadWriteLock appendLock = new ReentrantReadWriteLock(); - ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>(); + ConcurrentLinkedQueue queue = new ConcurrentLinkedQueue<>(); } // ===Concurrent Write stuff=== @@ -146,11 +146,11 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile // } // } - public void addToWriteQueue(ChunkSizedFullDataSource chunkDataSource) + public void addToWriteQueue(ChunkSizedFullDataView chunkDataSource) { debugCheck(); - DhLodPos chunkPos = new DhLodPos((byte) (chunkDataSource.dataDetail + 4), chunkDataSource.x, chunkDataSource.z); - LodUtil.assertTrue(pos.getSectionBBoxPos().overlapsExactly(chunkPos), "Chunk pos "+chunkPos+" doesn't overlap with section "+pos); + DhLodPos chunkLodPos = new DhLodPos(LodUtil.CHUNK_DETAIL_LEVEL, chunkDataSource.pos.x, chunkDataSource.pos.z); + LodUtil.assertTrue(pos.getSectionBBoxPos().overlapsExactly(chunkLodPos), "Chunk pos "+chunkLodPos+" doesn't overlap with section "+pos); //LOGGER.info("Write Chunk {} to file {}", chunkPos, pos); GuardedMultiAppendQueue writeQueue = this.writeQueue.get(); @@ -293,7 +293,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile private static BaseMetaData makeMetaData(IFullDataSource data) { AbstractFullDataSourceLoader loader = AbstractFullDataSourceLoader.getLoader(data.getClass(), data.getDataVersion()); return new BaseMetaData(data.getSectionPos(), -1, - data.getDataDetail(), data.getWorldGenStep(), (loader == null ? 0 : loader.datatypeId), data.getDataVersion()); + data.getDataDetailLevel(), data.getWorldGenStep(), (loader == null ? 0 : loader.datatypeId), data.getDataVersion()); } // "unchecked": Suppress casting of CompletableFuture to CompletableFuture @@ -398,7 +398,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile { // Write/Update data LodUtil.assertTrue(metaData != null); - metaData.dataLevel = fullDataSource.getDataDetail(); + metaData.dataLevel = fullDataSource.getDataDetailLevel(); fullDataSourceLoader = AbstractFullDataSourceLoader.getLoader(fullDataSource.getClass(), fullDataSource.getDataVersion()); LodUtil.assertTrue(fullDataSourceLoader != null, "No loader for "+fullDataSource.getClass()+" (v"+fullDataSource.getDataVersion()+")"); dataType = fullDataSource.getClass(); @@ -430,7 +430,7 @@ public class FullDataMetaFile extends AbstractMetaDataContainerFile { this.swapWriteQueue(); int count = this._backQueue.queue.size(); - for (ChunkSizedFullDataSource chunk : this._backQueue.queue) + for (ChunkSizedFullDataView chunk : this._backQueue.queue) { fullDataSource.update(chunk); } diff --git a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/GeneratedFullDataFileHandler.java b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/GeneratedFullDataFileHandler.java index c89c96033..d9de969f2 100644 --- a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/GeneratedFullDataFileHandler.java +++ b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/GeneratedFullDataFileHandler.java @@ -2,9 +2,9 @@ package com.seibel.lod.core.file.fullDatafile; import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; import com.seibel.lod.core.dataObjects.fullData.sources.IIncompleteFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.dataObjects.fullData.sources.SparseFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.SingleChunkFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.sources.SpottyFullDataSource; import com.seibel.lod.core.generation.tasks.IWorldGenTaskTracker; import com.seibel.lod.core.generation.WorldGenerationQueue; import com.seibel.lod.core.generation.tasks.WorldGenResult; @@ -92,7 +92,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler } else { - incompleteFullDataSource = SingleChunkFullDataSource.createEmpty(pos); + incompleteFullDataSource = SpottyFullDataSource.createEmpty(pos); } @@ -105,7 +105,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler { // queue this section to be generated GenTask genTask = new GenTask(pos, new WeakReference<>(incompleteFullDataSource)); - worldGenQueue.submitGenTask(incompleteFullDataSource.getSectionPos().getSectionBBoxPos(), incompleteFullDataSource.getDataDetail(), genTask) + worldGenQueue.submitGenTask(incompleteFullDataSource.getSectionPos().getSectionBBoxPos(), incompleteFullDataSource.getDataDetailLevel(), genTask) .whenComplete((genTaskResult, ex) -> this.onWorldGenTaskComplete(genTaskResult, ex, genTask, pos)); } @@ -146,7 +146,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler } return CompletableFuture.allOf(loadDataFutures.toArray(new CompletableFuture[0])) - .thenApply((voidValue) -> incompleteFullDataSource.trySelfPromote()); + .thenApply((voidValue) -> incompleteFullDataSource.tryPromotingToCompleteDataSource()); } } @@ -218,7 +218,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler public boolean isMemoryAddressValid() { return this.targetFullDataSourceRef.get() != null; } @Override - public Consumer getOnGenTaskCompleteConsumer() + public Consumer getOnGenTaskCompleteConsumer() { if (this.loadedTargetFullDataSource == null) { @@ -231,7 +231,7 @@ public class GeneratedFullDataFileHandler extends FullDataFileHandler return (chunkSizedFullDataSource) -> { - if (chunkSizedFullDataSource.getBBoxLodPos().overlapsExactly(this.loadedTargetFullDataSource.getSectionPos().getSectionBBoxPos())) + if (chunkSizedFullDataSource.getLodPos().overlapsExactly(this.loadedTargetFullDataSource.getSectionPos().getSectionBBoxPos())) { GeneratedFullDataFileHandler.this.write(this.loadedTargetFullDataSource.getSectionPos(), chunkSizedFullDataSource); } diff --git a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/IFullDataSourceProvider.java b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/IFullDataSourceProvider.java index c0a9e51c3..a9f1ce5d8 100644 --- a/core/src/main/java/com/seibel/lod/core/file/fullDatafile/IFullDataSourceProvider.java +++ b/core/src/main/java/com/seibel/lod/core/file/fullDatafile/IFullDataSourceProvider.java @@ -1,7 +1,7 @@ package com.seibel.lod.core.file.fullDatafile; import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.file.metaData.BaseMetaData; import com.seibel.lod.core.pos.DhSectionPos; @@ -17,7 +17,7 @@ public interface IFullDataSourceProvider extends AutoCloseable void addScannedFile(Collection detectedFiles); CompletableFuture read(DhSectionPos pos); - void write(DhSectionPos sectionPos, ChunkSizedFullDataSource chunkData); + void write(DhSectionPos sectionPos, ChunkSizedFullDataView chunkData); CompletableFuture flushAndSave(); //long getCacheVersion(DhSectionPos sectionPos); diff --git a/core/src/main/java/com/seibel/lod/core/file/renderfile/ILodRenderSourceProvider.java b/core/src/main/java/com/seibel/lod/core/file/renderfile/ILodRenderSourceProvider.java index 3124b173b..388eda4ab 100644 --- a/core/src/main/java/com/seibel/lod/core/file/renderfile/ILodRenderSourceProvider.java +++ b/core/src/main/java/com/seibel/lod/core/file/renderfile/ILodRenderSourceProvider.java @@ -1,7 +1,7 @@ package com.seibel.lod.core.file.renderfile; import com.seibel.lod.core.dataObjects.render.ColumnRenderSource; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.pos.DhSectionPos; import java.io.File; @@ -18,7 +18,7 @@ public interface ILodRenderSourceProvider extends AutoCloseable { CompletableFuture readAsync(DhSectionPos pos); void addScannedFile(Collection detectedFiles); - void writeChunkDataToFile(DhSectionPos sectionPos, ChunkSizedFullDataSource chunkData); + void writeChunkDataToFile(DhSectionPos sectionPos, ChunkSizedFullDataView chunkData); CompletableFuture flushAndSaveAsync(); /** Returns true if the data was refreshed, false otherwise */ diff --git a/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderMetaDataFile.java b/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderMetaDataFile.java index b94f9e0bf..e10a3a88f 100644 --- a/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderMetaDataFile.java +++ b/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderMetaDataFile.java @@ -2,7 +2,7 @@ package com.seibel.lod.core.file.renderfile; import com.seibel.lod.core.dataObjects.render.ColumnRenderLoader; import com.seibel.lod.core.dataObjects.render.ColumnRenderSource; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.file.metaData.BaseMetaData; import com.seibel.lod.core.level.IDhClientLevel; import com.seibel.lod.core.level.IDhLevel; @@ -77,9 +77,9 @@ public class RenderMetaDataFile extends AbstractMetaDataContainerFile // FIXME: This can cause concurrent modification of LodRenderSource. // Not sure if it will cause issues or not. - public void updateChunkIfNeeded(ChunkSizedFullDataSource chunkData, IDhClientLevel level) + public void updateChunkIfNeeded(ChunkSizedFullDataView chunkDataView, IDhClientLevel level) { - DhLodPos chunkPos = new DhLodPos((byte) (chunkData.dataDetail + 4), chunkData.x, chunkData.z); + DhLodPos chunkPos = chunkDataView.getLodPos(); LodUtil.assertTrue(this.pos.getSectionBBoxPos().overlapsExactly(chunkPos), "Chunk pos {} doesn't overlap with section {}", chunkPos, pos); CompletableFuture source = this._readCached(this.data.get()); @@ -88,7 +88,7 @@ public class RenderMetaDataFile extends AbstractMetaDataContainerFile return; } - source.thenAccept((renderSource) -> renderSource.fastWrite(chunkData, level)); + source.thenAccept((renderSource) -> renderSource.fastWrite(chunkDataView, level)); } public CompletableFuture flushAndSave(ExecutorService renderCacheThread) diff --git a/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderSourceFileHandler.java b/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderSourceFileHandler.java index c6841cbb0..bde58c5a1 100644 --- a/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderSourceFileHandler.java +++ b/core/src/main/java/com/seibel/lod/core/file/renderfile/RenderSourceFileHandler.java @@ -3,7 +3,7 @@ package com.seibel.lod.core.file.renderfile; import com.google.common.collect.HashMultimap; import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; import com.seibel.lod.core.dataObjects.render.ColumnRenderSource; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.dataObjects.transformers.DataRenderTransformer; import com.seibel.lod.core.file.fullDatafile.IFullDataSourceProvider; import com.seibel.lod.core.level.IDhClientLevel; @@ -214,14 +214,14 @@ public class RenderSourceFileHandler implements ILodRenderSourceProvider * TODO why is there fullData handling in the render file handler? */ @Override - public void writeChunkDataToFile(DhSectionPos sectionPos, ChunkSizedFullDataSource chunkData) + public void writeChunkDataToFile(DhSectionPos sectionPos, ChunkSizedFullDataView chunkDataView) { - this.writeChunkDataToFileRecursively(sectionPos,chunkData); - this.fullDataSourceProvider.write(sectionPos, chunkData); + this.writeChunkDataToFileRecursively(sectionPos,chunkDataView); + this.fullDataSourceProvider.write(sectionPos, chunkDataView); } - private void writeChunkDataToFileRecursively(DhSectionPos sectPos, ChunkSizedFullDataSource chunkData) + private void writeChunkDataToFileRecursively(DhSectionPos sectPos, ChunkSizedFullDataView chunkDataView) { - if (!sectPos.getSectionBBoxPos().overlapsExactly(new DhLodPos((byte) (4 + chunkData.dataDetail), chunkData.x, chunkData.z))) + if (!sectPos.getSectionBBoxPos().overlapsExactly(chunkDataView.getLodPos())) { return; } @@ -229,17 +229,17 @@ public class RenderSourceFileHandler implements ILodRenderSourceProvider if (sectPos.sectionDetailLevel > ColumnRenderSource.SECTION_SIZE_OFFSET) { - this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(0), chunkData); - this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(1), chunkData); - this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(2), chunkData); - this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(3), chunkData); + this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(0), chunkDataView); + this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(1), chunkDataView); + this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(2), chunkDataView); + this.writeChunkDataToFileRecursively(sectPos.getChildByIndex(3), chunkDataView); } RenderMetaDataFile metaFile = this.filesBySectionPos.get(sectPos); // Fast path: if there is a file for this section, just write to it. if (metaFile != null) { - metaFile.updateChunkIfNeeded(chunkData, this.level); + metaFile.updateChunkIfNeeded(chunkDataView, this.level); } } diff --git a/core/src/main/java/com/seibel/lod/core/file/subDimMatching/SubDimensionLevelMatcher.java b/core/src/main/java/com/seibel/lod/core/file/subDimMatching/SubDimensionLevelMatcher.java index d54c22b91..13850a3b6 100644 --- a/core/src/main/java/com/seibel/lod/core/file/subDimMatching/SubDimensionLevelMatcher.java +++ b/core/src/main/java/com/seibel/lod/core/file/subDimMatching/SubDimensionLevelMatcher.java @@ -2,7 +2,7 @@ package com.seibel.lod.core.file.subDimMatching; import com.seibel.lod.core.config.Config; import com.seibel.lod.core.dataObjects.fullData.sources.IFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.util.FullDataPointUtil; import com.seibel.lod.core.dataObjects.fullData.accessor.SingleFullArrayView; import com.seibel.lod.core.dataObjects.transformers.LodDataBuilder; @@ -165,20 +165,20 @@ public class SubDimensionLevelMatcher implements AutoCloseable LOGGER.info("Player block pos in dimension: [" + playerData.playerBlockPos.getX() + "," + playerData.playerBlockPos.getY() + "," + playerData.playerBlockPos.getZ() + "]"); // new chunk data - ChunkSizedFullDataSource newChunkSizedFullDataSource = LodDataBuilder.createChunkData(newlyLoadedChunk); + ChunkSizedFullDataView newChunkSizedFullDataView = LodDataBuilder.createChunkData(newlyLoadedChunk); long[][][] newChunkData = new long[LodUtil.CHUNK_WIDTH][LodUtil.CHUNK_WIDTH][]; - if (newChunkSizedFullDataSource != null) + if (newChunkSizedFullDataView != null) { for (int x = 0; x < LodUtil.CHUNK_WIDTH; x++) { for (int z = 0; z < LodUtil.CHUNK_WIDTH; z++) { - long[] array = newChunkSizedFullDataSource.get(x, z).getRaw(); + long[] array = newChunkSizedFullDataView.get(x, z).getRaw(); newChunkData[x][z] = array; } } } - boolean newChunkHasData = newChunkSizedFullDataSource != null && newChunkSizedFullDataSource.nonEmptyCount() != 0; + boolean newChunkHasData = newChunkSizedFullDataView != null && newChunkSizedFullDataView.nonEmptyCount() != 0; // check if the chunk is actually empty if (!newChunkHasData) diff --git a/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java b/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java index caabea413..3d6446fe8 100644 --- a/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java +++ b/core/src/main/java/com/seibel/lod/core/generation/WorldGenerationQueue.java @@ -3,7 +3,7 @@ package com.seibel.lod.core.generation; import com.seibel.lod.api.enums.worldGeneration.EDhApiDistantGeneratorMode; import com.seibel.lod.api.interfaces.override.worldGenerator.IDhApiWorldGenerator; import com.seibel.lod.core.config.Config; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.dataObjects.transformers.LodDataBuilder; import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.generation.tasks.*; @@ -345,7 +345,7 @@ public class WorldGenerationQueue implements Closeable LodUtil.assertTrue(taskDetailLevel >= this.minDataDetail && taskDetailLevel <= this.maxDataDetail); DhChunkPos chunkPosMin = new DhChunkPos(taskPos.getCornerBlockPos()); - LOGGER.info("Generating section "+taskPos+" with granularity "+granularity+" at "+chunkPosMin); + //LOGGER.info("Generating section "+taskPos+" with granularity "+granularity+" at "+chunkPosMin); this.numberOfTasksQueued++; inProgressTaskGroup.genFuture = startGenerationEvent(this.generator, chunkPosMin, granularity, taskDetailLevel, inProgressTaskGroup.group::onGenerationComplete); @@ -500,7 +500,7 @@ public class WorldGenerationQueue implements Closeable private static CompletableFuture startGenerationEvent(IDhApiWorldGenerator worldGenerator, DhChunkPos chunkPosMin, byte granularity, byte targetDataDetail, - Consumer generationCompleteConsumer) + Consumer generationCompleteConsumer) { EDhApiDistantGeneratorMode generatorMode = Config.Client.WorldGenerator.distantGeneratorMode.get(); return worldGenerator.generateChunks(chunkPosMin.x, chunkPosMin.z, granularity, targetDataDetail, generatorMode, (objectArray) -> diff --git a/core/src/main/java/com/seibel/lod/core/generation/tasks/IWorldGenTaskTracker.java b/core/src/main/java/com/seibel/lod/core/generation/tasks/IWorldGenTaskTracker.java index 09422e52d..cc93ab5b3 100644 --- a/core/src/main/java/com/seibel/lod/core/generation/tasks/IWorldGenTaskTracker.java +++ b/core/src/main/java/com/seibel/lod/core/generation/tasks/IWorldGenTaskTracker.java @@ -1,6 +1,6 @@ package com.seibel.lod.core.generation.tasks; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import java.util.function.Consumer; @@ -13,6 +13,6 @@ public interface IWorldGenTaskTracker /** Returns true if the task hasn't been garbage collected. */ boolean isMemoryAddressValid(); - Consumer getOnGenTaskCompleteConsumer(); + Consumer getOnGenTaskCompleteConsumer(); } diff --git a/core/src/main/java/com/seibel/lod/core/generation/tasks/SplitWorldGenTaskTracker.java b/core/src/main/java/com/seibel/lod/core/generation/tasks/SplitWorldGenTaskTracker.java index e3fb263b2..8da4a973f 100644 --- a/core/src/main/java/com/seibel/lod/core/generation/tasks/SplitWorldGenTaskTracker.java +++ b/core/src/main/java/com/seibel/lod/core/generation/tasks/SplitWorldGenTaskTracker.java @@ -1,6 +1,6 @@ package com.seibel.lod.core.generation.tasks; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import java.util.concurrent.CompletableFuture; import java.util.function.Consumer; @@ -52,6 +52,6 @@ public class SplitWorldGenTaskTracker implements IWorldGenTaskTracker public boolean isMemoryAddressValid() { return this.isValid; } @Override - public Consumer getOnGenTaskCompleteConsumer() { return this.parentTracker.getOnGenTaskCompleteConsumer(); } + public Consumer getOnGenTaskCompleteConsumer() { return this.parentTracker.getOnGenTaskCompleteConsumer(); } } diff --git a/core/src/main/java/com/seibel/lod/core/generation/tasks/WorldGenTaskGroup.java b/core/src/main/java/com/seibel/lod/core/generation/tasks/WorldGenTaskGroup.java index ca5187d63..9fc46e729 100644 --- a/core/src/main/java/com/seibel/lod/core/generation/tasks/WorldGenTaskGroup.java +++ b/core/src/main/java/com/seibel/lod/core/generation/tasks/WorldGenTaskGroup.java @@ -1,8 +1,7 @@ package com.seibel.lod.core.generation.tasks; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; import com.seibel.lod.core.pos.DhLodPos; -import com.seibel.lod.core.pos.DhSectionPos; import java.util.Iterator; import java.util.LinkedList; @@ -29,13 +28,13 @@ public final class WorldGenTaskGroup - public void onGenerationComplete(ChunkSizedFullDataSource chunkSizedFullDataSource) + public void onGenerationComplete(ChunkSizedFullDataView chunkSizedFullDataView) { Iterator tasks = this.worldGenTasks.iterator(); while (tasks.hasNext()) { WorldGenTask task = tasks.next(); - Consumer onGenTaskCompleteConsumer = task.taskTracker.getOnGenTaskCompleteConsumer(); + Consumer onGenTaskCompleteConsumer = task.taskTracker.getOnGenTaskCompleteConsumer(); if (onGenTaskCompleteConsumer == null) { tasks.remove(); @@ -44,7 +43,7 @@ public final class WorldGenTaskGroup else { // TODO why aren't we removing the task if it has a consumer? - onGenTaskCompleteConsumer.accept(chunkSizedFullDataSource); + onGenTaskCompleteConsumer.accept(chunkSizedFullDataView); } } } diff --git a/core/src/main/java/com/seibel/lod/core/level/AbstractDhClientLevel.java b/core/src/main/java/com/seibel/lod/core/level/AbstractDhClientLevel.java index c678352de..4efb11194 100644 --- a/core/src/main/java/com/seibel/lod/core/level/AbstractDhClientLevel.java +++ b/core/src/main/java/com/seibel/lod/core/level/AbstractDhClientLevel.java @@ -1,8 +1,8 @@ package com.seibel.lod.core.level; import com.seibel.lod.core.config.Config; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource; +import com.seibel.lod.core.dataObjects.fullData.accessor.ChunkSizedFullDataView; +import com.seibel.lod.core.dataObjects.fullData.sources.CompleteFullDataSource; import com.seibel.lod.core.dataObjects.transformers.ChunkToLodBuilder; import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.file.fullDatafile.FullDataFileHandler; @@ -172,16 +172,16 @@ public abstract class AbstractDhClientLevel implements IDhClientLevel @Override public void updateChunkAsync(IChunkWrapper chunk) { - CompletableFuture future = this.chunkToLodBuilder.tryGenerateData(chunk); + CompletableFuture future = this.chunkToLodBuilder.tryGenerateData(chunk); if (future != null) { future.thenAccept(this::saveWrites); } } - private void saveWrites(ChunkSizedFullDataSource data) + private void saveWrites(ChunkSizedFullDataView data) { ClientRenderState ClientRenderState = this.ClientRenderStateRef.get(); - DhLodPos pos = data.getBBoxLodPos().convertToDetailLevel(FullDataSource.SECTION_SIZE_OFFSET); + DhLodPos pos = data.getLodPos().convertToDetailLevel(CompleteFullDataSource.SECTION_SIZE_OFFSET); if (ClientRenderState != null) { ClientRenderState.renderSourceFileHandler.writeChunkDataToFile(new DhSectionPos(pos.detailLevel, pos.x, pos.z), data); diff --git a/core/src/main/java/com/seibel/lod/core/level/DhClientLevel.java b/core/src/main/java/com/seibel/lod/core/level/DhClientLevel.java index ed14f681c..c2a665177 100644 --- a/core/src/main/java/com/seibel/lod/core/level/DhClientLevel.java +++ b/core/src/main/java/com/seibel/lod/core/level/DhClientLevel.java @@ -1,32 +1,20 @@ package com.seibel.lod.core.level; -import com.seibel.lod.core.dataObjects.fullData.sources.ChunkSizedFullDataSource; -import com.seibel.lod.core.dataObjects.fullData.sources.FullDataSource; -import com.seibel.lod.core.dataObjects.transformers.ChunkToLodBuilder; import com.seibel.lod.core.file.fullDatafile.FullDataFileHandler; import com.seibel.lod.core.file.fullDatafile.IFullDataSourceProvider; import com.seibel.lod.core.file.structure.AbstractSaveStructure; import com.seibel.lod.core.level.states.ClientRenderState; import com.seibel.lod.core.logging.f3.F3Screen; -import com.seibel.lod.core.pos.DhLodPos; -import com.seibel.lod.core.pos.DhSectionPos; -import com.seibel.lod.core.util.FileScanUtil; -import com.seibel.lod.core.file.fullDatafile.RemoteFullDataFileHandler; import com.seibel.lod.core.dependencyInjection.SingletonInjector; import com.seibel.lod.core.logging.DhLoggerBuilder; import com.seibel.lod.core.pos.DhBlockPos; -import com.seibel.lod.core.util.LodUtil; -import com.seibel.lod.core.util.math.Mat4f; import com.seibel.lod.core.wrapperInterfaces.block.IBlockStateWrapper; -import com.seibel.lod.core.wrapperInterfaces.chunk.IChunkWrapper; import com.seibel.lod.core.wrapperInterfaces.minecraft.IMinecraftClientWrapper; -import com.seibel.lod.core.wrapperInterfaces.minecraft.IProfilerWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IBiomeWrapper; import com.seibel.lod.core.wrapperInterfaces.world.IClientLevelWrapper; import com.seibel.lod.core.wrapperInterfaces.world.ILevelWrapper; import org.apache.logging.log4j.Logger; -import java.util.concurrent.CompletableFuture; import java.util.concurrent.atomic.AtomicReference; /** The level used when connected to a server */