package net.minecraft.world.level.block.state.properties; import com.google.common.base.MoreObjects; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; import com.mojang.serialization.DynamicOps; import java.util.List; import java.util.Optional; import java.util.stream.Stream; import javax.annotation.Nullable; import net.minecraft.world.level.block.state.StateHolder; public abstract class Property> { private final Class clazz; private final String name; @Nullable private Integer hashCode; private final Codec codec = Codec.STRING .comapFlatMap( p_61698_ -> this.getValue(p_61698_) .map(DataResult::success) .orElseGet(() -> DataResult.error(() -> "Unable to read property: " + this + " with value: " + p_61698_)), this::getName ); private final Codec> valueCodec = this.codec.xmap(this::value, Property.Value::value); protected Property(String p_61692_, Class p_61693_) { this.clazz = p_61693_; this.name = p_61692_; } public Property.Value value(T p_61700_) { return new Property.Value<>(this, p_61700_); } public Property.Value value(StateHolder p_61695_) { return new Property.Value<>(this, p_61695_.getValue(this)); } public Stream> getAllValues() { return this.getPossibleValues().stream().map(this::value); } public Codec codec() { return this.codec; } public Codec> valueCodec() { return this.valueCodec; } public String getName() { return this.name; } public Class getValueClass() { return this.clazz; } public abstract List getPossibleValues(); public abstract String getName(T p_61696_); public abstract Optional getValue(String p_61701_); public abstract int getInternalIndex(T p_366384_); @Override public String toString() { return MoreObjects.toStringHelper(this).add("name", this.name).add("clazz", this.clazz).add("values", this.getPossibleValues()).toString(); } @Override public boolean equals(Object p_61707_) { if (this == p_61707_) { return true; } else { return !(p_61707_ instanceof Property property) ? false : this.clazz.equals(property.clazz) && this.name.equals(property.name); } } @Override public final int hashCode() { if (this.hashCode == null) { this.hashCode = this.generateHashCode(); } return this.hashCode; } public int generateHashCode() { return 31 * this.clazz.hashCode() + this.name.hashCode(); } public > DataResult parseValue(DynamicOps p_156032_, S p_156033_, U p_156034_) { DataResult dataresult = this.codec.parse(p_156032_, p_156034_); return dataresult.map(p_156030_ -> p_156033_.setValue(this, p_156030_)).setPartial(p_156033_); } public record Value>(Property property, T value) { public Value(Property property, T value) { if (!property.getPossibleValues().contains(value)) { throw new IllegalArgumentException("Value " + value + " does not belong to property " + property); } else { this.property = property; this.value = value; } } @Override public String toString() { return this.property.getName() + "=" + this.property.getName(this.value); } } }