Refactor and rename DhApiChunkOfDataPoints -> DhApiChunk

This commit is contained in:
James Seibel
2023-12-21 22:14:13 -06:00
parent 9e8ca25a71
commit 51c76fe5fb
6 changed files with 256 additions and 102 deletions
@@ -0,0 +1,56 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2023 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.api.enums.worldGeneration;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
import com.seibel.distanthorizons.api.interfaces.override.worldGenerator.IDhApiWorldGenerator;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;
/**
* VANILLA_CHUNKS, <br>
* API_CHUNKS <br>
*
* @author Builderb0y, James Seibel
* @version 2023-12-21
* @since API 1.1.0
*/
public enum EDhApiWorldGeneratorReturnType
{
/**
* when this constant is returned by {@link IDhApiWorldGenerator#getReturnType()},
* {@link IDhApiWorldGenerator#generateChunks(int, int, byte, byte, EDhApiDistantGeneratorMode, ExecutorService, Consumer)}
* will be used when generating terrain.
*
* @since API 1.1.0
*/
VANILLA_CHUNKS,
/**
* when this constant is returned by {@link IDhApiWorldGenerator#getReturnType()},
* {@link IDhApiWorldGenerator#generateApiChunks(int, int, byte, byte, EDhApiDistantGeneratorMode, ExecutorService, Consumer)}
* will be used when generating terrain.
*
* @since API 1.1.0
*/
API_CHUNKS;
}
@@ -19,10 +19,11 @@
package com.seibel.distanthorizons.api.interfaces.override.worldGenerator;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiWorldGeneratorReturnType;
import com.seibel.distanthorizons.api.interfaces.override.IDhApiOverrideable;
import com.seibel.distanthorizons.api.enums.EDhApiDetailLevel;
import com.seibel.distanthorizons.api.enums.worldGeneration.EDhApiDistantGeneratorMode;
import com.seibel.distanthorizons.api.objects.data.DhApiChunkOfDataPoints;
import com.seibel.distanthorizons.api.objects.data.DhApiChunk;
import java.io.Closeable;
import java.util.concurrent.CompletableFuture;
@@ -104,7 +105,7 @@ public interface IDhApiWorldGenerator extends Closeable, IDhApiOverrideable
/**
* This method is called by Distant Horizons to generate terrain over a given area when
* {@link #getReturnType()} returns {@link EDhApiWorldGeneratorReturnType#CHUNKS}. <br><br>
* {@link #getReturnType()} returns {@link EDhApiWorldGeneratorReturnType#VANILLA_CHUNKS}. <br><br>
*
* After a chunk has been generated it (and any necessary supporting objects as listed below) should be passed into the
* resultConsumer's {@link Consumer#accept} method. If the Consumer is given the wrong data
@@ -118,8 +119,8 @@ public interface IDhApiWorldGenerator extends Closeable, IDhApiOverrideable
* - [net.minecraft.world.level.ServerLevel] or [net.minecraft.world.level.ClientLevel] <br>
*
* @implNote the default implementation of this method throws an {@link UnsupportedOperationException},
* and must be overridden when {@link #getReturnType()} returns {@link EDhApiWorldGeneratorReturnType#CHUNKS}.
* since {@link #getReturnType()} returns {@link EDhApiWorldGeneratorReturnType#CHUNKS} by default,
* and must be overridden when {@link #getReturnType()} returns {@link EDhApiWorldGeneratorReturnType#VANILLA_CHUNKS}.
* since {@link #getReturnType()} returns {@link EDhApiWorldGeneratorReturnType#VANILLA_CHUNKS} by default,
* this method must also be overridden when {@link #getReturnType()} is NOT overridden.
*
* @param chunkPosMinX the chunk X position closest to negative infinity
@@ -142,19 +143,20 @@ public interface IDhApiWorldGenerator extends Closeable, IDhApiOverrideable
EDhApiDistantGeneratorMode generatorMode,
ExecutorService worldGeneratorThreadPool,
Consumer<Object[]> resultConsumer
) {
)
{
throw new UnsupportedOperationException();
}
/**
* This method is called by Distant Horizons to generate terrain over a given area when
* {@link #getReturnType()} returns {@link EDhApiWorldGeneratorReturnType#CHUNKS_OF_DATA_POINTS}. <br><br>
* {@link #getReturnType()} returns {@link EDhApiWorldGeneratorReturnType#API_CHUNKS}. <br><br>
*
* after the chunk of data points has been generated, it should be passed into the
* After the {@link DhApiChunk} has been generated, it should be passed into the
* resultConsumer's {@link Consumer#accept(Object)} method.
*
* @implNote the default implementation of this method throws an {@link UnsupportedOperationException},
* and must be overridden when {@link #getReturnType()} returns {@link EDhApiWorldGeneratorReturnType#CHUNKS_OF_DATA_POINTS}.
* and must be overridden when {@link #getReturnType()} returns {@link EDhApiWorldGeneratorReturnType#API_CHUNKS}.
*
* @param chunkPosMinX the chunk X position closest to negative infinity
* @param chunkPosMinZ the chunk Z position closest to negative infinity
@@ -168,30 +170,28 @@ public interface IDhApiWorldGenerator extends Closeable, IDhApiOverrideable
*
* @since API 1.1.0
*/
default CompletableFuture<Void> generateChunksOfDataPoints(
default CompletableFuture<Void> generateApiChunks(
int chunkPosMinX,
int chunkPosMinZ,
byte granularity,
byte targetDataDetail,
EDhApiDistantGeneratorMode generatorMode,
ExecutorService worldGeneratorThreadPool,
Consumer<DhApiChunkOfDataPoints> resultConsumer
) {
Consumer<DhApiChunk> resultConsumer
)
{
throw new UnsupportedOperationException();
}
/**
* This method controls how Distant Horizons should request that
* this world generator generate terrain over a given area.
* by default, the return value is {@link EDhApiWorldGeneratorReturnType#CHUNKS},
* This method controls how Distant Horizons requests generated chunks.
* By default, the return value is {@link EDhApiWorldGeneratorReturnType#VANILLA_CHUNKS},
* which means that {@link #generateChunks(int, int, byte, byte, EDhApiDistantGeneratorMode, ExecutorService, Consumer)}
* will be invoked whenever Distant Horizons wants this world generator to generate terrain over a given area.
* will be invoked whenever Distant Horizons wants to generate terrain with this world generator.
*
* @since API 1.1.0
*/
default EDhApiWorldGeneratorReturnType getReturnType() {
return EDhApiWorldGeneratorReturnType.CHUNKS;
}
default EDhApiWorldGeneratorReturnType getReturnType() { return EDhApiWorldGeneratorReturnType.VANILLA_CHUNKS; }
@@ -218,30 +218,5 @@ public interface IDhApiWorldGenerator extends Closeable, IDhApiOverrideable
@Override
void close();
/**
* an enum to control how Distant Horizons should request that
* a world generator generate terrain over a given area.
*
* @since API 1.1.0
*/
enum EDhApiWorldGeneratorReturnType {
/**
* when this constant is returned by {@link #getReturnType()},
* {@link #generateChunks(int, int, byte, byte, EDhApiDistantGeneratorMode, ExecutorService, Consumer)}
* will be called to generate terrain.
*
* @since API 1.1.0
*/
CHUNKS,
/**
* when this constant is returned by {@link #getReturnType()},
* {@link #generateChunksOfDataPoints(int, int, byte, byte, EDhApiDistantGeneratorMode, ExecutorService, Consumer)}
* will be called to generate terrain.
*
* @since API 1.1.0
*/
CHUNKS_OF_DATA_POINTS;
}
}
@@ -0,0 +1,129 @@
/*
* This file is part of the Distant Horizons mod
* licensed under the GNU LGPL v3 License.
*
* Copyright (C) 2020-2023 James Seibel
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, version 3.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.seibel.distanthorizons.api.objects.data;
import com.seibel.distanthorizons.api.interfaces.factories.IDhApiWrapperFactory;
import com.seibel.distanthorizons.api.interfaces.override.worldGenerator.IDhApiWorldGenerator;
import java.util.ArrayList;
import java.util.List;
/**
* Contains a list of {@link DhApiTerrainDataPoint} representing the blocks in a Minecraft chunk.
*
* @author Builderb0y, James Seibel
* @version 2023-12-21
* @since API 1.1.0
*
* @see IDhApiWrapperFactory
* @see DhApiTerrainDataPoint
* @see IDhApiWorldGenerator
*/
public class DhApiChunk
{
public final int chunkPosX;
public final int chunkPosZ;
public final int topYBlockPos;
public final int bottomYBlockPos;
private final List<List<DhApiTerrainDataPoint>> dataPoints = new ArrayList<>(16 * 16); // 256
//==============//
// constructors //
//==============//
public DhApiChunk(int chunkPosX, int chunkPosZ, int topYBlockPos, int bottomYBlockPos)
{
this.chunkPosX = chunkPosX;
this.chunkPosZ = chunkPosZ;
this.topYBlockPos = topYBlockPos;
this.bottomYBlockPos = bottomYBlockPos;
}
//=================//
// getters/setters //
//=================//
/**
* @param relX a block position between 0 and 15 (inclusive) representing the X axis in the chunk
* @param relZ a block position between 0 and 15 (inclusive) representing the Z axis in the chunk
* @return the {@link DhApiTerrainDataPoint}'s representing the blocks at the relative X and Z position in the chunk.
* @throws IndexOutOfBoundsException if relX or relZ are outside the chunk
*/
public List<DhApiTerrainDataPoint> getDataPoints(int relX, int relZ) throws IndexOutOfBoundsException
{
throwIfRelativePosOutOfBounds(relX, relZ);
return this.dataPoints.get((relZ << 4) | relX);
}
/**
* @param relX a block position between 0 and 15 (inclusive) representing the X axis in the chunk
* @param relZ a block position between 0 and 15 (inclusive) representing the Z axis in the chunk
* @param dataPoints Represents the blocks at the relative X and Z position in the chunk.
* Cannot contain null objects or data points with any detail level but 0 (block-sized).
* @throws IndexOutOfBoundsException if relX or relZ are outside the chunk
*/
public void setDataPoints(int relX, int relZ, List<DhApiTerrainDataPoint> dataPoints) throws IndexOutOfBoundsException, IllegalArgumentException
{
throwIfRelativePosOutOfBounds(relX, relZ);
// validate the incoming datapoints
if (dataPoints != null)
{
for (int i = 0; i < dataPoints.size(); i++) // standard for-loop used instead of an enhanced for-loop to slightly reduce GC overhead due to iterator allocation
{
DhApiTerrainDataPoint dataPoint = dataPoints.get(i);
if (dataPoint == null)
{
throw new IllegalArgumentException("Null DhApiTerrainDataPoints are not allowed. If you want to represent empty terrain, please use AIR.");
}
if (dataPoint.detailLevel != 0)
{
throw new IllegalArgumentException("DhApiTerrainDataPoints has the wrong detail level ["+dataPoint.detailLevel+"], all data points must be block sized; IE their detail level must be [0].");
}
}
}
this.dataPoints.set((relZ << 4) | relX, dataPoints);
}
//================//
// helper methods //
//================//
/** Included to prevent users accidentally setting columns outside the chunk */
private static void throwIfRelativePosOutOfBounds(int relX, int relZ)
{
if (relX < 0 || relX > 15 ||
relZ < 0 || relZ > 15)
{
throw new IndexOutOfBoundsException("Relative block positions must be between 0 and 15 (inclusive) the block pos: ("+relX+","+relZ+") is outside of those boundaries.");
}
}
}
@@ -1,26 +0,0 @@
package com.seibel.distanthorizons.api.objects.data;
import java.util.List;
public class DhApiChunkOfDataPoints {
public final int chunkPosX, chunkPosZ;
public final int chunkBottomY, chunkTopY;
@SuppressWarnings("unchecked") //generic array.
private final List<DhApiTerrainDataPoint>[] dataPoints = new List[256];
public DhApiChunkOfDataPoints(int chunkPosX, int chunkPosZ, int chunkBottomY, int chunkTopY) {
this.chunkPosX = chunkPosX;
this.chunkPosZ = chunkPosZ;
this.chunkBottomY = chunkBottomY;
this.chunkTopY = chunkTopY;
}
public List<DhApiTerrainDataPoint> getDataPoints(int x, int z) {
return this.dataPoints[(z << 4) | x];
}
public void setDataPoints(int x, int z, List<DhApiTerrainDataPoint> dataPoints) {
this.dataPoints[(z << 4) | x] = dataPoints;
}
}