mirror of
https://github.com/VolmitSoftware/Iris.git
synced 2025-07-18 18:23:06 +00:00
Atomic MCA Data
This commit is contained in:
parent
7d56164882
commit
42e02a6129
@ -25,18 +25,22 @@ import com.volmit.iris.engine.data.nbt.tag.ListTag;
|
||||
import com.volmit.iris.engine.data.nbt.tag.LongArrayTag;
|
||||
import com.volmit.iris.util.collection.KMap;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
import java.util.concurrent.atomic.AtomicLongArray;
|
||||
|
||||
public class Section {
|
||||
|
||||
private static final Field longArrayStealer = getLongArrayValueField();
|
||||
private CompoundTag data;
|
||||
private Map<String, List<PaletteIndex>> valueIndexedPalette = new KMap<>();
|
||||
private ListTag<CompoundTag> palette;
|
||||
private byte[] blockLight;
|
||||
private long[] blockStates;
|
||||
private AtomicLongArray blockStates;
|
||||
private byte[] skyLight;
|
||||
private int dataVersion;
|
||||
|
||||
@ -65,7 +69,7 @@ public class Section {
|
||||
this.blockLight = blockLight != null ? blockLight.getValue() : null;
|
||||
}
|
||||
if ((loadFlags & LoadFlags.BLOCK_STATES) != 0) {
|
||||
this.blockStates = blockStates != null ? blockStates.getValue() : null;
|
||||
this.blockStates = blockStates != null ? new AtomicLongArray(blockStates.getValue()) : null;
|
||||
}
|
||||
if ((loadFlags & LoadFlags.SKY_LIGHT) != 0) {
|
||||
this.skyLight = skyLight != null ? skyLight.getValue() : null;
|
||||
@ -185,24 +189,24 @@ public class Section {
|
||||
* @return The index of the block data in the palette.
|
||||
*/
|
||||
public int getPaletteIndex(int blockStateIndex) {
|
||||
int bits = blockStates.length >> 6;
|
||||
int bits = blockStates.length() >> 6;
|
||||
|
||||
if (dataVersion < 2527) {
|
||||
double blockStatesIndex = blockStateIndex / (4096D / blockStates.length);
|
||||
double blockStatesIndex = blockStateIndex / (4096D / blockStates.length());
|
||||
int longIndex = (int) blockStatesIndex;
|
||||
int startBit = (int) ((blockStatesIndex - Math.floor(blockStatesIndex)) * 64D);
|
||||
if (startBit + bits > 64) {
|
||||
long prev = bitRange(blockStates[longIndex], startBit, 64);
|
||||
long next = bitRange(blockStates[longIndex + 1], 0, startBit + bits - 64);
|
||||
long prev = bitRange(blockStates.get(longIndex), startBit, 64);
|
||||
long next = bitRange(blockStates.get(longIndex + 1), 0, startBit + bits - 64);
|
||||
return (int) ((next << 64 - startBit) + prev);
|
||||
} else {
|
||||
return (int) bitRange(blockStates[longIndex], startBit, startBit + bits);
|
||||
return (int) bitRange(blockStates.get(longIndex), startBit, startBit + bits);
|
||||
}
|
||||
} else {
|
||||
int indicesPerLong = (int) (64D / bits);
|
||||
int blockStatesIndex = blockStateIndex / indicesPerLong;
|
||||
int startBit = (blockStateIndex % indicesPerLong) * bits;
|
||||
return (int) bitRange(blockStates[blockStatesIndex], startBit, startBit + bits);
|
||||
return (int) bitRange(blockStates.get(blockStatesIndex), startBit, startBit + bits);
|
||||
}
|
||||
}
|
||||
|
||||
@ -213,24 +217,24 @@ public class Section {
|
||||
* @param paletteIndex The block state to be set (index of block data in the palette).
|
||||
* @param blockStates The block states to be updated.
|
||||
*/
|
||||
public void setPaletteIndex(int blockIndex, int paletteIndex, long[] blockStates) {
|
||||
int bits = blockStates.length >> 6;
|
||||
public void setPaletteIndex(int blockIndex, int paletteIndex, AtomicLongArray blockStates) {
|
||||
int bits = blockStates.length() >> 6;
|
||||
|
||||
if (dataVersion < 2527) {
|
||||
double blockStatesIndex = blockIndex / (4096D / blockStates.length);
|
||||
double blockStatesIndex = blockIndex / (4096D / blockStates.length());
|
||||
int longIndex = (int) blockStatesIndex;
|
||||
int startBit = (int) ((blockStatesIndex - Math.floor(longIndex)) * 64D);
|
||||
if (startBit + bits > 64) {
|
||||
blockStates[longIndex] = updateBits(blockStates[longIndex], paletteIndex, startBit, 64);
|
||||
blockStates[longIndex + 1] = updateBits(blockStates[longIndex + 1], paletteIndex, startBit - 64, startBit + bits - 64);
|
||||
blockStates.set(longIndex, updateBits(blockStates.get(longIndex), paletteIndex, startBit, 64));
|
||||
blockStates.set(longIndex + 1, updateBits(blockStates.get(longIndex + 1), paletteIndex, startBit - 64, startBit + bits - 64));
|
||||
} else {
|
||||
blockStates[longIndex] = updateBits(blockStates[longIndex], paletteIndex, startBit, startBit + bits);
|
||||
blockStates.set(longIndex, updateBits(blockStates.get(longIndex), paletteIndex, startBit, startBit + bits));
|
||||
}
|
||||
} else {
|
||||
int indicesPerLong = (int) (64D / bits);
|
||||
int blockStatesIndex = blockIndex / indicesPerLong;
|
||||
int startBit = (blockIndex % indicesPerLong) * bits;
|
||||
blockStates[blockStatesIndex] = updateBits(blockStates[blockStatesIndex], paletteIndex, startBit, startBit + bits);
|
||||
blockStates.set(blockStatesIndex, updateBits(blockStates.get(blockStatesIndex), paletteIndex, startBit, startBit + bits));
|
||||
}
|
||||
}
|
||||
|
||||
@ -304,7 +308,7 @@ public class Section {
|
||||
return allIndices;
|
||||
}
|
||||
|
||||
void adjustBlockStateBits(Map<Integer, Integer> oldToNewMapping, long[] blockStates) {
|
||||
void adjustBlockStateBits(Map<Integer, Integer> oldToNewMapping, AtomicLongArray blockStates) {
|
||||
//increases or decreases the amount of bits used per BlockState
|
||||
//based on the size of the palette. oldToNewMapping can be used to update indices
|
||||
//if the palette had been cleaned up before using MCAFile#cleanupPalette().
|
||||
@ -312,13 +316,13 @@ public class Section {
|
||||
int newBits = 32 - Integer.numberOfLeadingZeros(palette.size() - 1);
|
||||
newBits = Math.max(newBits, 4);
|
||||
|
||||
long[] newBlockStates;
|
||||
AtomicLongArray newBlockStates;
|
||||
|
||||
if (dataVersion < 2527) {
|
||||
newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newBits * 64];
|
||||
newBlockStates = newBits == blockStates.length() / 64 ? blockStates : new AtomicLongArray(newBits * 64);
|
||||
} else {
|
||||
int newLength = (int) Math.ceil(4096D / (64D / newBits));
|
||||
newBlockStates = newBits == blockStates.length / 64 ? blockStates : new long[newLength];
|
||||
newBlockStates = newBits == blockStates.length() / 64 ? blockStates : new AtomicLongArray(newLength);
|
||||
}
|
||||
if (oldToNewMapping != null) {
|
||||
for (int i = 0; i < 4096; i++) {
|
||||
@ -355,7 +359,7 @@ public class Section {
|
||||
/**
|
||||
* @return The indices of the block states of this Section.
|
||||
*/
|
||||
public long[] getBlockStates() {
|
||||
public AtomicLongArray getBlockStates() {
|
||||
return blockStates;
|
||||
}
|
||||
|
||||
@ -366,10 +370,10 @@ public class Section {
|
||||
* @throws NullPointerException If <code>blockStates</code> is <code>null</code>
|
||||
* @throws IllegalArgumentException When <code>blockStates</code>' length is < 256 or > 4096 and is not a multiple of 64
|
||||
*/
|
||||
public void setBlockStates(long[] blockStates) {
|
||||
public void setBlockStates(AtomicLongArray blockStates) {
|
||||
if (blockStates == null) {
|
||||
throw new NullPointerException("BlockStates cannot be null");
|
||||
} else if (blockStates.length % 64 != 0 || blockStates.length < 256 || blockStates.length > 4096) {
|
||||
} else if (blockStates.length() % 64 != 0 || blockStates.length() < 256 || blockStates.length() > 4096) {
|
||||
throw new IllegalArgumentException("BlockStates must have a length > 255 and < 4097 and must be divisible by 64");
|
||||
}
|
||||
this.blockStates = blockStates;
|
||||
@ -402,7 +406,7 @@ public class Section {
|
||||
*/
|
||||
public static Section newSection() {
|
||||
Section s = new Section();
|
||||
s.blockStates = new long[256];
|
||||
s.blockStates = new AtomicLongArray(256);
|
||||
s.palette = new ListTag<>(CompoundTag.class);
|
||||
CompoundTag air = new CompoundTag();
|
||||
air.putString("Name", "minecraft:air");
|
||||
@ -428,11 +432,27 @@ public class Section {
|
||||
data.putByteArray("BlockLight", blockLight);
|
||||
}
|
||||
if (blockStates != null) {
|
||||
data.putLongArray("BlockStates", blockStates);
|
||||
try {
|
||||
data.putLongArray("BlockStates", (long[]) longArrayStealer.get(blockStates));
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (skyLight != null) {
|
||||
data.putByteArray("SkyLight", skyLight);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private static Field getLongArrayValueField() {
|
||||
Field f = null;
|
||||
try {
|
||||
f = AtomicLongArray.class.getDeclaredField("array");
|
||||
f.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return f;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user