Separate BlockBiomeWrapperPair from FullDataPointIdMap
This commit is contained in:
+3
-3
@@ -240,7 +240,7 @@ public class ConfigFileHandler
|
||||
else if (entry.getTrueValue() == null)
|
||||
{
|
||||
// TODO when can this happen?
|
||||
throw new IllegalArgumentException("Entry [" + entry.getNameAndCategory() + "] is null, this may be a problem with [" + ModInfo.NAME + "]. Please contact the authors.");
|
||||
throw new IllegalArgumentException("BlockBiomeWrapperPair [" + entry.getNameAndCategory() + "] is null, this may be a problem with [" + ModInfo.NAME + "]. Please contact the authors.");
|
||||
}
|
||||
|
||||
workConfig.set(entry.getNameAndCategory(), ConfigTypeConverters.attemptToConvertToString(entry.getType(), entry.getTrueValue()));
|
||||
@@ -287,13 +287,13 @@ public class ConfigFileHandler
|
||||
|
||||
if (entry.getTrueValue() == null)
|
||||
{
|
||||
LOGGER.warn("Entry [" + entry.getNameAndCategory() + "] returned as null from the config. Using default value.");
|
||||
LOGGER.warn("BlockBiomeWrapperPair [" + entry.getNameAndCategory() + "] returned as null from the config. Using default value.");
|
||||
entry.setWithoutFiringEvents(entry.getDefaultValue());
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Entry [" + entry.getNameAndCategory() + "] had an invalid value when loading the config. Using default value.");
|
||||
LOGGER.warn("BlockBiomeWrapperPair [" + entry.getNameAndCategory() + "] had an invalid value when loading the config. Using default value.");
|
||||
entry.setWithoutFiringEvents(entry.getDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
+151
@@ -0,0 +1,151 @@
|
||||
package com.seibel.distanthorizons.core.dataObjects;
|
||||
|
||||
import com.seibel.distanthorizons.core.dataObjects.fullData.FullDataPointIdMap;
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.util.objects.DataCorruptedException;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* A pooled compound key between the biome and blockState. <br>
|
||||
* These objects are pooled since we will need this compound key
|
||||
* many times.
|
||||
*
|
||||
* @see FullDataPointIdMap
|
||||
* @see IBlockStateWrapper
|
||||
* @see IBiomeWrapper
|
||||
*/
|
||||
public class BlockBiomeWrapperPair
|
||||
{
|
||||
private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
|
||||
|
||||
/** two levels are present so we don't need to use a key object */
|
||||
private static final ConcurrentHashMap<IBlockStateWrapper, ConcurrentHashMap<IBiomeWrapper, BlockBiomeWrapperPair>> CACHED_PAIR_BY_BIOME_BY_BLOCK = new ConcurrentHashMap<>();
|
||||
|
||||
public final IBiomeWrapper biome;
|
||||
public final IBlockStateWrapper blockState;
|
||||
|
||||
private int hashCode = 0;
|
||||
private boolean hashGenerated = false;
|
||||
private String serialString = null;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public static BlockBiomeWrapperPair get(IBlockStateWrapper blockState, IBiomeWrapper biome)
|
||||
{
|
||||
// check for existing entry
|
||||
ConcurrentHashMap<IBiomeWrapper, BlockBiomeWrapperPair> pairByBiomeWrapper = CACHED_PAIR_BY_BIOME_BY_BLOCK.get(blockState);
|
||||
if (pairByBiomeWrapper != null)
|
||||
{
|
||||
BlockBiomeWrapperPair pair = pairByBiomeWrapper.get(biome);
|
||||
if (pair != null)
|
||||
{
|
||||
return pair;
|
||||
}
|
||||
}
|
||||
|
||||
// Lazily create the inner map and new BlockBiomeWrapperPair
|
||||
return CACHED_PAIR_BY_BIOME_BY_BLOCK
|
||||
.computeIfAbsent(blockState, newBlockState -> new ConcurrentHashMap<>())
|
||||
.computeIfAbsent(biome, newBiome -> new BlockBiomeWrapperPair(biome, blockState));
|
||||
}
|
||||
private BlockBiomeWrapperPair(IBiomeWrapper biome, IBlockStateWrapper blockState)
|
||||
{
|
||||
this.biome = biome;
|
||||
this.blockState = blockState;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// overrides //
|
||||
//===========//
|
||||
|
||||
/**
|
||||
* Reminder: this hash code won't always be unique, collisions can occur;
|
||||
* because of that this hash shouldn't be the only unique identifier for this object.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
// cache the hash code to improve speed
|
||||
if (!this.hashGenerated)
|
||||
{
|
||||
this.hashCode = generateHashCode(this);
|
||||
this.hashGenerated = true;
|
||||
}
|
||||
|
||||
return this.hashCode;
|
||||
}
|
||||
private static int generateHashCode(BlockBiomeWrapperPair pair) { return generateHashCode(pair.biome, pair.blockState); }
|
||||
private static int generateHashCode(IBiomeWrapper biome, IBlockStateWrapper blockState)
|
||||
{
|
||||
final int prime = 31;
|
||||
|
||||
int result = 1;
|
||||
// the biome and blockstate hashcode should be already calculated by the time
|
||||
// we get here, so this operation should be very fast
|
||||
result = prime * result + (biome == null ? 0 : biome.hashCode());
|
||||
result = prime * result + (blockState == null ? 0 : blockState.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object otherObj)
|
||||
{
|
||||
if (otherObj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(otherObj instanceof BlockBiomeWrapperPair))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BlockBiomeWrapperPair other = (BlockBiomeWrapperPair) otherObj;
|
||||
return other.biome.getSerialString().equals(this.biome.getSerialString())
|
||||
&& other.blockState.getSerialString().equals(this.blockState.getSerialString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() { return this.serialize(); }
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// (de)serializing //
|
||||
//=================//
|
||||
|
||||
public String serialize()
|
||||
{
|
||||
if (this.serialString == null)
|
||||
{
|
||||
this.serialString = this.biome.getSerialString() + FullDataPointIdMap.BLOCK_STATE_SEPARATOR_STRING + this.blockState.getSerialString();
|
||||
}
|
||||
|
||||
return this.serialString;
|
||||
}
|
||||
|
||||
public static BlockBiomeWrapperPair deserialize(String str, ILevelWrapper levelWrapper) throws DataCorruptedException
|
||||
{
|
||||
int separatorIndex = str.indexOf(FullDataPointIdMap.BLOCK_STATE_SEPARATOR_STRING);
|
||||
if (separatorIndex == -1)
|
||||
{
|
||||
throw new DataCorruptedException("Failed to deserialize BiomeBlockStateEntry ["+str+"], unable to find separator.");
|
||||
}
|
||||
|
||||
IBiomeWrapper biome = WRAPPER_FACTORY.deserializeBiomeWrapperOrGetDefault(str.substring(0, separatorIndex), levelWrapper);
|
||||
IBlockStateWrapper blockState = WRAPPER_FACTORY.deserializeBlockStateWrapperOrGetDefault(str.substring(separatorIndex+FullDataPointIdMap.BLOCK_STATE_SEPARATOR_STRING.length()), levelWrapper);
|
||||
return BlockBiomeWrapperPair.get(blockState, biome);
|
||||
}
|
||||
|
||||
}
|
||||
+52
-190
@@ -19,7 +19,7 @@
|
||||
|
||||
package com.seibel.distanthorizons.core.dataObjects.fullData;
|
||||
|
||||
import com.seibel.distanthorizons.core.dependencyInjection.SingletonInjector;
|
||||
import com.seibel.distanthorizons.core.dataObjects.BlockBiomeWrapperPair;
|
||||
import com.seibel.distanthorizons.core.logging.DhLoggerBuilder;
|
||||
import com.seibel.distanthorizons.core.pos.DhSectionPos;
|
||||
import com.seibel.distanthorizons.core.util.LodUtil;
|
||||
@@ -28,9 +28,7 @@ import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataInputStrea
|
||||
import com.seibel.distanthorizons.core.util.objects.dataStreams.DhDataOutputStream;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.block.IBlockStateWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.IBiomeWrapper;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.IWrapperFactory;
|
||||
import com.seibel.distanthorizons.core.wrapperInterfaces.world.ILevelWrapper;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import com.seibel.distanthorizons.core.logging.DhLogger;
|
||||
|
||||
import java.io.*;
|
||||
@@ -60,15 +58,15 @@ public class FullDataPointIdMap
|
||||
*/
|
||||
private static final boolean RUN_SERIALIZATION_DUPLICATE_VALIDATION = false;
|
||||
/** Distant Horizons - Block State Wrapper */
|
||||
private static final String BLOCK_STATE_SEPARATOR_STRING = "_DH-BSW_";
|
||||
public static final String BLOCK_STATE_SEPARATOR_STRING = "_DH-BSW_";
|
||||
|
||||
|
||||
/** should only be used for debugging */
|
||||
private long pos;
|
||||
|
||||
/** The index should be the same as the Entry's ID */
|
||||
private final ArrayList<Entry> entryList = new ArrayList<>();
|
||||
private final ConcurrentHashMap<Entry, Integer> idMap = new ConcurrentHashMap<>();
|
||||
/** The index should be the same as the BlockBiomeWrapperPair's ID */
|
||||
private final ArrayList<BlockBiomeWrapperPair> blockBiomePairList = new ArrayList<>();
|
||||
private final ConcurrentHashMap<BlockBiomeWrapperPair, Integer> idMap = new ConcurrentHashMap<>();
|
||||
|
||||
private int cachedHashCode = 0;
|
||||
|
||||
@@ -90,28 +88,28 @@ public class FullDataPointIdMap
|
||||
public IBiomeWrapper getBiomeWrapper(int id) throws IndexOutOfBoundsException { return this.getEntry(id).biome; }
|
||||
/** @see FullDataPointIdMap#getEntry(int) */
|
||||
public IBlockStateWrapper getBlockStateWrapper(int id) throws IndexOutOfBoundsException { return this.getEntry(id).blockState; }
|
||||
/** @throws IndexOutOfBoundsException if the given ID isn't in the {@link FullDataPointIdMap#entryList} */
|
||||
private Entry getEntry(int id) throws IndexOutOfBoundsException
|
||||
/** @throws IndexOutOfBoundsException if the given ID isn't in the {@link FullDataPointIdMap#blockBiomePairList} */
|
||||
private BlockBiomeWrapperPair getEntry(int id) throws IndexOutOfBoundsException
|
||||
{
|
||||
Entry entry;
|
||||
BlockBiomeWrapperPair pair;
|
||||
try
|
||||
{
|
||||
entry = this.entryList.get(id);
|
||||
pair = this.blockBiomePairList.get(id);
|
||||
}
|
||||
catch (IndexOutOfBoundsException e)
|
||||
{
|
||||
throw new IndexOutOfBoundsException("FullData ID Map out of sync for pos: "+DhSectionPos.toString(this.pos)+". ID: ["+id+"] greater than the number of known ID's: ["+this.entryList.size()+"].");
|
||||
throw new IndexOutOfBoundsException("FullData ID Map out of sync for pos: "+DhSectionPos.toString(this.pos)+". ID: ["+id+"] greater than the number of known ID's: ["+this.blockBiomePairList.size()+"].");
|
||||
}
|
||||
|
||||
return entry;
|
||||
return pair;
|
||||
}
|
||||
|
||||
|
||||
/** @return -1 if the list is empty */
|
||||
public int getMaxValidId() { return this.entryList.size() - 1; }
|
||||
public int size() { return this.entryList.size(); }
|
||||
public int getMaxValidId() { return this.blockBiomePairList.size() - 1; }
|
||||
public int size() { return this.blockBiomePairList.size(); }
|
||||
|
||||
public boolean isEmpty() { return this.entryList.isEmpty(); }
|
||||
public boolean isEmpty() { return this.blockBiomePairList.isEmpty(); }
|
||||
|
||||
public long getPos() { return this.pos; }
|
||||
|
||||
@@ -125,11 +123,11 @@ public class FullDataPointIdMap
|
||||
* If an entry with the given values already exists nothing will
|
||||
* be added but the existing item's ID will still be returned.
|
||||
*/
|
||||
public int addIfNotPresentAndGetId(IBiomeWrapper biome, IBlockStateWrapper blockState) { return this.addIfNotPresentAndGetId(Entry.getEntry(biome, blockState)); }
|
||||
private int addIfNotPresentAndGetId(Entry biomeBlockStateEntry)
|
||||
public int addIfNotPresentAndGetId(IBiomeWrapper biome, IBlockStateWrapper blockState) { return this.addIfNotPresentAndGetId(BlockBiomeWrapperPair.get(blockState, biome)); }
|
||||
private int addIfNotPresentAndGetId(BlockBiomeWrapperPair pair)
|
||||
{
|
||||
// try getting the existing ID
|
||||
Integer nullableId = this.idMap.get(biomeBlockStateEntry);
|
||||
Integer nullableId = this.idMap.get(pair);
|
||||
if (nullableId != null)
|
||||
{
|
||||
return nullableId;
|
||||
@@ -137,7 +135,7 @@ public class FullDataPointIdMap
|
||||
|
||||
|
||||
// create the new ID
|
||||
return this.idMap.compute(biomeBlockStateEntry, (Entry newBiomeBlockStateEntry, Integer currentId) ->
|
||||
return this.idMap.compute(pair, (BlockBiomeWrapperPair newPair, Integer currentId) ->
|
||||
{
|
||||
if (currentId != null)
|
||||
{
|
||||
@@ -146,8 +144,8 @@ public class FullDataPointIdMap
|
||||
|
||||
|
||||
// Add the new ID
|
||||
currentId = this.entryList.size();
|
||||
this.entryList.add(biomeBlockStateEntry);
|
||||
currentId = this.blockBiomePairList.size();
|
||||
this.blockBiomePairList.add(newPair);
|
||||
|
||||
// invalidate the cached hash code
|
||||
this.cachedHashCode = 0;
|
||||
@@ -157,7 +155,7 @@ public class FullDataPointIdMap
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds every {@link Entry} from inputMap into this map. <br>
|
||||
* Adds every {@link BlockBiomeWrapperPair} from inputMap into this map. <br>
|
||||
* Allows duplicate entries. <br><br>
|
||||
*
|
||||
* Allowing duplicate entries should be done if a datasource is just being read in and
|
||||
@@ -167,19 +165,19 @@ public class FullDataPointIdMap
|
||||
*/
|
||||
public void addAll(FullDataPointIdMap inputMap)
|
||||
{
|
||||
ArrayList<Entry> entriesToMerge = inputMap.entryList;
|
||||
for (int i = 0; i < entriesToMerge.size(); i++)
|
||||
ArrayList<BlockBiomeWrapperPair> pairsToMerge = inputMap.blockBiomePairList;
|
||||
for (int i = 0; i < pairsToMerge.size(); i++)
|
||||
{
|
||||
Entry entity = entriesToMerge.get(i);
|
||||
this.add(entity);
|
||||
BlockBiomeWrapperPair pair = pairsToMerge.get(i);
|
||||
this.add(pair);
|
||||
}
|
||||
}
|
||||
/** allows for adding duplicate {@link Entry} */
|
||||
private void add(Entry biomeBlockStateEntry)
|
||||
/** allows for adding duplicate {@link BlockBiomeWrapperPair} */
|
||||
private void add(BlockBiomeWrapperPair pair)
|
||||
{
|
||||
int id = this.entryList.size();
|
||||
this.entryList.add(biomeBlockStateEntry);
|
||||
this.idMap.put(biomeBlockStateEntry, id);
|
||||
int id = this.blockBiomePairList.size();
|
||||
this.blockBiomePairList.add(pair);
|
||||
this.idMap.put(pair, id);
|
||||
|
||||
// invalidate the cached hash code
|
||||
this.cachedHashCode = 0;
|
||||
@@ -196,23 +194,23 @@ public class FullDataPointIdMap
|
||||
*/
|
||||
public int[] mergeAndReturnRemappedEntityIds(FullDataPointIdMap inputMap)
|
||||
{
|
||||
ArrayList<Entry> entriesToMerge = inputMap.entryList;
|
||||
int[] remappedEntryIds = new int[entriesToMerge.size()];
|
||||
ArrayList<BlockBiomeWrapperPair> entriesToMerge = inputMap.blockBiomePairList;
|
||||
int[] remappedPairIds = new int[entriesToMerge.size()];
|
||||
for (int i = 0; i < entriesToMerge.size(); i++)
|
||||
{
|
||||
Entry entity = entriesToMerge.get(i);
|
||||
BlockBiomeWrapperPair entity = entriesToMerge.get(i);
|
||||
int id = this.addIfNotPresentAndGetId(entity);
|
||||
remappedEntryIds[i] = id;
|
||||
remappedPairIds[i] = id;
|
||||
}
|
||||
|
||||
return remappedEntryIds;
|
||||
return remappedPairIds;
|
||||
}
|
||||
|
||||
/** Should only be used if this map is going to be reused, otherwise bad things will happen. */
|
||||
public void clear(long pos)
|
||||
{
|
||||
this.pos = pos;
|
||||
this.entryList.clear();
|
||||
this.blockBiomePairList.clear();
|
||||
this.idMap.clear();
|
||||
this.cachedHashCode = 0;
|
||||
}
|
||||
@@ -226,27 +224,27 @@ public class FullDataPointIdMap
|
||||
/** Serializes all contained entries into the given stream, formatted in UTF */
|
||||
public void serialize(DhDataOutputStream outputStream) throws IOException
|
||||
{
|
||||
outputStream.writeInt(this.entryList.size());
|
||||
outputStream.writeInt(this.blockBiomePairList.size());
|
||||
|
||||
// only used when debugging
|
||||
HashMap<String, FullDataPointIdMap.Entry> dataPointEntryBySerialization = new HashMap<>();
|
||||
HashMap<String, BlockBiomeWrapperPair> dataPointEntryBySerialization = new HashMap<>();
|
||||
|
||||
for (Entry entry : this.entryList)
|
||||
for (BlockBiomeWrapperPair pair : this.blockBiomePairList)
|
||||
{
|
||||
String entryString = entry.serialize();
|
||||
String entryString = pair.serialize();
|
||||
outputStream.writeUTF(entryString);
|
||||
|
||||
if (RUN_SERIALIZATION_DUPLICATE_VALIDATION)
|
||||
{
|
||||
if (dataPointEntryBySerialization.containsKey(entryString))
|
||||
{
|
||||
LOGGER.error("Duplicate serialized entry found with serial: " + entryString);
|
||||
LOGGER.error("Duplicate serialized pair found with serial: " + entryString);
|
||||
}
|
||||
if (dataPointEntryBySerialization.containsValue(entry))
|
||||
if (dataPointEntryBySerialization.containsValue(pair))
|
||||
{
|
||||
LOGGER.error("Duplicate serialized entry found with value: " + entry.serialize());
|
||||
LOGGER.error("Duplicate serialized pair found with value: " + pair.serialize());
|
||||
}
|
||||
dataPointEntryBySerialization.put(entryString, entry);
|
||||
dataPointEntryBySerialization.put(entryString, pair);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -262,7 +260,7 @@ public class FullDataPointIdMap
|
||||
|
||||
|
||||
// only used when debugging
|
||||
HashMap<String, FullDataPointIdMap.Entry> dataPointEntryBySerialization = new HashMap<>();
|
||||
HashMap<String, BlockBiomeWrapperPair> dataPointEntryBySerialization = new HashMap<>();
|
||||
|
||||
FullDataPointIdMap newMap = new FullDataPointIdMap(pos);
|
||||
for (int i = 0; i < entityCount; i++)
|
||||
@@ -275,8 +273,8 @@ public class FullDataPointIdMap
|
||||
|
||||
|
||||
String entryString = inputStream.readUTF();
|
||||
Entry newEntry = Entry.deserialize(entryString, levelWrapper);
|
||||
newMap.entryList.add(newEntry);
|
||||
BlockBiomeWrapperPair newPair = BlockBiomeWrapperPair.deserialize(entryString, levelWrapper);
|
||||
newMap.blockBiomePairList.add(newPair);
|
||||
|
||||
if (RUN_SERIALIZATION_DUPLICATE_VALIDATION)
|
||||
{
|
||||
@@ -284,11 +282,11 @@ public class FullDataPointIdMap
|
||||
{
|
||||
LOGGER.error("Duplicate deserialized entry found with serial: " + entryString);
|
||||
}
|
||||
if (dataPointEntryBySerialization.containsValue(newEntry))
|
||||
if (dataPointEntryBySerialization.containsValue(newPair))
|
||||
{
|
||||
LOGGER.error("Duplicate deserialized entry found with value: " + newEntry.serialize());
|
||||
LOGGER.error("Duplicate deserialized entry found with value: " + newPair.serialize());
|
||||
}
|
||||
dataPointEntryBySerialization.put(entryString, newEntry);
|
||||
dataPointEntryBySerialization.put(entryString, newPair);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,149 +332,13 @@ public class FullDataPointIdMap
|
||||
private void generateHashCode()
|
||||
{
|
||||
int result = DhSectionPos.hashCode(this.pos);
|
||||
for (int i = 0; i < this.entryList.size(); i++)
|
||||
for (int i = 0; i < this.blockBiomePairList.size(); i++)
|
||||
{
|
||||
result = 31 * result + this.entryList.hashCode();
|
||||
result = 31 * result + this.blockBiomePairList.hashCode();
|
||||
}
|
||||
this.cachedHashCode = result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//==============//
|
||||
// helper class //
|
||||
//==============//
|
||||
|
||||
private static final class Entry
|
||||
{
|
||||
private static final IWrapperFactory WRAPPER_FACTORY = SingletonInjector.INSTANCE.get(IWrapperFactory.class);
|
||||
|
||||
/** two levels are present so we don't need to use a key object */
|
||||
private static final ConcurrentHashMap<IBiomeWrapper, ConcurrentHashMap<IBlockStateWrapper, Entry>> ENTRY_BY_BLOCKSTATE_BY_BIOMEWRAPPER = new ConcurrentHashMap<>();
|
||||
|
||||
public final IBiomeWrapper biome;
|
||||
public final IBlockStateWrapper blockState;
|
||||
|
||||
private int hashCode = 0;
|
||||
private boolean hashGenerated = false;
|
||||
private String serialString = null;
|
||||
|
||||
|
||||
|
||||
//=============//
|
||||
// constructor //
|
||||
//=============//
|
||||
|
||||
public static Entry getEntry(IBiomeWrapper biome, IBlockStateWrapper blockState)
|
||||
{
|
||||
// check for existing entry
|
||||
ConcurrentHashMap<IBlockStateWrapper, Entry> entryByBlockState = ENTRY_BY_BLOCKSTATE_BY_BIOMEWRAPPER.get(biome);
|
||||
if (entryByBlockState != null)
|
||||
{
|
||||
Entry entry = entryByBlockState.get(blockState);
|
||||
if (entry != null)
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
// Lazily create the inner map and new Entry
|
||||
return ENTRY_BY_BLOCKSTATE_BY_BIOMEWRAPPER
|
||||
.computeIfAbsent(biome, newBiome -> new ConcurrentHashMap<>())
|
||||
.computeIfAbsent(blockState, newBlockState -> new Entry(biome, blockState));
|
||||
}
|
||||
private Entry(IBiomeWrapper biome, IBlockStateWrapper blockState)
|
||||
{
|
||||
this.biome = biome;
|
||||
this.blockState = blockState;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//===========//
|
||||
// overrides //
|
||||
//===========//
|
||||
|
||||
/**
|
||||
* Reminder: this hash code won't always be unique, collisions can occur;
|
||||
* because of that this hash shouldn't be the only unique identifier for this object.
|
||||
*/
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
// cache the hash code to improve speed
|
||||
if (!this.hashGenerated)
|
||||
{
|
||||
this.hashCode = generateHashCode(this);
|
||||
this.hashGenerated = true;
|
||||
}
|
||||
|
||||
return this.hashCode;
|
||||
}
|
||||
private static int generateHashCode(Entry entry) { return generateHashCode(entry.biome, entry.blockState); }
|
||||
private static int generateHashCode(IBiomeWrapper biome, IBlockStateWrapper blockState)
|
||||
{
|
||||
final int prime = 31;
|
||||
|
||||
int result = 1;
|
||||
// the biome and blockstate hashcode should be already calculated by the time
|
||||
// we get here, so this operation should be very fast
|
||||
result = prime * result + (biome == null ? 0 : biome.hashCode());
|
||||
result = prime * result + (blockState == null ? 0 : blockState.hashCode());
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object otherObj)
|
||||
{
|
||||
if (otherObj == this)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(otherObj instanceof Entry))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Entry other = (Entry) otherObj;
|
||||
return other.biome.getSerialString().equals(this.biome.getSerialString())
|
||||
&& other.blockState.getSerialString().equals(this.blockState.getSerialString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() { return this.serialize(); }
|
||||
|
||||
|
||||
|
||||
//=================//
|
||||
// (de)serializing //
|
||||
//=================//
|
||||
|
||||
public String serialize()
|
||||
{
|
||||
if (this.serialString == null)
|
||||
{
|
||||
this.serialString = this.biome.getSerialString() + BLOCK_STATE_SEPARATOR_STRING + this.blockState.getSerialString();
|
||||
}
|
||||
|
||||
return this.serialString;
|
||||
}
|
||||
|
||||
public static Entry deserialize(String str, ILevelWrapper levelWrapper) throws DataCorruptedException
|
||||
{
|
||||
int separatorIndex = str.indexOf(BLOCK_STATE_SEPARATOR_STRING);
|
||||
if (separatorIndex == -1)
|
||||
{
|
||||
throw new DataCorruptedException("Failed to deserialize BiomeBlockStateEntry ["+str+"], unable to find separator.");
|
||||
}
|
||||
|
||||
IBiomeWrapper biome = WRAPPER_FACTORY.deserializeBiomeWrapperOrGetDefault(str.substring(0, separatorIndex), levelWrapper);
|
||||
IBlockStateWrapper blockState = WRAPPER_FACTORY.deserializeBlockStateWrapperOrGetDefault(str.substring(separatorIndex+BLOCK_STATE_SEPARATOR_STRING.length()), levelWrapper);
|
||||
return Entry.getEntry(biome, blockState);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user