Remove PROPERTIES_VALUES

This commit is contained in:
themode 2022-03-07 13:49:56 +01:00
parent 94406d5380
commit 29f55ee720

View File

@ -7,9 +7,9 @@ import it.unimi.dsi.fastutil.objects.Object2ObjectMaps;
import net.minestom.server.registry.Registry; import net.minestom.server.registry.Registry;
import net.minestom.server.tag.Tag; import net.minestom.server.tag.Tag;
import net.minestom.server.utils.ArrayUtils; import net.minestom.server.utils.ArrayUtils;
import net.minestom.server.utils.collection.ObjectArray;
import net.minestom.server.utils.block.BlockUtils; import net.minestom.server.utils.block.BlockUtils;
import net.minestom.server.utils.collection.MergedMap; import net.minestom.server.utils.collection.MergedMap;
import net.minestom.server.utils.collection.ObjectArray;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable; import org.jetbrains.annotations.Unmodifiable;
@ -27,9 +27,7 @@ record BlockImpl(@NotNull Registry.BlockEntry registry,
// Block state -> block object // Block state -> block object
private static final ObjectArray<Block> BLOCK_STATE_MAP = new ObjectArray<>(); private static final ObjectArray<Block> BLOCK_STATE_MAP = new ObjectArray<>();
// Block id -> valid property keys (order is important for lookup) // Block id -> valid property keys (order is important for lookup)
private static final ObjectArray<String[]> PROPERTIES_KEYS = new ObjectArray<>(); private static final ObjectArray<PropertyType[]> PROPERTIES_TYPE = new ObjectArray<>();
// Block id -> [property key -> values]
private static final ObjectArray<String[][]> PROPERTIES_VALUES = new ObjectArray<>();
// Block id -> Map<PropertiesValues, Block> // Block id -> Map<PropertiesValues, Block>
private static final ObjectArray<Map<PropertiesHolder, BlockImpl>> POSSIBLE_STATES = new ObjectArray<>(); private static final ObjectArray<Map<PropertiesHolder, BlockImpl>> POSSIBLE_STATES = new ObjectArray<>();
private static final Registry.Container<Block> CONTAINER = Registry.createContainer(Registry.Resource.BLOCKS, private static final Registry.Container<Block> CONTAINER = Registry.createContainer(Registry.Resource.BLOCKS,
@ -38,26 +36,23 @@ record BlockImpl(@NotNull Registry.BlockEntry registry,
final Registry.Properties stateObject = properties.section("states"); final Registry.Properties stateObject = properties.section("states");
// Retrieve properties // Retrieve properties
String[] keys = new String[0]; PropertyType[] propertyTypes;
String[][] values = new String[0][];
{ {
Registry.Properties stateProperties = properties.section("properties"); Registry.Properties stateProperties = properties.section("properties");
if (stateProperties != null) { if (stateProperties != null) {
final int stateCount = stateProperties.size(); final int stateCount = stateProperties.size();
keys = new String[stateCount]; propertyTypes = new PropertyType[stateCount];
values = new String[stateCount][];
int i = 0; int i = 0;
for (var entry : stateProperties) { for (var entry : stateProperties) {
final int entryIndex = i++; final var k = entry.getKey();
keys[entryIndex] = entry.getKey();
final var v = (List<String>) entry.getValue(); final var v = (List<String>) entry.getValue();
values[entryIndex] = v.toArray(String[]::new); propertyTypes[i++] = new PropertyType(k, v);
} }
} else {
propertyTypes = new PropertyType[0];
} }
} }
PROPERTIES_KEYS.set(blockId, keys); PROPERTIES_TYPE.set(blockId, propertyTypes);
PROPERTIES_VALUES.set(blockId, values);
// Retrieve block states // Retrieve block states
{ {
@ -69,17 +64,11 @@ record BlockImpl(@NotNull Registry.BlockEntry registry,
final String query = stateEntry.getKey(); final String query = stateEntry.getKey();
final var stateOverride = (Map<String, Object>) stateEntry.getValue(); final var stateOverride = (Map<String, Object>) stateEntry.getValue();
final var propertyMap = BlockUtils.parseProperties(query); final var propertyMap = BlockUtils.parseProperties(query);
assert keys.length == propertyMap.size(); assert propertyTypes.length == propertyMap.size();
byte[] propertiesArray = new byte[keys.length]; byte[] propertiesArray = new byte[propertyTypes.length];
for (var entry : propertyMap.entrySet()) { for (var entry : propertyMap.entrySet()) {
final int keyIndex = ArrayUtils.indexOf(keys, entry.getKey()); final byte keyIndex = findKeyIndex(propertyTypes, entry.getKey(), null);
if (keyIndex == -1) { final byte valueIndex = findValueIndex(propertyTypes[keyIndex], entry.getValue(), null);
throw new IllegalArgumentException("Unknown property key: " + entry.getKey());
}
final byte valueIndex = (byte) ArrayUtils.indexOf(values[keyIndex], entry.getValue());
if (valueIndex == -1) {
throw new IllegalArgumentException("Unknown property value: " + entry.getValue());
}
propertiesArray[keyIndex] = valueIndex; propertiesArray[keyIndex] = valueIndex;
} }
@ -102,8 +91,7 @@ record BlockImpl(@NotNull Registry.BlockEntry registry,
.build(); .build();
static { static {
PROPERTIES_KEYS.trim(); PROPERTIES_TYPE.trim();
PROPERTIES_VALUES.trim();
BLOCK_STATE_MAP.trim(); BLOCK_STATE_MAP.trim();
POSSIBLE_STATES.trim(); POSSIBLE_STATES.trim();
} }
@ -130,18 +118,10 @@ record BlockImpl(@NotNull Registry.BlockEntry registry,
@Override @Override
public @NotNull Block withProperty(@NotNull String property, @NotNull String value) { public @NotNull Block withProperty(@NotNull String property, @NotNull String value) {
final String[] keys = PROPERTIES_KEYS.get(id()); final PropertyType[] propertyTypes = PROPERTIES_TYPE.get(id());
final String[][] values = PROPERTIES_VALUES.get(id()); assert propertyTypes != null;
assert keys != null; final byte keyIndex = findKeyIndex(propertyTypes, property, this);
assert values != null; final byte valueIndex = findValueIndex(propertyTypes[keyIndex], value, this);
final int keyIndex = ArrayUtils.indexOf(keys, property);
if (keyIndex == -1) {
throw new IllegalArgumentException("Property " + property + " is not valid for block " + this);
}
final byte valueIndex = (byte) ArrayUtils.indexOf(values[keyIndex], value);
if (valueIndex == -1) {
throw new IllegalArgumentException("Value " + value + " is not valid for property " + property + " of block " + this);
}
var properties = this.propertiesArray.clone(); var properties = this.propertiesArray.clone();
properties[keyIndex] = valueIndex; properties[keyIndex] = valueIndex;
return compute(properties); return compute(properties);
@ -150,20 +130,12 @@ record BlockImpl(@NotNull Registry.BlockEntry registry,
@Override @Override
public @NotNull Block withProperties(@NotNull Map<@NotNull String, @NotNull String> properties) { public @NotNull Block withProperties(@NotNull Map<@NotNull String, @NotNull String> properties) {
if (properties.isEmpty()) return this; if (properties.isEmpty()) return this;
final String[] keys = PROPERTIES_KEYS.get(id()); final PropertyType[] propertyTypes = PROPERTIES_TYPE.get(id());
final String[][] values = PROPERTIES_VALUES.get(id()); assert propertyTypes != null;
assert keys != null;
assert values != null;
byte[] result = this.propertiesArray.clone(); byte[] result = this.propertiesArray.clone();
for (var entry : properties.entrySet()) { for (var entry : properties.entrySet()) {
final int keyIndex = ArrayUtils.indexOf(keys, entry.getKey()); final byte keyIndex = findKeyIndex(propertyTypes, entry.getKey(), this);
if (keyIndex == -1) { final byte valueIndex = findValueIndex(propertyTypes[keyIndex], entry.getValue(), this);
throw new IllegalArgumentException("Property " + entry.getKey() + " is not valid for block " + this);
}
final byte valueIndex = (byte) ArrayUtils.indexOf(values[keyIndex], entry.getValue());
if (valueIndex == -1) {
throw new IllegalArgumentException("Value " + entry.getValue() + " is not valid for property " + entry.getKey() + " of block " + this);
}
result[keyIndex] = valueIndex; result[keyIndex] = valueIndex;
} }
return compute(result); return compute(result);
@ -184,15 +156,17 @@ record BlockImpl(@NotNull Registry.BlockEntry registry,
@Override @Override
public @Unmodifiable @NotNull Map<String, String> properties() { public @Unmodifiable @NotNull Map<String, String> properties() {
final String[] keys = PROPERTIES_KEYS.get(id()); final PropertyType[] propertyTypes = PROPERTIES_TYPE.get(id());
final String[][] values = PROPERTIES_VALUES.get(id()); assert propertyTypes != null;
assert keys != null; final int length = propertyTypes.length;
assert values != null; String[] keys = new String[length];
String[] finalValues = new String[keys.length]; String[] values = new String[length];
for (int i = 0; i < keys.length; i++) { for (int i = 0; i < length; i++) {
finalValues[i] = values[i][propertiesArray[i]]; var property = propertyTypes[i];
keys[i] = property.key();
values[i] = property.values().get(propertiesArray[i]);
} }
return Map.class.cast(Object2ObjectMaps.unmodifiable(new Object2ObjectArrayMap<>(keys, finalValues, keys.length))); return Map.class.cast(Object2ObjectMaps.unmodifiable(new Object2ObjectArrayMap<>(keys, values, length)));
} }
@Override @Override
@ -234,6 +208,31 @@ record BlockImpl(@NotNull Registry.BlockEntry registry,
return nbt == null && handler == null ? block : new BlockImpl(block.registry(), block.propertiesArray, nbt, handler); return nbt == null && handler == null ? block : new BlockImpl(block.registry(), block.propertiesArray, nbt, handler);
} }
private static byte findKeyIndex(PropertyType[] properties, String key, BlockImpl block) {
for (byte i = 0; i < properties.length; i++) {
if (properties[i].key().equals(key)) return i;
}
if (block != null) {
throw new IllegalArgumentException("Property " + key + " is not valid for block " + block);
} else {
throw new IllegalArgumentException("Unknown property key: " + key);
}
}
private static byte findValueIndex(PropertyType propertyType, String value, BlockImpl block) {
final List<String> values = propertyType.values();
final byte index = (byte) values.indexOf(value);
if (index != -1) return index;
if (block != null) {
throw new IllegalArgumentException("Property " + propertyType.key() + " value " + value + " is not valid for block " + block);
} else {
throw new IllegalArgumentException("Unknown property value: " + value);
}
}
private record PropertyType(String key, List<String> values) {
}
private static final class PropertiesHolder { private static final class PropertiesHolder {
private final byte[] properties; private final byte[] properties;
private final int hashCode; private final int hashCode;