KeyValueCondition.java
net.minecraft.client.renderer.block.dispatch.multipart.KeyValueCondition
信息
- 全限定名:net.minecraft.client.renderer.block.dispatch.multipart.KeyValueCondition
- 类型:public record
- 包:net.minecraft.client.renderer.block.dispatch.multipart
- 源码路径:src/main/java/net/minecraft/client/renderer/block/dispatch/multipart/KeyValueCondition.java
- 起始行号:L25
- 实现:Condition
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L26 - 说明:
TODO
- 类型:
-
CODEC- 类型:
Codec<KeyValueCondition> - 修饰符:
public static final - 源码定位:
L27 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.client.renderer.block.dispatch.multipart.KeyValueCondition.Term- 类型:
record - 修饰符:
public - 源码定位:
L47 - 说明:
TODO
- 类型:
-
net.minecraft.client.renderer.block.dispatch.multipart.KeyValueCondition.Terms- 类型:
record - 修饰符:
public - 源码定位:
L70 - 说明:
TODO
- 类型:
构造器
- 无
方法
下面的方法块按源码顺序生成。
public <O,S extends StateHolder<O,S>> Predicate<S> instantiate(StateDefinition<O,S> definition) @ L30
- 方法名:instantiate
- 源码定位:L30
- 返回类型:<O,S extends StateHolder<O,S>> Predicate
- 修饰符:public
参数:
- definition: StateDefinition<O,S>
说明:
TODO
private static <O,S extends StateHolder<O,S>> Predicate<S> instantiate(StateDefinition<O,S> definition, String key, KeyValueCondition.Terms valueTest) @ L37
- 方法名:instantiate
- 源码定位:L37
- 返回类型:<O,S extends StateHolder<O,S>> Predicate
- 修饰符:private static
参数:
- definition: StateDefinition<O,S>
- key: String
- valueTest: KeyValueCondition.Terms
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public record KeyValueCondition(Map<String, KeyValueCondition.Terms> tests) implements Condition {
private static final Logger LOGGER = LogUtils.getLogger();
public static final Codec<KeyValueCondition> CODEC = ExtraCodecs.nonEmptyMap(Codec.unboundedMap(Codec.STRING, KeyValueCondition.Terms.CODEC))
.xmap(KeyValueCondition::new, KeyValueCondition::tests);
@Override
public <O, S extends StateHolder<O, S>> Predicate<S> instantiate(StateDefinition<O, S> definition) {
List<Predicate<S>> predicates = new ArrayList<>(this.tests.size());
this.tests.forEach((key, valueTest) -> predicates.add(instantiate(definition, key, valueTest)));
return Util.allOf(predicates);
}
private static <O, S extends StateHolder<O, S>> Predicate<S> instantiate(StateDefinition<O, S> definition, String key, KeyValueCondition.Terms valueTest) {
Property<?> property = definition.getProperty(key);
if (property == null) {
throw new IllegalArgumentException(String.format(Locale.ROOT, "Unknown property '%s' on '%s'", key, definition.getOwner()));
} else {
return valueTest.instantiate(definition.getOwner(), property);
}
}
@OnlyIn(Dist.CLIENT)
public record Term(String value, boolean negated) {
private static final String NEGATE = "!";
public Term(String value, boolean negated) {
if (value.isEmpty()) {
throw new IllegalArgumentException("Empty term");
} else {
this.value = value;
this.negated = negated;
}
}
public static KeyValueCondition.Term parse(String value) {
return value.startsWith("!") ? new KeyValueCondition.Term(value.substring(1), true) : new KeyValueCondition.Term(value, false);
}
@Override
public String toString() {
return this.negated ? "!" + this.value : this.value;
}
}
@OnlyIn(Dist.CLIENT)
public record Terms(List<KeyValueCondition.Term> entries) {
private static final char SEPARATOR = '|';
private static final Joiner JOINER = Joiner.on('|');
private static final Splitter SPLITTER = Splitter.on('|');
private static final Codec<String> LEGACY_REPRESENTATION_CODEC = Codec.either(Codec.INT, Codec.BOOL)
.flatComapMap(either -> either.map(String::valueOf, String::valueOf), o -> DataResult.error(() -> "This codec can't be used for encoding"));
public static final Codec<KeyValueCondition.Terms> CODEC = Codec.withAlternative(Codec.STRING, LEGACY_REPRESENTATION_CODEC)
.comapFlatMap(KeyValueCondition.Terms::parse, KeyValueCondition.Terms::toString);
public Terms(List<KeyValueCondition.Term> entries) {
if (entries.isEmpty()) {
throw new IllegalArgumentException("Empty value for property");
} else {
this.entries = entries;
}
}
public static DataResult<KeyValueCondition.Terms> parse(String value) {
List<KeyValueCondition.Term> terms = SPLITTER.splitToStream(value).map(KeyValueCondition.Term::parse).toList();
if (terms.isEmpty()) {
return DataResult.error(() -> "Empty value for property");
} else {
for (KeyValueCondition.Term entry : terms) {
if (entry.value.isEmpty()) {
return DataResult.error(() -> "Empty term in value '" + value + "'");
}
}
return DataResult.success(new KeyValueCondition.Terms(terms));
}
}
@Override
public String toString() {
return JOINER.join(this.entries);
}
public <O, S extends StateHolder<O, S>, T extends Comparable<T>> Predicate<S> instantiate(O owner, Property<T> property) {
Predicate<T> allowedValueTest = Util.anyOf(Lists.transform(this.entries, t -> this.instantiate(owner, property, t)));
List<T> allowedValues = new ArrayList<>(property.getPossibleValues());
int allValuesCount = allowedValues.size();
allowedValues.removeIf(allowedValueTest.negate());
int allowedValuesCount = allowedValues.size();
if (allowedValuesCount == 0) {
KeyValueCondition.LOGGER.warn("Condition {} for property {} on {} is always false", this, property.getName(), owner);
return blockState -> false;
} else {
int rejectedValuesCount = allValuesCount - allowedValuesCount;
if (rejectedValuesCount == 0) {
KeyValueCondition.LOGGER.warn("Condition {} for property {} on {} is always true", this, property.getName(), owner);
return blockState -> true;
} else {
boolean negate;
List<T> valuesToMatch;
if (allowedValuesCount <= rejectedValuesCount) {
negate = false;
valuesToMatch = allowedValues;
} else {
negate = true;
List<T> rejectedValues = new ArrayList<>(property.getPossibleValues());
rejectedValues.removeIf(allowedValueTest);
valuesToMatch = rejectedValues;
}
if (valuesToMatch.size() == 1) {
T expectedValue = (T)valuesToMatch.getFirst();
return state -> {
T value = state.getValue(property);
return expectedValue.equals(value) ^ negate;
};
} else {
return state -> {
T value = state.getValue(property);
return valuesToMatch.contains(value) ^ negate;
};
}
}
}
}
private <T extends Comparable<T>> T getValueOrThrow(Object owner, Property<T> property, String input) {
Optional<T> value = property.getValue(input);
if (value.isEmpty()) {
throw new RuntimeException(String.format(Locale.ROOT, "Unknown value '%s' for property '%s' on '%s' in '%s'", input, property, owner, this));
} else {
return value.get();
}
}
private <T extends Comparable<T>> Predicate<T> instantiate(Object owner, Property<T> property, KeyValueCondition.Term term) {
T parsedValue = this.getValueOrThrow(owner, property, term.value);
return term.negated ? value -> !value.equals(parsedValue) : value -> value.equals(parsedValue);
}
}
}引用的其他类
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ExtraCodecs.nonEmptyMap()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.allOf(), Util.anyOf()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
返回值
- 引用位置: