minecraft-source/src/net/minecraft/world/level/block/state/AbstractStateHolder.java

136 lines
5.6 KiB
Java

package net.minecraft.world.level.block.state;
import javax.annotation.Nullable;
import com.google.common.collect.Maps;
import com.google.common.collect.UnmodifiableIterator;
import com.google.common.collect.ArrayTable;
import com.google.common.collect.HashBasedTable;
import java.util.Collections;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.Iterator;
import java.util.Collection;
import com.google.common.collect.Table;
import com.google.common.collect.ImmutableMap;
import net.minecraft.world.level.block.state.properties.Property;
import java.util.Map;
import java.util.function.Function;
public abstract class AbstractStateHolder<O, S> implements StateHolder<S> {
private static final Function<Map.Entry<Property<?>, Comparable<?>>, String> PROPERTY_ENTRY_TO_STRING_FUNCTION;
protected final O owner;
private final ImmutableMap<Property<?>, Comparable<?>> values;
private Table<Property<?>, Comparable<?>, S> neighbours;
protected AbstractStateHolder(final O object, final ImmutableMap<Property<?>, Comparable<?>> immutableMap) {
this.owner = object;
this.values = immutableMap;
}
public <T extends Comparable<T>> S cycle(final Property<T> bzj) {
return this.<T, Comparable>setValue(bzj, (Comparable)AbstractStateHolder.<V>findNextInCollection((Collection<V>)bzj.getPossibleValues(), (V)this.<T>getValue((Property<T>)bzj)));
}
protected static <T> T findNextInCollection(final Collection<T> collection, final T object) {
final Iterator<T> iterator3 = collection.iterator();
while (iterator3.hasNext()) {
if (iterator3.next().equals(object)) {
if (iterator3.hasNext()) {
return iterator3.next();
}
return collection.iterator().next();
}
}
return iterator3.next();
}
@Override
public String toString() {
final StringBuilder stringBuilder2 = new StringBuilder();
stringBuilder2.append(this.owner);
if (!this.getValues().isEmpty()) {
stringBuilder2.append('[');
stringBuilder2.append(this.getValues().entrySet().stream().map(AbstractStateHolder.PROPERTY_ENTRY_TO_STRING_FUNCTION).collect(Collectors.joining(",")));
stringBuilder2.append(']');
}
return stringBuilder2.toString();
}
public Collection<Property<?>> getProperties() {
return Collections.<Property<?>>unmodifiableCollection(this.values.keySet());
}
public <T extends Comparable<T>> boolean hasProperty(final Property<T> bzj) {
return this.values.containsKey(bzj);
}
@Override
public <T extends Comparable<T>> T getValue(final Property<T> bzj) {
final Comparable<?> comparable3 = this.values.get(bzj);
if (comparable3 == null) {
throw new IllegalArgumentException("Cannot get property " + bzj + " as it does not exist in " + this.owner);
}
return bzj.getValueClass().cast(comparable3);
}
@Override
public <T extends Comparable<T>, V extends T> S setValue(final Property<T> bzj, final V comparable) {
final Comparable<?> comparable2 = this.values.get(bzj);
if (comparable2 == null) {
throw new IllegalArgumentException("Cannot set property " + bzj + " as it does not exist in " + this.owner);
}
if (comparable2 == comparable) {
return (S)this;
}
final S object5 = this.neighbours.get(bzj, comparable);
if (object5 == null) {
throw new IllegalArgumentException("Cannot set property " + bzj + " to " + comparable + " on " + this.owner + ", it is not an allowed value");
}
return object5;
}
public void populateNeighbours(final Map<Map<Property<?>, Comparable<?>>, S> map) {
if (this.neighbours != null) {
throw new IllegalStateException();
}
final Table<Property<?>, Comparable<?>, S> table3 = HashBasedTable.create();
for (final Map.Entry<Property<?>, Comparable<?>> entry5 : this.values.entrySet()) {
final Property<?> bzj6 = entry5.getKey();
for (final Comparable<?> comparable8 : bzj6.getPossibleValues()) {
if (comparable8 != entry5.getValue()) {
table3.put(bzj6, comparable8, map.get(this.makeNeighbourValues(bzj6, comparable8)));
}
}
}
this.neighbours = (table3.isEmpty() ? table3 : ArrayTable.<Property<?>, Comparable<?>, S>create(table3));
}
private Map<Property<?>, Comparable<?>> makeNeighbourValues(final Property<?> bzj, final Comparable<?> comparable) {
final Map<Property<?>, Comparable<?>> map4 = Maps.newHashMap(this.values);
map4.put(bzj, comparable);
return map4;
}
@Override
public ImmutableMap<Property<?>, Comparable<?>> getValues() {
return this.values;
}
static {
PROPERTY_ENTRY_TO_STRING_FUNCTION = new Function<Map.Entry<Property<?>, Comparable<?>>, String>() {
@Override
public String apply(@Nullable final Map.Entry<Property<?>, Comparable<?>> entry) {
if (entry == null) {
return "<NULL>";
}
final Property<?> bzj3 = entry.getKey();
return bzj3.getName() + "=" + this.getName(bzj3, entry.getValue());
}
private <T extends Comparable<T>> String getName(final Property<T> bzj, final Comparable<?> comparable) {
return bzj.getName((T)comparable);
}
};
}
}