Add Palette#fill

This commit is contained in:
themode 2022-01-03 22:07:13 +01:00 committed by TheMode
parent cf93b39321
commit 9689c89010
3 changed files with 50 additions and 0 deletions

View File

@ -25,6 +25,8 @@ public sealed interface Palette extends Writeable permits PaletteImpl {
void set(int x, int y, int z, int value); void set(int x, int y, int z, int value);
void fill(int value);
/** /**
* Returns the number of entries in this palette. * Returns the number of entries in this palette.
*/ */

View File

@ -7,6 +7,8 @@ import net.minestom.server.instance.Chunk;
import net.minestom.server.utils.binary.BinaryWriter; import net.minestom.server.utils.binary.BinaryWriter;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
final class PaletteImpl implements Palette, Cloneable { final class PaletteImpl implements Palette, Cloneable {
private static final int[] MAGIC_MASKS; private static final int[] MAGIC_MASKS;
private static final int[] VALUES_PER_LONG; private static final int[] VALUES_PER_LONG;
@ -125,6 +127,30 @@ final class PaletteImpl implements Palette, Cloneable {
} }
} }
@Override
public void fill(int value) {
final boolean placedAir = value == 0;
if (!placedAir) value = getPaletteIndex(value);
final int bitsPerEntry = this.bitsPerEntry;
final int valuesPerLong = VALUES_PER_LONG[bitsPerEntry];
long[] values = this.values;
if (values.length == 0) {
if (placedAir) {
// Section is empty and method is trying to place an air block, stop unnecessary computation
return;
}
// Initialize the section
this.values = values = new long[(size + valuesPerLong - 1) / valuesPerLong];
}
long block = 0;
for (int i = 0; i < valuesPerLong; i++) {
block |= (long) value << i * bitsPerEntry;
}
Arrays.fill(values, block);
this.count = maxSize();
}
@Override @Override
public int size() { public int size() {
return count; return count;

View File

@ -77,6 +77,28 @@ public class PaletteTest {
assertEquals(4, palette.get(0, 0, 3)); assertEquals(4, palette.get(0, 0, 3));
} }
@Test
public void fill() {
var palettes = testPalettes();
for (Palette palette : palettes) {
assertEquals(0, palette.size());
palette.set(0, 0, 0, 5);
assertEquals(1, palette.size());
assertEquals(5, palette.get(0, 0, 0));
palette.fill(6);
assertEquals(6, palette.get(0, 0, 0));
assertEquals(palette.maxSize(), palette.size());
for (int y = 0; y < palette.dimension(); y++) {
for (int x = 0; x < palette.dimension(); x++) {
for (int z = 0; z < palette.dimension(); z++) {
assertEquals(6, palette.get(x, y, z));
}
}
}
}
}
@Test @Test
public void dimension() { public void dimension() {
assertThrows(Exception.class, () -> Palette.newPalette(0, 5, 3, 1)); assertThrows(Exception.class, () -> Palette.newPalette(0, 5, 3, 1));