package net.minecraft.data.models.blockstates; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Maps; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; import net.minecraft.world.level.block.state.properties.Property; public abstract class PropertyDispatch { private final Map> values = Maps.>newHashMap(); protected void putValue(Selector selector, List values) { List list = (List)this.values.put(selector, values); if (list != null) { throw new IllegalStateException("Value " + selector + " is already defined"); } } Map> getEntries() { this.verifyComplete(); return ImmutableMap.copyOf(this.values); } private void verifyComplete() { List> list = this.getDefinedProperties(); Stream stream = Stream.of(Selector.empty()); for (Property property : list) { stream = stream.flatMap(selector -> property.getAllValues().map(selector::extend)); } List list2 = (List)stream.filter(selector -> !this.values.containsKey(selector)).collect(Collectors.toList()); if (!list2.isEmpty()) { throw new IllegalStateException("Missing definition for properties: " + list2); } } abstract List> getDefinedProperties(); public static > PropertyDispatch.C1 property(Property property1) { return new PropertyDispatch.C1<>(property1); } public static , T2 extends Comparable> PropertyDispatch.C2 properties(Property property1, Property property2) { return new PropertyDispatch.C2<>(property1, property2); } public static , T2 extends Comparable, T3 extends Comparable> PropertyDispatch.C3 properties( Property property1, Property property2, Property property3 ) { return new PropertyDispatch.C3<>(property1, property2, property3); } public static , T2 extends Comparable, T3 extends Comparable, T4 extends Comparable> PropertyDispatch.C4 properties( Property property1, Property property2, Property property3, Property property4 ) { return new PropertyDispatch.C4<>(property1, property2, property3, property4); } public static , T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, T5 extends Comparable> PropertyDispatch.C5 properties( Property property1, Property property2, Property property3, Property property4, Property property5 ) { return new PropertyDispatch.C5<>(property1, property2, property3, property4, property5); } public static class C1> extends PropertyDispatch { private final Property property1; C1(Property property1) { this.property1 = property1; } @Override public List> getDefinedProperties() { return ImmutableList.of(this.property1); } public PropertyDispatch.C1 select(T1 propertyValue, List variants) { Selector selector = Selector.of(this.property1.value(propertyValue)); this.putValue(selector, variants); return this; } public PropertyDispatch.C1 select(T1 propertyValue, Variant variant) { return this.select(propertyValue, Collections.singletonList(variant)); } public PropertyDispatch generate(Function propertyValueToVariantMapper) { this.property1.getPossibleValues().forEach(comparable -> this.select((T1)comparable, (Variant)propertyValueToVariantMapper.apply(comparable))); return this; } public PropertyDispatch generateList(Function> propertyValueToVariantsMapper) { this.property1.getPossibleValues().forEach(comparable -> this.select((T1)comparable, (List)propertyValueToVariantsMapper.apply(comparable))); return this; } } public static class C2, T2 extends Comparable> extends PropertyDispatch { private final Property property1; private final Property property2; C2(Property property1, Property property2) { this.property1 = property1; this.property2 = property2; } @Override public List> getDefinedProperties() { return ImmutableList.of(this.property1, this.property2); } public PropertyDispatch.C2 select(T1 property1Value, T2 property2Value, List variants) { Selector selector = Selector.of(this.property1.value(property1Value), this.property2.value(property2Value)); this.putValue(selector, variants); return this; } public PropertyDispatch.C2 select(T1 property1Value, T2 property2Value, Variant variant) { return this.select(property1Value, property2Value, Collections.singletonList(variant)); } public PropertyDispatch generate(BiFunction propertyValuesToVariantMapper) { this.property1 .getPossibleValues() .forEach( comparable -> this.property2 .getPossibleValues() .forEach(comparable2 -> this.select((T1)comparable, (T2)comparable2, (Variant)propertyValuesToVariantMapper.apply(comparable, comparable2))) ); return this; } public PropertyDispatch generateList(BiFunction> propertyValuesToVariantsMapper) { this.property1 .getPossibleValues() .forEach( comparable -> this.property2 .getPossibleValues() .forEach(comparable2 -> this.select((T1)comparable, (T2)comparable2, (List)propertyValuesToVariantsMapper.apply(comparable, comparable2))) ); return this; } } public static class C3, T2 extends Comparable, T3 extends Comparable> extends PropertyDispatch { private final Property property1; private final Property property2; private final Property property3; C3(Property property1, Property property2, Property property3) { this.property1 = property1; this.property2 = property2; this.property3 = property3; } @Override public List> getDefinedProperties() { return ImmutableList.of(this.property1, this.property2, this.property3); } public PropertyDispatch.C3 select(T1 property1Value, T2 property2Value, T3 property3Value, List variants) { Selector selector = Selector.of(this.property1.value(property1Value), this.property2.value(property2Value), this.property3.value(property3Value)); this.putValue(selector, variants); return this; } public PropertyDispatch.C3 select(T1 property1Value, T2 property2Value, T3 property3Value, Variant variant) { return this.select(property1Value, property2Value, property3Value, Collections.singletonList(variant)); } public PropertyDispatch generate(PropertyDispatch.TriFunction propertyValuesToVariantMapper) { this.property1 .getPossibleValues() .forEach( comparable -> this.property2 .getPossibleValues() .forEach( comparable2 -> this.property3 .getPossibleValues() .forEach( comparable3 -> this.select( (T1)comparable, (T2)comparable2, (T3)comparable3, propertyValuesToVariantMapper.apply((T1)comparable, (T2)comparable2, (T3)comparable3) ) ) ) ); return this; } public PropertyDispatch generateList(PropertyDispatch.TriFunction> propertyValuesToVariantsMapper) { this.property1 .getPossibleValues() .forEach( comparable -> this.property2 .getPossibleValues() .forEach( comparable2 -> this.property3 .getPossibleValues() .forEach( comparable3 -> this.select( (T1)comparable, (T2)comparable2, (T3)comparable3, propertyValuesToVariantsMapper.apply((T1)comparable, (T2)comparable2, (T3)comparable3) ) ) ) ); return this; } } public static class C4, T2 extends Comparable, T3 extends Comparable, T4 extends Comparable> extends PropertyDispatch { private final Property property1; private final Property property2; private final Property property3; private final Property property4; C4(Property property1, Property property2, Property property3, Property property4) { this.property1 = property1; this.property2 = property2; this.property3 = property3; this.property4 = property4; } @Override public List> getDefinedProperties() { return ImmutableList.of(this.property1, this.property2, this.property3, this.property4); } public PropertyDispatch.C4 select(T1 property1Value, T2 property2Value, T3 property3Value, T4 property4Value, List variants) { Selector selector = Selector.of( this.property1.value(property1Value), this.property2.value(property2Value), this.property3.value(property3Value), this.property4.value(property4Value) ); this.putValue(selector, variants); return this; } public PropertyDispatch.C4 select(T1 property1Value, T2 property2Value, T3 property3Value, T4 property4Value, Variant variant) { return this.select(property1Value, property2Value, property3Value, property4Value, Collections.singletonList(variant)); } public PropertyDispatch generate(PropertyDispatch.QuadFunction propertyValuesToVariantMapper) { this.property1 .getPossibleValues() .forEach( comparable -> this.property2 .getPossibleValues() .forEach( comparable2 -> this.property3 .getPossibleValues() .forEach( comparable3 -> this.property4 .getPossibleValues() .forEach( comparable4 -> this.select( (T1)comparable, (T2)comparable2, (T3)comparable3, (T4)comparable4, propertyValuesToVariantMapper.apply((T1)comparable, (T2)comparable2, (T3)comparable3, (T4)comparable4) ) ) ) ) ); return this; } public PropertyDispatch generateList(PropertyDispatch.QuadFunction> propertyValuesToVariantsMapper) { this.property1 .getPossibleValues() .forEach( comparable -> this.property2 .getPossibleValues() .forEach( comparable2 -> this.property3 .getPossibleValues() .forEach( comparable3 -> this.property4 .getPossibleValues() .forEach( comparable4 -> this.select( (T1)comparable, (T2)comparable2, (T3)comparable3, (T4)comparable4, propertyValuesToVariantsMapper.apply((T1)comparable, (T2)comparable2, (T3)comparable3, (T4)comparable4) ) ) ) ) ); return this; } } public static class C5, T2 extends Comparable, T3 extends Comparable, T4 extends Comparable, T5 extends Comparable> extends PropertyDispatch { private final Property property1; private final Property property2; private final Property property3; private final Property property4; private final Property property5; C5(Property property1, Property property2, Property property3, Property property4, Property property5) { this.property1 = property1; this.property2 = property2; this.property3 = property3; this.property4 = property4; this.property5 = property5; } @Override public List> getDefinedProperties() { return ImmutableList.of(this.property1, this.property2, this.property3, this.property4, this.property5); } public PropertyDispatch.C5 select( T1 property1Value, T2 property2Value, T3 property3Value, T4 property4Value, T5 property5Value, List variants ) { Selector selector = Selector.of( this.property1.value(property1Value), this.property2.value(property2Value), this.property3.value(property3Value), this.property4.value(property4Value), this.property5.value(property5Value) ); this.putValue(selector, variants); return this; } public PropertyDispatch.C5 select( T1 property1Value, T2 property2Value, T3 property3Value, T4 property4Value, T5 property5Value, Variant variant ) { return this.select(property1Value, property2Value, property3Value, property4Value, property5Value, Collections.singletonList(variant)); } public PropertyDispatch generate(PropertyDispatch.PentaFunction propertyValuesToVariantMapper) { this.property1 .getPossibleValues() .forEach( comparable -> this.property2 .getPossibleValues() .forEach( comparable2 -> this.property3 .getPossibleValues() .forEach( comparable3 -> this.property4 .getPossibleValues() .forEach( comparable4 -> this.property5 .getPossibleValues() .forEach( comparable5 -> this.select( (T1)comparable, (T2)comparable2, (T3)comparable3, (T4)comparable4, (T5)comparable5, propertyValuesToVariantMapper.apply((T1)comparable, (T2)comparable2, (T3)comparable3, (T4)comparable4, (T5)comparable5) ) ) ) ) ) ); return this; } public PropertyDispatch generateList(PropertyDispatch.PentaFunction> propertyValuesToVariantsMapper) { this.property1 .getPossibleValues() .forEach( comparable -> this.property2 .getPossibleValues() .forEach( comparable2 -> this.property3 .getPossibleValues() .forEach( comparable3 -> this.property4 .getPossibleValues() .forEach( comparable4 -> this.property5 .getPossibleValues() .forEach( comparable5 -> this.select( (T1)comparable, (T2)comparable2, (T3)comparable3, (T4)comparable4, (T5)comparable5, propertyValuesToVariantsMapper.apply((T1)comparable, (T2)comparable2, (T3)comparable3, (T4)comparable4, (T5)comparable5) ) ) ) ) ) ); return this; } } @FunctionalInterface public interface PentaFunction { R apply(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5); } @FunctionalInterface public interface QuadFunction { R apply(P1 p1, P2 p2, P3 p3, P4 p4); } @FunctionalInterface public interface TriFunction { R apply(P1 object, P2 object2, P3 object3); } }