mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2026-06-19 23:31:27 +00:00
BITS BITS EVERYWHERE
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.hunk.bits;
|
||||
|
||||
import com.volmit.iris.util.data.Varint;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLongArray;
|
||||
import java.util.function.IntConsumer;
|
||||
|
||||
public class DataBits {
|
||||
private static final int[] MAGIC = new int[]{
|
||||
-1, -1, 0, Integer.MIN_VALUE, 0, 0, 1431655765, 1431655765, 0, Integer.MIN_VALUE,
|
||||
0, 1, 858993459, 858993459, 0, 715827882, 715827882, 0, 613566756, 613566756,
|
||||
0, Integer.MIN_VALUE, 0, 2, 477218588, 477218588, 0, 429496729, 429496729, 0,
|
||||
390451572, 390451572, 0, 357913941, 357913941, 0, 330382099, 330382099, 0, 306783378,
|
||||
306783378, 0, 286331153, 286331153, 0, Integer.MIN_VALUE, 0, 3, 252645135, 252645135,
|
||||
0, 238609294, 238609294, 0, 226050910, 226050910, 0, 214748364, 214748364, 0,
|
||||
204522252, 204522252, 0, 195225786, 195225786, 0, 186737708, 186737708, 0, 178956970,
|
||||
178956970, 0, 171798691, 171798691, 0, 165191049, 165191049, 0, 159072862, 159072862,
|
||||
0, 153391689, 153391689, 0, 148102320, 148102320, 0, 143165576, 143165576, 0,
|
||||
138547332, 138547332, 0, Integer.MIN_VALUE, 0, 4, 130150524, 130150524, 0, 126322567,
|
||||
126322567, 0, 122713351, 122713351, 0, 119304647, 119304647, 0, 116080197, 116080197,
|
||||
0, 113025455, 113025455, 0, 110127366, 110127366, 0, 107374182, 107374182, 0,
|
||||
104755299, 104755299, 0, 102261126, 102261126, 0, 99882960, 99882960, 0, 97612893,
|
||||
97612893, 0, 95443717, 95443717, 0, 93368854, 93368854, 0, 91382282, 91382282,
|
||||
0, 89478485, 89478485, 0, 87652393, 87652393, 0, 85899345, 85899345, 0,
|
||||
84215045, 84215045, 0, 82595524, 82595524, 0, 81037118, 81037118, 0, 79536431,
|
||||
79536431, 0, 78090314, 78090314, 0, 76695844, 76695844, 0, 75350303, 75350303,
|
||||
0, 74051160, 74051160, 0, 72796055, 72796055, 0, 71582788, 71582788, 0,
|
||||
70409299, 70409299, 0, 69273666, 69273666, 0, 68174084, 68174084, 0, Integer.MIN_VALUE,
|
||||
0, 5};
|
||||
|
||||
private final AtomicLongArray data;
|
||||
private final int bits;
|
||||
private final long mask;
|
||||
private final int size;
|
||||
private final int valuesPerLong;
|
||||
private final int divideMul;
|
||||
private final int divideAdd;
|
||||
private final int divideShift;
|
||||
|
||||
public DataBits(int bits, int length) {
|
||||
this(bits, length, (AtomicLongArray) null);
|
||||
}
|
||||
|
||||
public DataBits(int bits, int length, DataInputStream din) throws IOException
|
||||
{
|
||||
this(bits, length, longs(din, (length + ((char) (64 / bits)) - 1) / ((char) (64 / bits))));
|
||||
}
|
||||
|
||||
public DataBits(int bits, int length, AtomicLongArray data) {
|
||||
Validate.inclusiveBetween(1L, 32L, bits);
|
||||
this.size = length;
|
||||
this.bits = bits;
|
||||
this.mask = (1L << bits) - 1L;
|
||||
this.valuesPerLong = (char) (64 / bits);
|
||||
int var3 = 3 * (valuesPerLong - 1);
|
||||
this.divideMul = MAGIC[var3];
|
||||
this.divideAdd = MAGIC[var3 + 1];
|
||||
this.divideShift = MAGIC[var3 + 2];
|
||||
int var4 = (length + valuesPerLong - 1) / valuesPerLong;
|
||||
if (data != null) {
|
||||
if (data.length() != var4)
|
||||
{
|
||||
throw new RuntimeException("NO!");
|
||||
}
|
||||
this.data = data;
|
||||
} else {
|
||||
this.data = new AtomicLongArray(var4);
|
||||
}
|
||||
}
|
||||
|
||||
private static AtomicLongArray longs(DataInputStream din, int len) throws IOException{
|
||||
AtomicLongArray a = new AtomicLongArray(len);
|
||||
|
||||
for(int i = 0; i < len; i++)
|
||||
{
|
||||
a.set(i, din.readLong());
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
public DataBits setBits(int newBits)
|
||||
{
|
||||
if(bits != newBits)
|
||||
{
|
||||
DataBits newData = new DataBits(newBits, size);
|
||||
AtomicInteger c = new AtomicInteger(0);
|
||||
getAll((i) -> newData.set(c.incrementAndGet(), i));
|
||||
return newData;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private int cellIndex(int var0) {
|
||||
long var1 = Integer.toUnsignedLong(this.divideMul);
|
||||
long var3 = Integer.toUnsignedLong(this.divideAdd);
|
||||
return (int) (var0 * var1 + var3 >> 32L >> this.divideShift);
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBitwiseExpression")
|
||||
public int getAndSet(int var0, int var1) {
|
||||
Validate.inclusiveBetween(0L, (this.size - 1), var0);
|
||||
Validate.inclusiveBetween(0L, this.mask, var1);
|
||||
int var2 = cellIndex(var0);
|
||||
long var3 = this.data.get(var2);
|
||||
int var5 = (var0 - var2 * this.valuesPerLong) * this.bits;
|
||||
int var6 = (int) (var3 >> var5 & this.mask);
|
||||
this.data.set(var2, var3 & (this.mask << var5 ^ 0xFFFFFFFFFFFFFFFFL) | (var1 & this.mask) << var5);
|
||||
return var6;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PointlessBitwiseExpression")
|
||||
public void set(int var0, int var1) {
|
||||
Validate.inclusiveBetween(0L, (this.size - 1), var0);
|
||||
Validate.inclusiveBetween(0L, this.mask, var1);
|
||||
int var2 = cellIndex(var0);
|
||||
long var3 = this.data.get(var2);
|
||||
int var5 = (var0 - var2 * this.valuesPerLong) * this.bits;
|
||||
|
||||
this.data.set(var2, var3 & (this.mask << var5 ^ 0xFFFFFFFFFFFFFFFFL) | (var1 & this.mask) << var5);
|
||||
}
|
||||
|
||||
public int get(int var0) {
|
||||
Validate.inclusiveBetween(0L, (size - 1), var0);
|
||||
int var1 = cellIndex(var0);
|
||||
long var2 = this.data.get(var1);
|
||||
int var4 = (var0 - var1 * valuesPerLong) * this.bits;
|
||||
return (int) (var2 >> var4 & mask);
|
||||
}
|
||||
|
||||
public AtomicLongArray getRaw() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public int getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public int getBits() {
|
||||
return bits;
|
||||
}
|
||||
|
||||
public void getAll(IntConsumer var0) {
|
||||
int var1 = 0;
|
||||
for(int i = 0; i < data.length(); i++)
|
||||
{
|
||||
long var5 = data.get(i);
|
||||
for (int var7 = 0; var7 < valuesPerLong; var7++) {
|
||||
var0.accept((int) (var5 & mask));
|
||||
var5 >>= bits;
|
||||
if (++var1 >= size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void write(DataOutputStream dos) throws IOException {
|
||||
dos.writeByte(bits);
|
||||
|
||||
for(int i = 0; i < data.length(); i++)
|
||||
{
|
||||
dos.writeLong(data.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.hunk.bits;
|
||||
|
||||
import com.volmit.iris.util.data.Varint;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
public class DataContainer<T> {
|
||||
protected static final int INITIAL_BITS = 3;
|
||||
protected static final int LINEAR_BITS_LIMIT = 5;
|
||||
protected static final int LINEAR_INITIAL_LENGTH = (int) Math.pow(2, LINEAR_BITS_LIMIT) + 1;
|
||||
protected static final int[] BIT = computeBitLimits();
|
||||
private final AtomicReference<Palette<T>> palette;
|
||||
private final AtomicReference<DataBits> data;
|
||||
private final AtomicInteger bits;
|
||||
private final int length;
|
||||
private final Writable<T> writer;
|
||||
|
||||
public DataContainer(Writable<T> writer, int length)
|
||||
{
|
||||
this.writer = writer;
|
||||
this.length = length;
|
||||
this.palette = new AtomicReference<>(newPalette(INITIAL_BITS));
|
||||
this.data = new AtomicReference<>(new DataBits(INITIAL_BITS, length));
|
||||
this.bits = new AtomicInteger(INITIAL_BITS);
|
||||
}
|
||||
|
||||
public byte[] write() throws IOException
|
||||
{
|
||||
ByteArrayOutputStream boas = new ByteArrayOutputStream();
|
||||
write(boas);
|
||||
return boas.toByteArray();
|
||||
}
|
||||
|
||||
public static <T> DataContainer<T> read(InputStream in, Writable<T> writer) throws IOException {
|
||||
DataInputStream din = new DataInputStream(in);
|
||||
return readDin(din, writer);
|
||||
}
|
||||
|
||||
public static <T> DataContainer<T> readDin(DataInputStream in, Writable<T> writer) throws IOException {
|
||||
DataInputStream din = new DataInputStream(in);
|
||||
DataContainer<T> container = new DataContainer<>(writer, Varint.readUnsignedVarInt(din));
|
||||
int paletteSize = Varint.readUnsignedVarInt(din);
|
||||
container.palette.set(container.newPalette(BIT[paletteSize]).from(paletteSize, writer, din));
|
||||
container.data.set(new DataBits(container.palette.get().bits(), container.length, din));
|
||||
return container;
|
||||
}
|
||||
|
||||
public void write(OutputStream out) throws IOException
|
||||
{
|
||||
DataOutputStream dos = new DataOutputStream(out);
|
||||
writeDos(dos);
|
||||
}
|
||||
|
||||
public void writeDos(DataOutputStream out) throws IOException
|
||||
{
|
||||
DataOutputStream dos = new DataOutputStream(out);
|
||||
Varint.writeUnsignedVarInt(length);
|
||||
Varint.writeUnsignedVarInt(palette.get().size());
|
||||
palette.get().iterateIO((data, __) -> writer.writeNodeData(dos, data));
|
||||
data.get().write(dos);
|
||||
}
|
||||
|
||||
private Palette<T> newPalette(int bits)
|
||||
{
|
||||
if(bits <= LINEAR_BITS_LIMIT)
|
||||
{
|
||||
return new LinearPalette<>(LINEAR_INITIAL_LENGTH);
|
||||
}
|
||||
|
||||
return new HashPalette<>();
|
||||
}
|
||||
|
||||
public void set(int position, T t)
|
||||
{
|
||||
int id = palette.get().id(t);
|
||||
|
||||
if(id == -1)
|
||||
{
|
||||
id = palette.get().add(t);
|
||||
}
|
||||
|
||||
data.get().set(position, id);
|
||||
}
|
||||
|
||||
public T get(int position)
|
||||
{
|
||||
int id = data.get().get(position);
|
||||
|
||||
if(id <= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return palette.get().get(id - 1);
|
||||
}
|
||||
|
||||
public void setBits(int bits)
|
||||
{
|
||||
if(this.bits.get() != bits)
|
||||
{
|
||||
if(this.bits.get() <= LINEAR_BITS_LIMIT != bits <= LINEAR_BITS_LIMIT)
|
||||
{
|
||||
palette.set(newPalette(bits).from(palette.get()));
|
||||
}
|
||||
|
||||
this.bits.set(bits);
|
||||
data.set(data.get().setBits(bits));
|
||||
}
|
||||
}
|
||||
|
||||
private static int[] computeBitLimits() {
|
||||
int[] m = new int[16];
|
||||
|
||||
for(int i = 0; i < m.length; i++)
|
||||
{
|
||||
m[i] = (int) Math.pow(2, i);
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.hunk.bits;
|
||||
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
import com.volmit.iris.util.function.Consumer2;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class HashPalette<T> implements Palette<T> {
|
||||
private final KMap<T, Integer> palette;
|
||||
private final KMap<Integer, T> lookup;
|
||||
private final AtomicInteger size;
|
||||
|
||||
public HashPalette()
|
||||
{
|
||||
this.size = new AtomicInteger(0);
|
||||
this.palette = new KMap<>();
|
||||
this.lookup = new KMap<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(int id) {
|
||||
if(id < 0 || id >= size.get())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return lookup.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int add(T t) {
|
||||
int index = size.getAndIncrement();
|
||||
palette.put(t, index);
|
||||
lookup.put(index, t);
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int id(T t) {
|
||||
Integer v = palette.get(t);
|
||||
return v != null ? v : -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iterate(Consumer2<T, Integer> c) {
|
||||
for(T i : palette.keySet())
|
||||
{
|
||||
c.accept(i, id(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.hunk.bits;
|
||||
|
||||
import com.volmit.iris.util.function.Consumer2;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.concurrent.atomic.AtomicReferenceArray;
|
||||
|
||||
public class LinearPalette<T> implements Palette<T> {
|
||||
private final AtomicReference<AtomicReferenceArray<T>> palette;
|
||||
private final AtomicInteger size;
|
||||
|
||||
public LinearPalette(int initialSize)
|
||||
{
|
||||
this.size = new AtomicInteger(0);
|
||||
this.palette = new AtomicReference<>(new AtomicReferenceArray<>(initialSize));
|
||||
}
|
||||
|
||||
@Override
|
||||
public T get(int id) {
|
||||
if(id < 0 || id >= size.get())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return palette.get().get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int add(T t) {
|
||||
int index = size.getAndIncrement();
|
||||
grow(index + 1);
|
||||
palette.get().set(index, t);
|
||||
return index;
|
||||
}
|
||||
|
||||
private void grow(int newLength) {
|
||||
if(newLength > palette.get().length())
|
||||
{
|
||||
AtomicReferenceArray<T> a = new AtomicReferenceArray<>(newLength + size.get());
|
||||
|
||||
for(int i = 0; i < palette.get().length(); i++)
|
||||
{
|
||||
a.set(i, palette.get().get(i));
|
||||
}
|
||||
|
||||
palette.set(a);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int id(T t) {
|
||||
for(int i = 0; i < size(); i++)
|
||||
{
|
||||
if(t.equals(palette.get().get(i)))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return size.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void iterate(Consumer2<T, Integer> c) {
|
||||
for(int i = 0; i < size(); i++)
|
||||
{
|
||||
c.accept(palette.get().get(i), i);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.hunk.bits;
|
||||
|
||||
import com.volmit.iris.util.function.Consumer2;
|
||||
import com.volmit.iris.util.function.Consumer2IO;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface Palette<T> {
|
||||
T get(int id);
|
||||
|
||||
int add(T t);
|
||||
|
||||
int id(T t);
|
||||
|
||||
int size();
|
||||
|
||||
default int bits()
|
||||
{
|
||||
return bits(DataContainer.INITIAL_BITS);
|
||||
}
|
||||
|
||||
default int bits(int minBits)
|
||||
{
|
||||
if(size() <= DataContainer.BIT[minBits])
|
||||
{
|
||||
return minBits;
|
||||
}
|
||||
|
||||
for(int i = 0; i < DataContainer.BIT.length; i++)
|
||||
{
|
||||
if(DataContainer.BIT[i] >= size())
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return DataContainer.BIT.length - 1;
|
||||
}
|
||||
|
||||
void iterate(Consumer2<T, Integer> c);
|
||||
|
||||
default void iterateIO(Consumer2IO<T, Integer> c)
|
||||
{
|
||||
iterate((a,b)-> {
|
||||
try {
|
||||
c.accept(a,b);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
default Palette<T> from(int size, Writable<T> writable, DataInputStream in) throws IOException {
|
||||
for(int i = 0; i < size; i++)
|
||||
{
|
||||
add(writable.readNodeData(in));
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
default Palette<T> from(Palette<T> oldPalette)
|
||||
{
|
||||
oldPalette.iterate((k,v) -> add(k));
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Iris is a World Generator for Minecraft Bukkit Servers
|
||||
* Copyright (c) 2021 Arcane Arts (Volmit Software)
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.volmit.iris.util.hunk.bits;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public interface Writable<T> {
|
||||
T readNodeData(DataInputStream din) throws IOException;
|
||||
|
||||
void writeNodeData(DataOutputStream dos, T t) throws IOException;
|
||||
}
|
||||
@@ -23,6 +23,8 @@ import com.volmit.iris.util.data.palette.PalettedContainer;
|
||||
import com.volmit.iris.util.function.Consumer4;
|
||||
import com.volmit.iris.util.function.Consumer4IO;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.hunk.bits.DataContainer;
|
||||
import com.volmit.iris.util.hunk.bits.Writable;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@@ -33,17 +35,27 @@ import java.util.Map;
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class PaletteHunk<T> extends StorageHunk<T> implements Hunk<T> {
|
||||
private PalettedContainer<T> data;
|
||||
private DataContainer<T> data;
|
||||
|
||||
public PaletteHunk() {
|
||||
super(16, 16, 16);
|
||||
data = new PalettedContainer<>();
|
||||
public PaletteHunk(int w, int h, int d, Writable<T> writer) {
|
||||
super(w,h,d);
|
||||
data = new DataContainer<>(writer, w * h * d);
|
||||
}
|
||||
|
||||
|
||||
public void setPalette(DataContainer<T> c) {
|
||||
data = c;
|
||||
}
|
||||
|
||||
|
||||
public boolean isMapped() {
|
||||
return false;
|
||||
}
|
||||
|
||||
private int index(int x, int y, int z) {
|
||||
return (z * getWidth() * getHeight()) + (y * getWidth()) + x;
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized Hunk<T> iterateSync(Consumer4<Integer, Integer, Integer, T> c) {
|
||||
for(int i = 0; i < getWidth(); i++)
|
||||
@@ -84,11 +96,11 @@ public class PaletteHunk<T> extends StorageHunk<T> implements Hunk<T> {
|
||||
|
||||
@Override
|
||||
public void setRaw(int x, int y, int z, T t) {
|
||||
data.set(x,y,z,t);
|
||||
data.set(index(x, y, z), t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getRaw(int x, int y, int z) {
|
||||
return data.get(x,y,z);
|
||||
return data.get(index(x, y, z));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@ import com.volmit.iris.util.data.palette.PalettedContainer;
|
||||
import com.volmit.iris.util.function.Consumer4;
|
||||
import com.volmit.iris.util.function.Consumer4IO;
|
||||
import com.volmit.iris.util.hunk.Hunk;
|
||||
import com.volmit.iris.util.hunk.bits.DataContainer;
|
||||
import com.volmit.iris.util.hunk.bits.Writable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
@@ -29,26 +31,26 @@ import java.util.function.Supplier;
|
||||
|
||||
public class PaletteOrHunk<T> extends StorageHunk<T> implements Hunk<T> {
|
||||
private final Hunk<T> hunk;
|
||||
public PaletteOrHunk(int width, int height, int depth, boolean allow, Supplier<Hunk<T>> factory) {
|
||||
public PaletteOrHunk(int width, int height, int depth, boolean allow, Writable<T> writable, Supplier<Hunk<T>> factory) {
|
||||
super(width, height, depth);
|
||||
hunk = (width == 16 && height == 16 && depth == 16 && allow) ? new PaletteHunk<>() : factory.get();
|
||||
hunk = (allow) ? new PaletteHunk<>(width, height, depth, writable) : factory.get();
|
||||
}
|
||||
|
||||
public PalettedContainer<T> palette()
|
||||
public DataContainer<T> palette()
|
||||
{
|
||||
return isPalette() ? ((PaletteHunk<T>)hunk).getData() : null;
|
||||
}
|
||||
|
||||
public void palette(PalettedContainer<T> t)
|
||||
{
|
||||
if(isPalette()){
|
||||
((PaletteHunk<T>)hunk).setData(t);
|
||||
public void setPalette(DataContainer<T> c) {
|
||||
if(isPalette())
|
||||
{
|
||||
((PaletteHunk<T>)hunk).setPalette(c);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPalette()
|
||||
{
|
||||
return getWidth() == 16 && getHeight() == 16 && getDepth() == 16;
|
||||
return hunk instanceof PaletteHunk;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -36,7 +36,7 @@ public class FunctionalHunkView<R, T> implements Hunk<T> {
|
||||
@Override
|
||||
public void setRaw(int x, int y, int z, T t) {
|
||||
if (backConverter == null) {
|
||||
throw new UnsupportedOperationException("You cannot write to this hunk (Read Only)");
|
||||
throw new UnsupportedOperationException("You cannot writeNodeData to this hunk (Read Only)");
|
||||
}
|
||||
|
||||
src.setRaw(x, y, z, backConverter.apply(t));
|
||||
|
||||
Reference in New Issue
Block a user