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 implements StateHolder { private static final Function, Comparable>, String> PROPERTY_ENTRY_TO_STRING_FUNCTION; protected final O owner; private final ImmutableMap, Comparable> values; private Table, Comparable, S> neighbours; protected AbstractStateHolder(final O object, final ImmutableMap, Comparable> immutableMap) { this.owner = object; this.values = immutableMap; } public > S cycle(final Property bzj) { return this.setValue(bzj, (Comparable)AbstractStateHolder.findNextInCollection((Collection)bzj.getPossibleValues(), (V)this.getValue((Property)bzj))); } protected static T findNextInCollection(final Collection collection, final T object) { final Iterator 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> getProperties() { return Collections.>unmodifiableCollection(this.values.keySet()); } public > boolean hasProperty(final Property bzj) { return this.values.containsKey(bzj); } @Override public > T getValue(final Property 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 , V extends T> S setValue(final Property 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, Comparable>, S> map) { if (this.neighbours != null) { throw new IllegalStateException(); } final Table, Comparable, S> table3 = HashBasedTable.create(); for (final Map.Entry, 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., Comparable, S>create(table3)); } private Map, Comparable> makeNeighbourValues(final Property bzj, final Comparable comparable) { final Map, Comparable> map4 = Maps.newHashMap(this.values); map4.put(bzj, comparable); return map4; } @Override public ImmutableMap, Comparable> getValues() { return this.values; } static { PROPERTY_ENTRY_TO_STRING_FUNCTION = new Function, Comparable>, String>() { @Override public String apply(@Nullable final Map.Entry, Comparable> entry) { if (entry == null) { return ""; } final Property bzj3 = entry.getKey(); return bzj3.getName() + "=" + this.getName(bzj3, entry.getValue()); } private > String getName(final Property bzj, final Comparable comparable) { return bzj.getName((T)comparable); } }; } }