Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ public class Section extends AbstractNBTItem implements SectionedChunk.Section {
public CompoundTag toNBT() {
setByte(TAG_Y, level);

final PackedArrayCube<Material>.PackedData packedMaterials = materials.pack(AIR);
final PackedArrayCube.PackedData<Material> packedMaterials = materials.pack(AIR);
final List<CompoundTag> paletteList = new ArrayList<>(packedMaterials.palette.length);
for (Material material: packedMaterials.palette) {
final CompoundTag paletteEntry = new CompoundTag("", Collections.emptyMap());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import org.jnbt.*;
import org.pepsoft.minecraft.MC118AnvilChunk.Section.IncompleteSectionException;
import org.pepsoft.util.PackedArrayCube;
import org.pepsoft.util.Palleted16Section;
import org.pepsoft.util.mdc.MDCCapturingRuntimeException;
import org.pepsoft.worldpainter.exporting.MinecraftWorld;
import org.slf4j.Logger;
Expand Down Expand Up @@ -513,7 +514,7 @@ public void setMaterial(int x, int y, int z, Material material) {
}
if (section.singleMaterial != null) {
if (material != section.singleMaterial) {
section.materials = new PackedArrayCube<>(16, 4, false, Material.class);
section.materials = new Palleted16Section<>(Material.class);
if (section.singleMaterial != AIR) {
section.materials.fill(section.singleMaterial);
}
Expand Down Expand Up @@ -817,7 +818,7 @@ public static class Section extends AbstractNBTItem implements SectionedChunk.Se
final LongArrayTag blockStatesDataTag = (LongArrayTag) blockStatesTag.getTag(TAG_DATA_);
if (blockStatesDataTag != null) {
final long[] blockStates = blockStatesDataTag.getValue();
materials = new PackedArrayCube<>(16, blockStates, palette, 4, false, Material.class);
materials = new Palleted16Section<>(16, blockStates, palette, 4, false, Material.class);
} else if (palette.length == 1) {
// Entire section filled with one material
singleMaterial = (palette[0] == null) ? AIR : palette[0];
Expand Down Expand Up @@ -875,7 +876,7 @@ public CompoundTag toNBT() {
if (singleMaterial != null) {
setMap(TAG_BLOCK_STATES_, ImmutableMap.of(TAG_PALETTE_, new ListTag<>(TAG_PALETTE_, CompoundTag.class, singletonList(createPaletteEntry(singleMaterial)))));
} else {
PackedArrayCube<Material>.PackedData packedMaterials = materials.pack();
PackedArrayCube.PackedData<Material> packedMaterials = materials.pack();
List<CompoundTag> palette = new ArrayList<>(packedMaterials.palette.length);
for (Material material: packedMaterials.palette) {
palette.add(createPaletteEntry(material));
Expand All @@ -886,7 +887,7 @@ public CompoundTag toNBT() {
if (singleBiome != null) {
setMap(TAG_BIOMES_, ImmutableMap.of(TAG_PALETTE_, new ListTag<>(TAG_PALETTE_, StringTag.class, singletonList(new StringTag("", singleBiome)))));
} else if (biomes != null) {
PackedArrayCube<String>.PackedData packedBiomes = biomes.pack();
PackedArrayCube.PackedData<String> packedBiomes = biomes.pack();
List<StringTag> palette = new ArrayList<>(packedBiomes.palette.length);
for (String biome: packedBiomes.palette) {
palette.add(new StringTag("", biome));
Expand Down Expand Up @@ -991,7 +992,7 @@ private CompoundTag createPaletteEntry(Material material) {
byte[] skyLight;
byte[] blockLight;
// Exactly one of these should be set:
PackedArrayCube<Material> materials;
Palleted16Section<Material> materials;
Material singleMaterial;
// At most one of these should be set:
PackedArrayCube<String> biomes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1194,14 +1194,7 @@ public static Material getByCombinedIndex(int index) {
* @return The single instance of the specified material.
*/
public static Material get(Identity identity) {
synchronized (ALL_MATERIALS) {
Material material = ALL_MATERIALS.get(identity);
if (material == null) {
material = new Material(identity);
ALL_MATERIALS.put(identity, material);
}
return material;
}
return ALL_MATERIALS.computeIfAbsent(identity, Material::new);
}

/**
Expand Down Expand Up @@ -1299,7 +1292,7 @@ public static Set<String> getAllNames() {
* Get all realised materials.
*/
public static Collection<Material> getAllMaterials() {
return Collections.unmodifiableCollection(ALL_MATERIALS.values());
return unmodifiableCollection(ALL_MATERIALS.values());
}

/**
Expand Down Expand Up @@ -1644,7 +1637,7 @@ public static boolean guessTreeRelated(String name) {
* legacy materials. 12-bit block ids above 255 are created on the fly.
*/
private static final Material[] LEGACY_MATERIALS = new Material[4096];
private static final Map<Identity, Material> ALL_MATERIALS = new HashMap<>();
private static final ConcurrentHashMap<Identity, Material> ALL_MATERIALS = new ConcurrentHashMap<>();
private static final Map<String, Set<String>> SIMPLE_NAMES_BY_NAMESPACE = new HashMap<>();
private static final Map<String, Material> DEFAULT_MATERIALS_BY_NAME = new HashMap<>();

Expand Down Expand Up @@ -2221,6 +2214,7 @@ public Identity(String name, Map<String, String> properties) {
}
this.name = name.intern();
this.properties = ((properties != null) && (! properties.isEmpty())) ? ImmutableMap.copyOf(properties) : null;
this.cHash();
}

/**
Expand Down Expand Up @@ -2255,14 +2249,15 @@ boolean containsPropertyWithValues(String propertyName, String... values) {

@Override
public boolean equals(Object o) {
return (o instanceof Identity)
return (o instanceof Identity) &&
this.cHash() == ((Identity)o).cHash()
&& name.equals(((Identity) o).name)
&& Objects.equals(properties, ((Identity) o).properties);
}

@Override
public int hashCode() {
return name.hashCode() * 37 + ((properties != null) ? properties.hashCode() : 0);
return (int) this.cHash();
}

@Override
Expand All @@ -2273,6 +2268,17 @@ public String toString() {
public final String name;
public final Map<String, String> properties;

private transient long hash;

private long cHash() {
if (this.hash != 0) return this.hash;
long hash = (this.name.hashCode()+527383922224181L)*578967237891L;
hash ^= hash>>32; hash ^= this.properties != null ? this.properties.hashCode() : 7777777777L;
hash += 58917598759833331L; hash *= 569586253252351L;
hash ^= hash>>32;
return this.hash = (hash==0)?1:hash;
}

private static final long serialVersionUID = 1L;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ public boolean isEmpty() {
*
* @return The packed data.
*/
public PackedData pack() {
public PackedData<T> pack() {
return pack(null);
}

Expand All @@ -140,7 +140,7 @@ public PackedData pack() {
* @return The packed data.
*/
@SuppressWarnings("unchecked") // Guaranteed by Java library
public PackedData pack(T nullSubstitute) {
public PackedData<T> pack(T nullSubstitute) {
// Create the palette. We have to do this first, because otherwise we don't know how many bits the indices will
// be and therefore how big to make the data array
final Map<T, Integer> reversePalette = new HashMap<>();
Expand Down Expand Up @@ -225,7 +225,7 @@ public PackedData pack(T nullSubstitute) {
}
}
}
return new PackedData(data, palette.toArray((T[]) Array.newInstance(type, palette.size())));
return new PackedData<T>(data, palette.toArray((T[]) Array.newInstance(type, palette.size())));
}

private int offset(int x, int y, int z) {
Expand All @@ -241,7 +241,7 @@ private T substituteNull(T value, T nullSubstitute) {
private final boolean straddleLongs;
private final T[] values;

public class PackedData {
public static class PackedData <T> {
public PackedData(long[] data, T[] palette) {
this.data = data;
this.palette = palette;
Expand Down
Loading